@envive-ai/react-hooks 0.2.6-alpha.12 → 0.2.6

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 (364) hide show
  1. package/dist/{NewOrgConfig-BfbTlFg1.js → NewOrgConfig-BfrGpiGk.js} +2 -2
  2. package/dist/{NewOrgConfig-DJm6_abA.cjs → NewOrgConfig-BxSuoP9C.cjs} +2 -2
  3. package/dist/{SystemSettingsContext-BbTKNBvJ.js → SystemSettingsContext-B8X_Dvw2.js} +2 -2
  4. package/dist/{SystemSettingsContext-6ZHzQkCE.cjs → SystemSettingsContext-Bkoiobdv.cjs} +2 -2
  5. package/dist/{TrackComponentVisibleEvent-BRC2FTp-.cjs → TrackComponentVisibleEvent-DMuX-byo.cjs} +7 -7
  6. package/dist/{TrackComponentVisibleEvent-BJgNOypY.js → TrackComponentVisibleEvent-DwfGqNTx.js} +3 -3
  7. package/dist/{amplitudeContext-CZUzMXHl.d.ts → amplitudeContext-CiO9T9c-.d.ts} +1 -1
  8. package/dist/amplitudeContext-DOqL2Vn8.js +264 -0
  9. package/dist/amplitudeContext-ZTQMvVTV.cjs +286 -0
  10. package/dist/{api-DeW6rHj3.cjs → api-BvygKEiX.cjs} +3 -3
  11. package/dist/{api-BWSsazAG.js → api-bHEYmSiT.js} +3 -3
  12. package/dist/app-Aqkm_SlS.js +110 -0
  13. package/dist/app-BQw_-JGl.cjs +156 -0
  14. package/dist/application/models/graphql/index.cjs +2 -2
  15. package/dist/application/models/graphql/index.d.ts +1 -1
  16. package/dist/application/models/graphql/index.js +2 -2
  17. package/dist/application/models/guards/api/index.cjs +3 -3
  18. package/dist/application/models/guards/api/index.d.ts +2 -2
  19. package/dist/application/models/guards/api/index.js +3 -3
  20. package/dist/application/models/guards/utils.cjs +1 -1
  21. package/dist/application/models/guards/utils.d.ts +1 -1
  22. package/dist/application/models/guards/utils.js +1 -1
  23. package/dist/application/models/index.cjs +8 -8
  24. package/dist/application/models/index.d.cts +2 -2
  25. package/dist/application/models/index.d.ts +11 -11
  26. package/dist/application/models/index.js +8 -8
  27. package/dist/application/models/utilityTypes/index.d.ts +1 -1
  28. package/dist/application/models/variantInfo/index.d.ts +1 -1
  29. package/dist/application/utils/index.cjs +18 -16
  30. package/dist/application/utils/index.d.cts +4 -4
  31. package/dist/application/utils/index.d.ts +13 -13
  32. package/dist/application/utils/index.js +18 -16
  33. package/dist/{atomStore-DNji91Im.cjs → atomStore-CmZbgQHc.cjs} +1 -1
  34. package/dist/{atomStore-DXTVqiKc.js → atomStore-DEcDhiLp.js} +1 -1
  35. package/dist/atoms/app/index.cjs +17 -22
  36. package/dist/atoms/app/index.d.cts +2 -2
  37. package/dist/atoms/app/index.d.ts +19 -19
  38. package/dist/atoms/app/index.js +12 -17
  39. package/dist/atoms/atomStore/index.cjs +1 -1
  40. package/dist/atoms/atomStore/index.js +1 -1
  41. package/dist/atoms/chat/index.cjs +19 -18
  42. package/dist/atoms/chat/index.d.cts +28 -28
  43. package/dist/atoms/chat/index.d.ts +38 -38
  44. package/dist/atoms/chat/index.js +19 -18
  45. package/dist/atoms/globalSearch/index.cjs +1 -2
  46. package/dist/atoms/globalSearch/index.d.cts +5 -5
  47. package/dist/atoms/globalSearch/index.d.ts +6 -6
  48. package/dist/atoms/globalSearch/index.js +1 -2
  49. package/dist/atoms/org/index.cjs +8 -7
  50. package/dist/atoms/org/index.d.cts +19 -19
  51. package/dist/atoms/org/index.d.ts +29 -29
  52. package/dist/atoms/org/index.js +4 -3
  53. package/dist/atoms/search/index.cjs +26 -25
  54. package/dist/atoms/search/index.d.cts +3 -3
  55. package/dist/atoms/search/index.d.ts +13 -13
  56. package/dist/atoms/search/index.js +26 -25
  57. package/dist/atoms/search/types.cjs +1 -1
  58. package/dist/atoms/search/types.d.ts +1 -1
  59. package/dist/atoms/search/types.js +1 -1
  60. package/dist/atoms/search/utils.cjs +1 -1
  61. package/dist/atoms/search/utils.d.ts +1 -1
  62. package/dist/atoms/search/utils.js +1 -1
  63. package/dist/{cdnContext-DOSIofl8.cjs → cdnContext-Cd0Kvt6g.cjs} +2 -2
  64. package/dist/{cdnContext-CEGBVVBU.js → cdnContext-D8pHA9gh.js} +2 -2
  65. package/dist/{chat-DCGriB7h.cjs → chat-CJ9D8n7g.cjs} +1 -1
  66. package/dist/{chat-CqPuT9_V.cjs → chat-DwNALtox.cjs} +12 -11
  67. package/dist/{chat-ClvJ9xEj.js → chat-EJbfGWRr.js} +1 -1
  68. package/dist/{chat-DH70QqJp.js → chat-U1IgKNij.js} +9 -8
  69. package/dist/{chatElementDisplayLocation-CpgV2wR1.d.ts → chatElementDisplayLocation-DbmdwAff.d.ts} +1 -1
  70. package/dist/{chatSearch-C7Y-hb-6.js → chatSearch-Bb2SMr9X.js} +7 -7
  71. package/dist/{chatSearch-DLV4BUGA.cjs → chatSearch-DtE2cUQw.cjs} +7 -7
  72. package/dist/{chatState-CcFtSqJT.cjs → chatState-B3Dyrd9M.cjs} +5 -5
  73. package/dist/{chatState-DKnNHmwe.js → chatState-BXBN-12W.js} +3 -3
  74. package/dist/commerce-api-DXbnMNT8.js +311 -0
  75. package/dist/commerce-api-Dx02FCQ7.cjs +318 -0
  76. package/dist/{common-DQPvV_S_.cjs → common-CuwWqIJ1.cjs} +1 -1
  77. package/dist/{common-c_4eX0qn.js → common-Df2bwzd2.js} +1 -1
  78. package/dist/{components-DKwVHIjq.cjs → components-BCfFLf9X.cjs} +1 -1
  79. package/dist/{components-CDpaMUjK.js → components-QGCWJ26c.js} +1 -1
  80. package/dist/config/index.cjs +4 -4
  81. package/dist/config/index.d.ts +4 -4
  82. package/dist/config/index.js +4 -4
  83. package/dist/config/locators/components/chat/index.cjs +1 -1
  84. package/dist/config/locators/components/chat/index.d.ts +1 -1
  85. package/dist/config/locators/components/chat/index.js +1 -1
  86. package/dist/config/locators/components/common/index.cjs +1 -1
  87. package/dist/config/locators/components/common/index.d.ts +1 -1
  88. package/dist/config/locators/components/common/index.js +1 -1
  89. package/dist/config/locators/components/index.cjs +1 -1
  90. package/dist/config/locators/components/index.d.ts +1 -1
  91. package/dist/config/locators/components/index.js +1 -1
  92. package/dist/config/locators/components/search/index.d.ts +1 -1
  93. package/dist/config/locators/index.cjs +4 -4
  94. package/dist/config/locators/index.d.ts +4 -4
  95. package/dist/config/locators/index.js +4 -4
  96. package/dist/contexts/amplitudeContext/index.cjs +19 -19
  97. package/dist/contexts/amplitudeContext/index.d.ts +1 -1
  98. package/dist/contexts/amplitudeContext/index.js +16 -16
  99. package/dist/contexts/cdnContext/index.cjs +4 -4
  100. package/dist/contexts/cdnContext/index.js +4 -4
  101. package/dist/contexts/chatContext/index.cjs +42 -37
  102. package/dist/contexts/chatContext/index.d.cts +4 -4
  103. package/dist/contexts/chatContext/index.d.ts +4 -4
  104. package/dist/contexts/chatContext/index.js +32 -27
  105. package/dist/contexts/enviveConfigContext/index.cjs +4 -4
  106. package/dist/contexts/enviveConfigContext/index.d.cts +1 -1
  107. package/dist/contexts/enviveConfigContext/index.d.ts +3 -3
  108. package/dist/contexts/enviveConfigContext/index.js +4 -4
  109. package/dist/contexts/enviveCssContext/index.cjs +16 -16
  110. package/dist/contexts/enviveCssContext/index.js +16 -16
  111. package/dist/contexts/featureFlagContext/index.cjs +6 -6
  112. package/dist/contexts/featureFlagContext/index.d.cts +1 -1
  113. package/dist/contexts/featureFlagContext/index.d.ts +3 -3
  114. package/dist/contexts/featureFlagContext/index.js +6 -6
  115. package/dist/contexts/featureFlagServiceContext/index.cjs +3 -3
  116. package/dist/contexts/featureFlagServiceContext/index.d.cts +2 -2
  117. package/dist/contexts/featureFlagServiceContext/index.d.ts +4 -4
  118. package/dist/contexts/featureFlagServiceContext/index.js +3 -3
  119. package/dist/contexts/graphqlContext/index.cjs +11 -11
  120. package/dist/contexts/graphqlContext/index.d.cts +3 -3
  121. package/dist/contexts/graphqlContext/index.d.ts +13 -13
  122. package/dist/contexts/graphqlContext/index.js +11 -11
  123. package/dist/contexts/localStorageContext/index.cjs +2 -2
  124. package/dist/contexts/localStorageContext/index.js +2 -2
  125. package/dist/contexts/newOrgConfigContext/index.cjs +15 -15
  126. package/dist/contexts/newOrgConfigContext/index.d.cts +4 -4
  127. package/dist/contexts/newOrgConfigContext/index.d.ts +14 -14
  128. package/dist/contexts/newOrgConfigContext/index.js +15 -15
  129. package/dist/contexts/searchContext/index.cjs +19 -22
  130. package/dist/contexts/searchContext/index.d.ts +2 -2
  131. package/dist/contexts/searchContext/index.js +19 -22
  132. package/dist/contexts/sessionStorageContext/index.cjs +2 -2
  133. package/dist/contexts/sessionStorageContext/index.js +2 -2
  134. package/dist/contexts/shopifyUrlContext/index.cjs +2 -2
  135. package/dist/contexts/shopifyUrlContext/index.d.cts +1 -1
  136. package/dist/contexts/shopifyUrlContext/index.d.ts +3 -3
  137. package/dist/contexts/shopifyUrlContext/index.js +2 -2
  138. package/dist/contexts/systemSettingsContext/index.cjs +4 -4
  139. package/dist/contexts/systemSettingsContext/index.d.cts +6 -6
  140. package/dist/contexts/systemSettingsContext/index.d.ts +15 -15
  141. package/dist/contexts/systemSettingsContext/index.js +4 -4
  142. package/dist/contexts/types.cjs +1 -1
  143. package/dist/contexts/types.d.cts +1 -1
  144. package/dist/contexts/types.d.ts +3 -3
  145. package/dist/contexts/types.js +1 -1
  146. package/dist/contexts/userIdentityContext/index.cjs +24 -18
  147. package/dist/contexts/userIdentityContext/index.d.ts +1 -1
  148. package/dist/contexts/userIdentityContext/index.js +22 -16
  149. package/dist/{domObserver-Bqf3ooj8.cjs → domObserver-COKvTfZV.cjs} +1 -1
  150. package/dist/{domObserver-v9ODTyfT.js → domObserver-DEiUh0qg.js} +1 -1
  151. package/dist/{enviveConfig-Dv9-esGV.cjs → enviveConfig-B42OJ8bK.cjs} +3 -3
  152. package/dist/{enviveConfig-DZBohDpc.js → enviveConfig-BlIkxiAF.js} +3 -3
  153. package/dist/{enviveConfigContext-DrDjCems.js → enviveConfigContext-1_EivtCa.js} +3 -3
  154. package/dist/{enviveConfigContext-D2OELZDR.cjs → enviveConfigContext-Y1ahEAMe.cjs} +3 -3
  155. package/dist/{featureFlagServiceContext-V0J-69ty.d.ts → featureFlagServiceContext-C5U0bshi.d.ts} +2 -2
  156. package/dist/{featureFlagServiceContext-FBM6DdMJ.js → featureFlagServiceContext-CAPrb4e_.js} +3 -3
  157. package/dist/{featureFlagServiceContext-Be_LUbFf.d.cts → featureFlagServiceContext-CiKWV306.d.cts} +2 -2
  158. package/dist/{featureFlagServiceContext-CJyYItqu.cjs → featureFlagServiceContext-D3Ge8GH5.cjs} +3 -3
  159. package/dist/{featureGates-qU_ulhpC.cjs → featureGates-Bt_Y3kZ7.cjs} +1 -1
  160. package/dist/{featureGates-KEwAL8p_.js → featureGates-D4Me_IZH.js} +1 -1
  161. package/dist/frontendConfig-BiD1-j48.d.ts +856 -0
  162. package/dist/frontendConfig-tVg0hsWZ.d.cts +856 -0
  163. package/dist/{globalSearch-FBk2epe8.cjs → globalSearch-BOG3wmck.cjs} +1 -1
  164. package/dist/{globalSearch-Ccxq8hNF.js → globalSearch-BQEX-2Ml.js} +1 -1
  165. package/dist/{graphql-3PxNRFOc.js → graphql-OkhsP4ir.js} +2 -2
  166. package/dist/{graphql-DGYfelZp.cjs → graphql-l4dQrsA6.cjs} +2 -2
  167. package/dist/graphqlConfig-BnfE0ql5.cjs +39 -0
  168. package/dist/graphqlConfig-CZGjJ8hP.js +14 -0
  169. package/dist/{graphqlContext-D67VEQg3.d.cts → graphqlContext-Bf3E-V2T.d.cts} +2 -2
  170. package/dist/{graphqlContext-BQA6gnpH.d.ts → graphqlContext-CDeKzb46.d.ts} +3 -3
  171. package/dist/{graphqlContext-W0cZNBf1.cjs → graphqlContext-CpwAvnro.cjs} +5 -5
  172. package/dist/{graphqlContext-Ci5GRAdH.js → graphqlContext-dyWNSWNv.js} +5 -5
  173. package/dist/hooks/AmplitudeOperations/index.cjs +18 -18
  174. package/dist/hooks/AmplitudeOperations/index.d.ts +1 -1
  175. package/dist/hooks/AmplitudeOperations/index.js +18 -18
  176. package/dist/hooks/AppDetails/index.cjs +15 -20
  177. package/dist/hooks/AppDetails/index.d.cts +2 -2
  178. package/dist/hooks/AppDetails/index.d.ts +11 -11
  179. package/dist/hooks/AppDetails/index.js +15 -20
  180. package/dist/hooks/CdnOperations/index.cjs +4 -4
  181. package/dist/hooks/CdnOperations/index.js +4 -4
  182. package/dist/hooks/ChatToggle/index.cjs +23 -22
  183. package/dist/hooks/ChatToggle/index.d.ts +1 -1
  184. package/dist/hooks/ChatToggle/index.js +20 -19
  185. package/dist/hooks/ChatToggleAnalytics/index.cjs +19 -19
  186. package/dist/hooks/ChatToggleAnalytics/index.d.ts +1 -1
  187. package/dist/hooks/ChatToggleAnalytics/index.js +19 -19
  188. package/dist/hooks/CustomerSupportHandoff/index.cjs +1 -1
  189. package/dist/hooks/CustomerSupportHandoff/index.js +1 -1
  190. package/dist/hooks/Debounce/index.cjs +1 -1
  191. package/dist/hooks/Debounce/index.js +1 -1
  192. package/dist/hooks/ElementObserver/index.cjs +1 -1
  193. package/dist/hooks/ElementObserver/index.d.ts +1 -1
  194. package/dist/hooks/ElementObserver/index.js +1 -1
  195. package/dist/hooks/GrabAndScroll/index.d.cts +2 -2
  196. package/dist/hooks/GraphQLConfig/index.cjs +12 -12
  197. package/dist/hooks/GraphQLConfig/index.d.cts +3 -3
  198. package/dist/hooks/GraphQLConfig/index.d.ts +12 -12
  199. package/dist/hooks/GraphQLConfig/index.js +12 -12
  200. package/dist/hooks/IdentifyUser/index.cjs +24 -18
  201. package/dist/hooks/IdentifyUser/index.js +23 -17
  202. package/dist/hooks/ImageResolver/index.cjs +10 -10
  203. package/dist/hooks/ImageResolver/index.js +10 -10
  204. package/dist/hooks/Intersection/index.cjs +1 -1
  205. package/dist/hooks/Intersection/index.js +1 -1
  206. package/dist/hooks/LocalStorageOperations/index.cjs +2 -2
  207. package/dist/hooks/LocalStorageOperations/index.js +2 -2
  208. package/dist/hooks/MessageFilter/index.cjs +8 -8
  209. package/dist/hooks/MessageFilter/index.d.cts +2 -2
  210. package/dist/hooks/MessageFilter/index.d.ts +11 -11
  211. package/dist/hooks/MessageFilter/index.js +8 -8
  212. package/dist/hooks/NewOrgConfig/index.cjs +16 -16
  213. package/dist/hooks/NewOrgConfig/index.d.cts +4 -4
  214. package/dist/hooks/NewOrgConfig/index.d.ts +14 -14
  215. package/dist/hooks/NewOrgConfig/index.js +16 -16
  216. package/dist/hooks/Search/index.cjs +46 -45
  217. package/dist/hooks/Search/index.d.cts +4 -4
  218. package/dist/hooks/Search/index.d.ts +15 -15
  219. package/dist/hooks/Search/index.js +38 -37
  220. package/dist/hooks/SearchOperations/index.cjs +20 -23
  221. package/dist/hooks/SearchOperations/index.d.ts +2 -2
  222. package/dist/hooks/SearchOperations/index.js +20 -23
  223. package/dist/hooks/SessionStorageOperations/index.cjs +2 -2
  224. package/dist/hooks/SessionStorageOperations/index.js +2 -2
  225. package/dist/hooks/ShopifyUrlOperations/index.cjs +2 -2
  226. package/dist/hooks/ShopifyUrlOperations/index.d.cts +3 -3
  227. package/dist/hooks/ShopifyUrlOperations/index.d.ts +5 -5
  228. package/dist/hooks/ShopifyUrlOperations/index.js +2 -2
  229. package/dist/hooks/SystemSettingsContext/index.cjs +5 -5
  230. package/dist/hooks/SystemSettingsContext/index.d.cts +4 -4
  231. package/dist/hooks/SystemSettingsContext/index.d.ts +13 -13
  232. package/dist/hooks/SystemSettingsContext/index.js +5 -5
  233. package/dist/hooks/TrackComponentVisibleEvent/index.cjs +18 -18
  234. package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +2 -2
  235. package/dist/hooks/TrackComponentVisibleEvent/index.js +18 -18
  236. package/dist/hooks/UpdateAnalyticsProps/index.cjs +21 -21
  237. package/dist/hooks/UpdateAnalyticsProps/index.js +16 -16
  238. package/dist/hooks/utils.d.cts +3 -3
  239. package/dist/hooks/utils.d.ts +12 -12
  240. package/dist/{index-DazMsEy_.d.ts → index--uHjE7L8.d.ts} +1 -1
  241. package/dist/{index-BeYfyZ6k.d.ts → index-B6xpW8RG.d.ts} +1 -1
  242. package/dist/{index-DLURqmo8.d.cts → index-Bq39XSmY.d.cts} +31 -31
  243. package/dist/{index-O33GSSRr.d.cts → index-CG3P8xE1.d.cts} +2 -2
  244. package/dist/{index-CCa4tZuO.d.ts → index-Cx9e-fRi.d.ts} +2 -2
  245. package/dist/{index-bjMvkcBF.d.ts → index-D2VaMPA3.d.ts} +1 -1
  246. package/dist/{index-xHVrsrbz.d.ts → index-D31m6bPU.d.ts} +1 -1
  247. package/dist/{index-h809JLbL.d.ts → index-DSRs6N6J.d.ts} +1 -1
  248. package/dist/{index-Dfwnna1j.d.ts → index-Dxpscrvz.d.ts} +1 -1
  249. package/dist/{index-DJTrxIFJ.d.ts → index-VwfWqyR_.d.ts} +1 -1
  250. package/dist/{index-D4c-port.d.ts → index-fUsw_Mea.d.ts} +6 -6
  251. package/dist/{index-BlRatkrH.d.ts → index-wFHfdr6p.d.ts} +34 -34
  252. package/dist/interceptors/index.d.cts +2 -2
  253. package/dist/interceptors/index.d.ts +12 -12
  254. package/dist/interceptors/types.d.cts +2 -2
  255. package/dist/interceptors/types.d.ts +12 -12
  256. package/dist/{localStorageContext-NRP-CdmF.cjs → localStorageContext-C5giszHn.cjs} +2 -2
  257. package/dist/{localStorageContext-BPZ82q-G.js → localStorageContext-DAOJ4be4.js} +2 -2
  258. package/dist/{locators-BMQGmGLq.js → locators-C2fWd-74.js} +1 -1
  259. package/dist/{locators-DxYdak1F.cjs → locators-Cx3q6Z_h.cjs} +1 -1
  260. package/dist/{logger-TBIl4uIH.cjs → logger-0D_8Ip2L.cjs} +1 -1
  261. package/dist/{logger-W3lqg-4b.js → logger-Co0IA3k5.js} +1 -1
  262. package/dist/{models-D-4db7XW.cjs → models-CkJ-wg9Q.cjs} +5 -5
  263. package/dist/{models-c86hYW-F.js → models-UHOY0ak5.js} +5 -5
  264. package/dist/{newOrgConfigAtom-DxILMn2I.cjs → newOrgConfigAtom-CPA6Gp6n.cjs} +1 -1
  265. package/dist/{newOrgConfigAtom-sqve6LZU.js → newOrgConfigAtom-DEUj6H-p.js} +1 -1
  266. package/dist/{newOrgConfigContext-DQiuf8nd.js → newOrgConfigContext-6mlrvr1w.js} +5 -5
  267. package/dist/{newOrgConfigContext-Cl4H9c3q.cjs → newOrgConfigContext-BMvcqPzD.cjs} +5 -5
  268. package/dist/{newOrgConfigContext-CS8IA5Eg.d.ts → newOrgConfigContext-BVyJExeW.d.ts} +2 -2
  269. package/dist/{newOrgConfigContext-5Bw7RwT-.d.cts → newOrgConfigContext-DOdUxlOE.d.cts} +2 -2
  270. package/dist/{nodeSelector-BiCDowlK.d.ts → nodeSelector-DYhDUi7v.d.ts} +1 -1
  271. package/dist/{org-DlAesvQ_.cjs → org-B_cWn2bt.cjs} +1 -1
  272. package/dist/{org-vi0njpBh.js → org-h32_LSEb.js} +1 -1
  273. package/dist/orgAnalyticsConfig-Bm23fw4s.cjs +39 -0
  274. package/dist/orgAnalyticsConfig-CpBmga08.js +14 -0
  275. package/dist/{search-1NQLQD9d.d.ts → search-B1OtJe8Z.d.ts} +2 -2
  276. package/dist/{search-CXXslzAO.cjs → search-D-UfTjB7.cjs} +5 -5
  277. package/dist/{search-filter-types-DPgeG8FS.d.ts → search-filter-types-OI9zH3E_.d.ts} +1 -1
  278. package/dist/{search-DBSMrXWv.js → search-yawhMv22.js} +5 -5
  279. package/dist/{searchContext-DXW6xvXv.cjs → searchContext-CFuwIIW-.cjs} +9 -9
  280. package/dist/{searchContext-mvwUJncR.js → searchContext-CiqOqTJL.js} +7 -7
  281. package/dist/{searchServiceAdapter-DEv1tTn0.cjs → searchServiceAdapter-BGlvoZFE.cjs} +1 -1
  282. package/dist/{searchServiceAdapter-WyCU55NV.js → searchServiceAdapter-Db6jEcJs.js} +1 -1
  283. package/dist/{sessionStorageContext-1Ks_d4Z0.cjs → sessionStorageContext-BmCW091C.cjs} +2 -2
  284. package/dist/{sessionStorageContext-CDcl7NVl.js → sessionStorageContext-CNxkqJi1.js} +2 -2
  285. package/dist/{shopifyUrlContext-CejRZfj7.js → shopifyUrlContext-BXbI0PIG.js} +2 -2
  286. package/dist/{shopifyUrlContext-lnHoAOEf.cjs → shopifyUrlContext-aZMwCfbJ.cjs} +2 -2
  287. package/dist/{spiffyWidgets-B1uc84_g.d.ts → spiffyWidgets-CvEJIuJx.d.ts} +1 -1
  288. package/dist/{systemSettingsContext-B0Kyq7nA.cjs → systemSettingsContext-SozpUezn.cjs} +2 -2
  289. package/dist/{systemSettingsContext-CVUxEcsU.js → systemSettingsContext-kz6yyiFF.js} +2 -2
  290. package/dist/{test-types-y6kp-tiw.d.ts → test-types-DRhqHXw-.d.ts} +1 -1
  291. package/dist/types/index.cjs +1 -16
  292. package/dist/types/index.d.cts +1 -15
  293. package/dist/types/index.d.ts +3 -17
  294. package/dist/types/index.js +2 -16
  295. package/dist/{types-CxObxLKs.cjs → types-BuvXXGxE.cjs} +1 -1
  296. package/dist/types-BwNrLPSZ.cjs +106 -0
  297. package/dist/types-D3uOF0Oy.js +76 -0
  298. package/dist/{types-CS0Hrzja.js → types-DXnG1tV0.js} +1 -1
  299. package/dist/{types-BCz-hOvv.d.ts → types-DZPuBnHe.d.ts} +1 -1
  300. package/dist/{types-Db5Eux6K.d.ts → types-r0Z6CwyF.d.ts} +2 -2
  301. package/dist/types.d.cts +2 -21
  302. package/dist/types.d.ts +4 -23
  303. package/dist/unsupportedProductExceptions-B4f9aLjr.cjs +32 -0
  304. package/dist/unsupportedProductExceptions-DlmraJm8.js +20 -0
  305. package/dist/{urlsParser-DxjoLj98.js → urlsParser-DLCzibqU.js} +1 -1
  306. package/dist/{urlsParser-COzMdJaX.cjs → urlsParser-DhcEZLc_.cjs} +1 -1
  307. package/dist/{useAmplitudeOperations-jqa7K9dH.cjs → useAmplitudeOperations-D0nvIYlt.cjs} +3 -3
  308. package/dist/{useAmplitudeOperations-DYs1h8a_.js → useAmplitudeOperations-Dhks3PgF.js} +2 -2
  309. package/dist/{useAppDetails-C71k0brz.cjs → useAppDetails-B9sGmpJ3.cjs} +7 -7
  310. package/dist/{useAppDetails-BRUqZEyt.js → useAppDetails-qyaQIbWE.js} +4 -4
  311. package/dist/{useDebounce-DZ8Cgiwc.cjs → useDebounce-BZDtUAQ8.cjs} +1 -1
  312. package/dist/{useDebounce-v9cezyjn.js → useDebounce-ueblXZI-.js} +1 -1
  313. package/dist/{useGraphQLConfig-5VwS9Q_Z.js → useGraphQLConfig-BccQUaeW.js} +2 -2
  314. package/dist/{useGraphQLConfig-Cj26_J9I.cjs → useGraphQLConfig-CgKEfVYc.cjs} +2 -2
  315. package/dist/{useIntersection-Cncgxdmy.js → useIntersection-CZSEBUbv.js} +1 -1
  316. package/dist/{useIntersection-m4PEpvG7.cjs → useIntersection-DSDREfj6.cjs} +1 -1
  317. package/dist/{userIdentityContext-BVODeTlN.d.ts → userIdentityContext-BKLedN4R.d.ts} +1 -1
  318. package/dist/userIdentityContext-Cb6lLv6t.cjs +132 -0
  319. package/dist/userIdentityContext-O_DHHPTN.js +115 -0
  320. package/dist/{utils-Covisryh.d.ts → utils-B1v0iXs3.d.ts} +4 -4
  321. package/dist/{utils-BxPPugeP.d.cts → utils-B7PAzB_M.d.cts} +2 -2
  322. package/dist/{utils-DpneNSJf.d.ts → utils-BhyZiDrE.d.ts} +1 -1
  323. package/dist/{utils-DIvMgPe8.js → utils-C4ci_t0-.js} +1 -1
  324. package/dist/{utils-CDw74BCO.cjs → utils-C6imnLBo.cjs} +1 -1
  325. package/dist/utils-Cazq8Q3q.cjs +715 -0
  326. package/dist/{utils-2SWrJ12w.cjs → utils-CvLmSsUj.cjs} +1 -1
  327. package/dist/{utils-CqBxIpEV.js → utils-D82gfbgU.js} +1 -1
  328. package/dist/utils-DFPt3FSw.js +606 -0
  329. package/package.json +14 -13
  330. package/src/application/utils/__tests__/divideArrays.test.ts +12 -13
  331. package/src/atoms/app/index.ts +1 -2
  332. package/src/contexts/enviveConfigContext/__tests__/enviveConfigContext.test.tsx +411 -0
  333. package/src/contexts/types.ts +13 -14
  334. package/src/contexts/userIdentityContext/__tests__/userIdentityContext.test.tsx +663 -0
  335. package/src/contexts/userIdentityContext/userIdentityContext.tsx +6 -0
  336. package/src/hooks/Search/useSearch.tsx +2 -2
  337. package/src/types/index.ts +0 -1
  338. package/src/types.ts +0 -14
  339. package/dist/frontendConfig-CeWhVevA.d.ts +0 -857
  340. package/dist/frontendConfig-OWWJmuPc.d.cts +0 -857
  341. package/dist/globalSearch-B9DRBxSM.cjs +0 -0
  342. package/dist/globalSearch-BpGfkuXz.js +0 -1
  343. package/dist/graphqlConfig-GHZ1UgCw.cjs +0 -73
  344. package/dist/graphqlConfig-mDg6J44N.js +0 -24
  345. package/dist/hooks/FloatingButtonVisibility/index.cjs +0 -73
  346. package/dist/hooks/FloatingButtonVisibility/index.d.cts +0 -7
  347. package/dist/hooks/FloatingButtonVisibility/index.d.ts +0 -7
  348. package/dist/hooks/FloatingButtonVisibility/index.js +0 -69
  349. package/dist/hooks/LastInteraction/index.cjs +0 -34
  350. package/dist/hooks/LastInteraction/index.d.cts +0 -17
  351. package/dist/hooks/LastInteraction/index.d.ts +0 -17
  352. package/dist/hooks/LastInteraction/index.js +0 -32
  353. package/dist/types-CtUb63bt.js +0 -76
  354. package/dist/types-UUvB6h05.cjs +0 -106
  355. package/dist/utils-CLGXsOwE.cjs +0 -1591
  356. package/dist/utils-jYtD3hmA.js +0 -1385
  357. package/src/hooks/FloatingButtonVisibility/index.ts +0 -1
  358. package/src/hooks/FloatingButtonVisibility/useFloatingButtonVisibility.ts +0 -99
  359. package/src/hooks/LastInteraction/index.ts +0 -1
  360. package/src/hooks/LastInteraction/useLastInteraction.ts +0 -42
  361. package/src/types/floatingbuttonoverrides-types.ts +0 -10
  362. /package/dist/{AmplitudeOperations-ni7wVevx.js → AmplitudeOperations-ChZWcSsc.js} +0 -0
  363. /package/dist/{AmplitudeOperations-DxQnurSG.cjs → AmplitudeOperations-JggIc1zD.cjs} +0 -0
  364. /package/dist/{index-CgAfoNpB.d.ts → index-mHc9_XC3.d.ts} +0 -0
@@ -1,1385 +0,0 @@
1
- import { EventsDispatcher, SpiffyEvent } from "./events-DyUix-Bn.js";
2
- import { MessageRole, MessageType, OrgShortName, ProductExperiment, isBaseEcommerceEvent, isGA4EcommerceEvent, isLegacyUAEcommerceEvent, validateOrgConfigResults, validateResponse, validateSuggestion, validateUserEvent } from "./models-c86hYW-F.js";
3
- import { FeatureGates } from "./featureGates-KEwAL8p_.js";
4
- import { logger_default } from "./logger-W3lqg-4b.js";
5
- import { VariantTypeEnum } from "./variantInfo-BfKlkaWU.js";
6
- import { LocalStorageKeys, useLocalStorage } from "./localStorageContext-BPZ82q-G.js";
7
- import { amplitudeApiKeyAtom, baseUrlAtom, contextSourceAtom, dataResidencyAtom, envAtom, identifyingPrefixAtom, orgShortNameAtom, reactAppNameAtom } from "./enviveConfig-DZBohDpc.js";
8
- import { featureFlagServiceAtom, orgAnalyticsGoogleAnalyticsConfigAtom, orgIdAtom } from "./graphqlConfig-mDg6J44N.js";
9
- import { getAtomStore, sessionStorageUtil } from "./atomStore-DXTVqiKc.js";
10
- import { useEnviveConfig } from "./enviveConfigContext-DrDjCems.js";
11
- import { useFeatureFlagService } from "./featureFlagServiceContext-FBM6DdMJ.js";
12
- import { Configuration, ContextEnvEnum, ContextSourceEnum, CustomerServiceApi, DefaultApi, FormType, InferenceApi, PLPAttributeCategory, ResponseCategory, ResponseError, UserEventCategory, V1OrgConfigGetSourceEnum } from "@spiffy-ai/commerce-api-client";
13
- import { v4 } from "uuid";
14
- import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
15
- import { atom, useAtomValue } from "jotai";
16
- import { createInstance } from "@amplitude/analytics-browser";
17
- import { jsx } from "react/jsx-runtime";
18
- import { atomWithStorage } from "jotai/utils";
19
- import UAParser from "ua-parser-js";
20
-
21
- //#region src/application/utils/coreUserEventToApiUserEvent.ts
22
- const coreUserEventToApiUserEvent = (data) => {
23
- if (data.category === UserEventCategory.PdpVisit || data.category === UserEventCategory.AddToCart) return {
24
- event_id: data.eventId,
25
- created_at: data.createdAt,
26
- category: data.category,
27
- attributes: {
28
- product_id: data.attributes.productId,
29
- parent_product_id: data.attributes.parentProductId,
30
- url: data.attributes.url
31
- }
32
- };
33
- if (data.category === UserEventCategory.PlpVisit) return {
34
- event_id: data.eventId,
35
- created_at: data.createdAt,
36
- category: data.category,
37
- attributes: {
38
- category: PLPAttributeCategory.Id,
39
- attributes: { id: data.attributes.attributes.id }
40
- }
41
- };
42
- if (data.category === UserEventCategory.QueryTyped) return {
43
- event_id: data.eventId,
44
- created_at: data.createdAt,
45
- category: data.category,
46
- attributes: { query: data.attributes.query }
47
- };
48
- if (data.category === UserEventCategory.Search) return {
49
- event_id: data.eventId,
50
- created_at: data.createdAt,
51
- category: data.category,
52
- attributes: {
53
- search_term: data.attributes.searchTerm,
54
- selected_filters: data.attributes.selectedFilters
55
- }
56
- };
57
- if (data.category === UserEventCategory.SuggestionClicked) return {
58
- event_id: data.eventId,
59
- created_at: data.createdAt,
60
- category: data.category,
61
- attributes: { suggestion_id: data.attributes.suggestionId }
62
- };
63
- if (data.category === UserEventCategory.PageVisit) return {
64
- event_id: data.eventId,
65
- created_at: data.createdAt,
66
- category: data.category,
67
- attributes: {
68
- url: data.attributes.url,
69
- page_visit_category: data.attributes.pageVisitCategory
70
- }
71
- };
72
- if (data.category === UserEventCategory.FormSubmitted) return {
73
- event_id: data.eventId,
74
- created_at: data.createdAt,
75
- category: data.category,
76
- attributes: {
77
- filled_schema: { ...data.attributes.filledSchema },
78
- form_response_id: data.attributes.formResponseId,
79
- form_type: data.attributes.formType
80
- }
81
- };
82
- return {
83
- event_id: data.eventId,
84
- created_at: data.createdAt,
85
- category: data.category
86
- };
87
- };
88
-
89
- //#endregion
90
- //#region src/application/utils/nextMessageRequestToApiRequest.ts
91
- const messageRequestToCommerceMessageRequest = (data) => ({
92
- context: {
93
- chat_id: data.context.chatId,
94
- org_id: data.context.orgId,
95
- org_short_name: data.context.orgShortName,
96
- user_id: data.context.userId,
97
- source: data.context.source,
98
- env: data.context.env
99
- },
100
- id: data.id,
101
- feature_flags: data.featureFlags,
102
- user_events: data.userEvents?.map((userEvent) => coreUserEventToApiUserEvent(userEvent)),
103
- generation_params: {
104
- model: data.generationParams?.model,
105
- max_tokens: data.generationParams?.maxTokens,
106
- stop: data.generationParams?.stop,
107
- stream: data.generationParams?.stream,
108
- temperature: data.generationParams?.temperature,
109
- top_p: data.generationParams?.topP,
110
- num_suggestions: data.generationParams?.numSuggestions,
111
- response_system_prompt: data.generationParams?.responseSystemPrompt,
112
- suggestion_system_prompt: data.generationParams?.suggestionSystemPrompt,
113
- response_caching: data.generationParams?.responseCaching
114
- }
115
- });
116
-
117
- //#endregion
118
- //#region src/application/utils/coreContextToApiContext.ts
119
- const coreContextToApiContext = (context) => ({
120
- chat_id: context.chatId,
121
- org_id: context.orgId,
122
- user_id: context.userId,
123
- org_short_name: context.orgShortName,
124
- source: context.source,
125
- env: context.env
126
- });
127
-
128
- //#endregion
129
- //#region src/application/utils/supportedEventRequestToApiRequest.ts
130
- const coreSupportedEventRequestToApiRequest = (coreSupportedEventRequest) => ({
131
- id: coreSupportedEventRequest.id,
132
- user_event: coreUserEventToApiUserEvent(coreSupportedEventRequest.userEvent),
133
- context: coreContextToApiContext(coreSupportedEventRequest.context)
134
- });
135
-
136
- //#endregion
137
- //#region src/types/exceptions/sessionExceptions.ts
138
- var SessionRestartRequired = class extends Error {
139
- constructor() {
140
- super("Session restart required");
141
- this.name = "SessionRestartRequired";
142
- }
143
- };
144
-
145
- //#endregion
146
- //#region src/types/exceptions/unsupportedProductExceptions.ts
147
- var UnsupportedProductException = class extends Error {
148
- constructor() {
149
- super("Unsupported product");
150
- this.name = "UnsupportedProduct";
151
- }
152
- };
153
-
154
- //#endregion
155
- //#region src/application/utils/messageFromFormSubmittedEvent.ts
156
- const messageFromFormSubmittedEvent = (event, formResponseAttributes) => {
157
- if (event.category !== UserEventCategory.FormSubmitted) return;
158
- const formStringContents = Object.entries(formResponseAttributes.schema.properties).map(([key, value]) => `${value.title}: ${event.attributes.filledSchema[key]}`).join("\n");
159
- return {
160
- id: event.eventId,
161
- role: MessageRole.User,
162
- type: MessageType.QueryTyped,
163
- createdAt: event.createdAt,
164
- metadata: { content: formStringContents }
165
- };
166
- };
167
-
168
- //#endregion
169
- //#region src/application/commerce-api.ts
170
- async function errorResponseBody(error) {
171
- try {
172
- return await error.response.json();
173
- } catch {
174
- return {};
175
- }
176
- }
177
- async function throwSessionRestartRequiredIf(errorMsg, error) {
178
- if (!(error instanceof ResponseError)) {
179
- logger_default.logInfo(errorMsg, error);
180
- throw error;
181
- }
182
- const errorResponse = await errorResponseBody(error);
183
- if (errorResponse?.message?.toLowerCase() === "unsupported product" || errorResponse?.app_code?.toUpperCase() === "PRODUCT_NOT_FOUND") throw new UnsupportedProductException();
184
- else if (errorResponse?.app_code?.toUpperCase() === "RESTART_SESSION" || errorResponse?.sub_code?.toUpperCase() === "NOT_FOUND") {
185
- logger_default.logInfo("Session does not exist. Re-start session", error, error.response, errorResponse);
186
- throw new SessionRestartRequired();
187
- }
188
- logger_default.logInfo(errorMsg, error);
189
- throw error;
190
- }
191
- var CommerceApiClient = class CommerceApiClient {
192
- static {
193
- this.getInstance = () => {
194
- if (!CommerceApiClient.instance) CommerceApiClient.instance = new CommerceApiClient();
195
- return CommerceApiClient.instance;
196
- };
197
- }
198
- constructor(basePath) {
199
- this.suggestionsAbortController = new AbortController();
200
- this.responsesAbortController = new AbortController();
201
- const baseUrl = getAtomStore().get(baseUrlAtom);
202
- const config = new Configuration({
203
- basePath: basePath || baseUrl,
204
- headers: {
205
- "Content-Type": "application/json",
206
- Accept: "application/json"
207
- }
208
- });
209
- this.defaultApi = new DefaultApi(config);
210
- this.inferenceApi = new InferenceApi(config);
211
- this.customerServiceApi = new CustomerServiceApi(config);
212
- }
213
- static {
214
- this.resolveUrl = async (url) => {
215
- const atomStore = getAtomStore();
216
- const orgShortName = atomStore.get(orgShortNameAtom);
217
- const orgId = atomStore.get(orgIdAtom);
218
- const userId = atomStore.get(userIdAtom);
219
- const chatId = atomStore.get(chatIdAtom);
220
- const source = atomStore.get(contextSourceAtom);
221
- const env = atomStore.get(envAtom);
222
- const featureFlagService = atomStore.get(featureFlagServiceAtom);
223
- const context = {
224
- user_id: userId ?? "",
225
- org_id: orgId ?? "",
226
- org_short_name: orgShortName ?? "",
227
- chat_id: chatId ?? "",
228
- source: source ?? ContextSourceEnum.App,
229
- env: env ?? ContextEnvEnum.Dev
230
- };
231
- const featureGates = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
232
- const urlResolvingRequest = {
233
- url,
234
- context,
235
- feature_gates: featureGates
236
- };
237
- return await (await CommerceApiClient.getInstance().inferenceApi.v1UrlResolvingPostRaw({ UrlResolvingRequest: urlResolvingRequest })).raw.json();
238
- };
239
- }
240
- static {
241
- this.reportSession = async (reportRequest) => {
242
- await CommerceApiClient.getInstance().defaultApi.v1ChatsReportSessionIdPost({ ReportSessionRequest: reportRequest });
243
- };
244
- }
245
- static {
246
- this.getNextResponses = async (payload) => {
247
- try {
248
- return (await CommerceApiClient.getInstance().inferenceApi.v1NextResponsesPost({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) })).map((resp) => validateResponse(resp)).map((resp) => messageFromResponse(resp)).filter((m) => m != null);
249
- } catch (err) {
250
- logger_default.logInfo("Failed to get next responses", err, {
251
- payloadContext: payload?.context,
252
- userEvents: payload?.userEvents
253
- });
254
- await throwSessionRestartRequiredIf("Failed to get next responses", err);
255
- return [];
256
- }
257
- };
258
- }
259
- static {
260
- this.getNextResponseStreaming = (payload) => {
261
- async function* generate(inferenceApi, abortController) {
262
- try {
263
- const response = await inferenceApi.v1NextResponsesPostRaw({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) }, { signal: abortController.signal });
264
- if (!response.raw.body) {
265
- logger_default.logError("[spiffy-ai] No body in the streamed response", void 0, { response: response.raw });
266
- return;
267
- }
268
- const reader = response.raw.body.getReader();
269
- const decoder = new TextDecoder("utf-8");
270
- let partial = "";
271
- const safeParse = (line) => {
272
- try {
273
- return JSON.parse(line);
274
- } catch (err) {
275
- logger_default.logError("[spiffy-ai] Error parsing streamed line", err, {
276
- line,
277
- partial
278
- });
279
- partial = line;
280
- return partial;
281
- }
282
- };
283
- const processChunk = (chunk) => {
284
- return `${partial}${chunk}`.split("\n").map((line) => line.replace(/^data: /, "").trim()).filter((line) => line !== "" && line !== "[DONE]").map(safeParse).filter((v) => v);
285
- };
286
- while (true) {
287
- const { done, value } = await reader.read();
288
- if (done) break;
289
- const chunk = decoder.decode(value);
290
- const parsedLines = processChunk(chunk);
291
- for (const parsedLine of parsedLines) {
292
- const validatedResponse = validateResponse(parsedLine);
293
- if (validatedResponse) yield validatedResponse;
294
- }
295
- }
296
- } catch (error) {
297
- logger_default.logError("[spiffy-ai] Failed to get next streaming responses", error, {
298
- payloadContext: payload?.context,
299
- userEvents: payload?.userEvents
300
- });
301
- await throwSessionRestartRequiredIf("Failed to get next streaming responses", error);
302
- }
303
- }
304
- CommerceApiClient.getInstance().responsesAbortController.abort();
305
- CommerceApiClient.getInstance().responsesAbortController = new AbortController();
306
- return generate(CommerceApiClient.getInstance().inferenceApi, CommerceApiClient.getInstance().responsesAbortController);
307
- };
308
- }
309
- static {
310
- this.getNextSuggestions = async (payload) => {
311
- try {
312
- CommerceApiClient.getInstance().suggestionsAbortController.abort();
313
- CommerceApiClient.getInstance().suggestionsAbortController = new AbortController();
314
- return (await CommerceApiClient.getInstance().inferenceApi.v1NextSuggestionsPost({ NextMessageRequest: messageRequestToCommerceMessageRequest(payload) }, { signal: CommerceApiClient.getInstance().suggestionsAbortController.signal })).map((resp) => validateSuggestion(resp)).filter((suggestion) => suggestion != null);
315
- } catch (error) {
316
- logger_default.logInfo("Failed to get suggestions", error, {
317
- payloadContext: payload?.context,
318
- userEvents: payload?.userEvents
319
- });
320
- await throwSessionRestartRequiredIf("Failed to get suggestions", error);
321
- return [];
322
- }
323
- };
324
- }
325
- static {
326
- this.getResponses = async (orgId, chatId, userId) => {
327
- let data = {
328
- responses: [],
329
- suggestions: [],
330
- user_events: []
331
- };
332
- const request = {
333
- org_id: orgId,
334
- chat_id: chatId,
335
- user_id: userId
336
- };
337
- try {
338
- data = await CommerceApiClient.getInstance().defaultApi.v1GetSessionMessages(request);
339
- } catch (error) {
340
- await throwSessionRestartRequiredIf("Failed to get chat responses", error);
341
- }
342
- const responses = data?.responses?.map((turn) => turn.map((response) => validateResponse(response)).filter((response) => response != null));
343
- const suggestions = data?.suggestions.map((suggestion) => validateSuggestion(suggestion)).filter((suggestion) => suggestion != null);
344
- const userEvents = data?.user_events.map((event) => validateUserEvent(event)).filter((event) => event != null);
345
- const formSubmittedUserEventsFormIds = userEvents.filter((event) => event.category === UserEventCategory.FormSubmitted).map((event) => event.attributes.formResponseId);
346
- const assistantMessages = responses.map((turn) => turn.filter((response) => !(response.category === ResponseCategory.Form && formSubmittedUserEventsFormIds.includes(response.id))).map((response) => messageFromResponse(response)).filter((message) => message != null)).filter((turn) => turn.length > 0);
347
- const userMessages = userEvents.map((event) => {
348
- if ([UserEventCategory.QueryTyped, UserEventCategory.Search].includes(event.category)) return [messageFromQueryEvent(event)];
349
- if (event.category === UserEventCategory.SuggestionClicked) return [messageFromSuggestionEvent(event, suggestions)];
350
- if (event.category === UserEventCategory.FormSubmitted) {
351
- const formResponse = responses.flat().find((response) => response.id === event.attributes.formResponseId && event.attributes.formType !== FormType.Escalation);
352
- if (formResponse && formResponse.category === ResponseCategory.Form) return [messageFromFormSubmittedEvent(event, formResponse.attributes)];
353
- }
354
- return [];
355
- }).filter((message) => message.length > 0);
356
- const sortedMessages = [...assistantMessages, ...userMessages].sort((a, b) => new Date(a[0].createdAt).getTime() - new Date(b[0].createdAt).getTime());
357
- return {
358
- responses,
359
- userEvents,
360
- suggestions,
361
- messages: sortedMessages
362
- };
363
- };
364
- }
365
- static {
366
- this.isSupportedEvent = async (payload) => {
367
- try {
368
- const httpResponseText = await (await CommerceApiClient.getInstance().inferenceApi.v1SupportedEventPostRaw({ SupportedEventRequest: coreSupportedEventRequestToApiRequest(payload) })).raw.text();
369
- const httpResponseJson = JSON.parse(httpResponseText);
370
- return {
371
- ...httpResponseJson,
372
- numberOfReviews: httpResponseJson.num_of_reviews,
373
- merchant_tags: httpResponseJson.merchant_tags || []
374
- };
375
- } catch (err) {
376
- logger_default.logError("Failed to get response for v1SupportedEventPost", { err });
377
- return {
378
- supported: false,
379
- ready: false,
380
- category: void 0,
381
- collections: [],
382
- numberOfReviews: void 0,
383
- top_category: void 0,
384
- merchant_tags: []
385
- };
386
- }
387
- };
388
- }
389
- static {
390
- this.identifyUser = async (spiffyUserId, merchantUserId, uaDetails) => {
391
- try {
392
- await CommerceApiClient.getInstance().defaultApi.v1AnalyticsIdentifyPost({ AnalyticsIdentifyRequest: {
393
- user_id: spiffyUserId,
394
- os_name: uaDetails.os,
395
- os_version: uaDetails.osVersion,
396
- platform: uaDetails.os,
397
- device_id: uaDetails.deviceModel,
398
- device_brand: uaDetails.deviceBrand,
399
- device_manufacturer: uaDetails.deviceManufacturer,
400
- device_model: uaDetails.deviceModel,
401
- user_properties: {
402
- cdp_user_id: merchantUserId,
403
- browser: uaDetails.browser,
404
- browser_version: uaDetails.browserVersion,
405
- user_agent: uaDetails.userAgent
406
- }
407
- } });
408
- } catch (err) {
409
- logger_default.logError("Failed to identify user", err);
410
- }
411
- };
412
- }
413
- static {
414
- this.mapContextSourceToV1OrgConfigGetSource = (source) => {
415
- if (source === void 0) return void 0;
416
- switch (source) {
417
- case ContextSourceEnum.Fork: return V1OrgConfigGetSourceEnum.Fork;
418
- case ContextSourceEnum.Playground: return V1OrgConfigGetSourceEnum.Playground;
419
- case ContextSourceEnum.App: return V1OrgConfigGetSourceEnum.App;
420
- case ContextSourceEnum.Test: return V1OrgConfigGetSourceEnum.Test;
421
- default: return source;
422
- }
423
- };
424
- }
425
- static {
426
- this.getOrgConfig = async (user_id) => {
427
- try {
428
- const atomStore = getAtomStore();
429
- const reactAppName = atomStore.get(reactAppNameAtom);
430
- const contextSource = atomStore.get(contextSourceAtom);
431
- const featureFlagService = atomStore.get(featureFlagServiceAtom);
432
- const request = {
433
- namespace: reactAppName,
434
- user_id,
435
- source: this.mapContextSourceToV1OrgConfigGetSource(contextSource),
436
- include_experiments: Object.values(ProductExperiment),
437
- include_feature_gates: Object.entries(featureFlagService?.featureFlagService?.getFeatureFlags() || {}).filter(([, isEnabled]) => isEnabled).map(([featureGateName]) => featureGateName)
438
- };
439
- const response = await CommerceApiClient.getInstance().defaultApi.v1OrgConfigGet(request);
440
- return validateOrgConfigResults(response);
441
- } catch (err) {
442
- logger_default.logError(`Failed to get org config`, err, { err });
443
- return;
444
- }
445
- };
446
- }
447
- static {
448
- this.addNoteToLatestConversation = async (spiffyUserId, email, customerServiceProvider) => {
449
- logger_default.logInfo(`addNoteToLatestConversation - user_id=${spiffyUserId} email=${email} customer_service_provider=${customerServiceProvider}`);
450
- try {
451
- await CommerceApiClient.getInstance().customerServiceApi.v1CustserviceAddNoteToLatestConversationPost({ AddNoteToLatestConversationRequest: {
452
- spiffy_user_id: spiffyUserId,
453
- email,
454
- customer_service_provider: customerServiceProvider
455
- } });
456
- } catch (err) {
457
- logger_default.logError("Failed to add note to latest conversation", { err });
458
- }
459
- };
460
- }
461
- static {
462
- this.getCustomerServiceApi = () => CommerceApiClient.getInstance().customerServiceApi;
463
- }
464
- };
465
- var commerce_api_default = CommerceApiClient;
466
-
467
- //#endregion
468
- //#region src/contexts/userIdentityContext/userIdentityContext.tsx
469
- const getUserAgentDetails = () => {
470
- const result = new UAParser().getResult();
471
- return {
472
- os: result?.os?.name,
473
- osVersion: result?.os?.version,
474
- deviceBrand: result?.device?.vendor,
475
- deviceManufacturer: result?.device?.vendor,
476
- deviceModel: result?.device?.model,
477
- browser: result?.browser?.name,
478
- browserVersion: result?.browser?.version,
479
- userAgent: result?.ua
480
- };
481
- };
482
- const UserIdentityContext = createContext(void 0);
483
- const UserIdentityProvider = ({ children }) => {
484
- const { getItem, setItem, isAvailable: localStorageIsReady } = useLocalStorage();
485
- const [isReady, setIsReady] = useState(false);
486
- useEffect(() => {
487
- setIsReady(localStorageIsReady);
488
- }, [localStorageIsReady]);
489
- const USER_ID_OVERRIDE_KEY = "v1-spiffy-user-id-override";
490
- const USER_ID_DEFAULT_KEY = "v1-spiffy-user-id-default";
491
- const getUserIdOverrideFromLocalStorage = useCallback(() => {
492
- return getItem(USER_ID_OVERRIDE_KEY) ?? void 0;
493
- }, [getItem]);
494
- const getUserIdDefaultFromLocalStorage = useCallback(() => {
495
- return getItem(USER_ID_DEFAULT_KEY) ?? void 0;
496
- }, [getItem]);
497
- const setUserIdDefaultInLocalStorage = useCallback((userId) => {
498
- logger_default.logInfo(`setUserIdDefaultInLocalStorage - Setting user_id=${userId}`);
499
- setItem(USER_ID_DEFAULT_KEY, userId);
500
- return userId;
501
- }, [setItem, USER_ID_DEFAULT_KEY]);
502
- const setUserIdOverrideInLocalStorage = useCallback((userId) => {
503
- logger_default.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
504
- setItem(USER_ID_OVERRIDE_KEY, userId);
505
- return userId;
506
- }, [setItem, USER_ID_OVERRIDE_KEY]);
507
- const clearUserIdOverrideInLocalStorage = useCallback(() => {
508
- logger_default.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
509
- setItem(USER_ID_OVERRIDE_KEY, "");
510
- }, [setItem, USER_ID_OVERRIDE_KEY]);
511
- const getUserIdOrDefault = useCallback(() => {
512
- const userIdOverride = getUserIdOverrideFromLocalStorage();
513
- if (userIdOverride) return userIdOverride;
514
- const defaultUserId = getUserIdDefaultFromLocalStorage();
515
- if (defaultUserId) return defaultUserId;
516
- return setUserIdDefaultInLocalStorage(`spiffy-user-id-${v4()}`);
517
- }, [
518
- getUserIdOverrideFromLocalStorage,
519
- getUserIdDefaultFromLocalStorage,
520
- setUserIdDefaultInLocalStorage
521
- ]);
522
- const identifyUser = useCallback(async () => {
523
- if (!isReady) {
524
- logger_default.logWarn("[UserIdentityContext] Context not ready, skipping identifyUser", void 0);
525
- return;
526
- }
527
- try {
528
- const cdpUserId = "UNKNOWN_CDP_USER_ID";
529
- const userId = getUserIdOrDefault();
530
- const userAgentDetails = getUserAgentDetails();
531
- await commerce_api_default.identifyUser(userId, cdpUserId, userAgentDetails);
532
- } catch (error) {
533
- logger_default.logError("[spiffy-ai] Error identifying user", error);
534
- }
535
- }, [isReady, getUserIdOrDefault]);
536
- const value = useMemo(() => ({
537
- identifyUser,
538
- getUserIdOrDefault,
539
- getUserIdOverrideFromLocalStorage,
540
- getUserIdDefaultFromLocalStorage,
541
- setUserIdDefaultInLocalStorage,
542
- setUserIdOverrideInLocalStorage,
543
- clearUserIdOverrideInLocalStorage,
544
- isReady
545
- }), [
546
- identifyUser,
547
- getUserIdOrDefault,
548
- getUserIdOverrideFromLocalStorage,
549
- getUserIdDefaultFromLocalStorage,
550
- setUserIdDefaultInLocalStorage,
551
- setUserIdOverrideInLocalStorage,
552
- clearUserIdOverrideInLocalStorage,
553
- isReady
554
- ]);
555
- return /* @__PURE__ */ jsx(UserIdentityContext.Provider, {
556
- value,
557
- children
558
- });
559
- };
560
- const useUserIdentity = () => {
561
- const context = useContext(UserIdentityContext);
562
- if (!context) throw new Error("useUserIdentity must be used within a UserIdentityProvider");
563
- return context;
564
- };
565
-
566
- //#endregion
567
- //#region src/atoms/app/variant.ts
568
- const internalStorageUrlResolverAtom = atomWithStorage("spiffy-url-resolver", void 0, sessionStorageUtil, { getOnInit: true });
569
- const urlResolverAtom = atom((get) => {
570
- const maybeUrlResolver = get(internalStorageUrlResolverAtom);
571
- if (maybeUrlResolver == null) return {};
572
- return JSON.parse(maybeUrlResolver);
573
- }, (get, set, value) => {
574
- const newCache = {
575
- ...get(urlResolverAtom),
576
- [value.url]: value.response
577
- };
578
- set(internalStorageUrlResolverAtom, JSON.stringify(newCache));
579
- });
580
- const internalStorageSupportedEventAtom = atomWithStorage("spiffy-supported-event", void 0, sessionStorageUtil, { getOnInit: true });
581
- const internalSupportedEventAtom = atom(void 0);
582
- const supportedEventAtom = atom((get) => {
583
- const maybeSupportedEvent = get(internalStorageSupportedEventAtom);
584
- if (maybeSupportedEvent == null) return;
585
- return JSON.parse(maybeSupportedEvent);
586
- }, (_, set, value) => {
587
- if (value == null) {
588
- set(internalStorageSupportedEventAtom, void 0);
589
- set(internalSupportedEventAtom, void 0);
590
- return;
591
- }
592
- set(internalSupportedEventAtom, value);
593
- set(internalStorageSupportedEventAtom, JSON.stringify(value));
594
- });
595
- const internalVariantIdAtom = atom();
596
- const internalProductIdAtom = atom();
597
- const internalParentProductIdAtom = atom();
598
- const internalProductUrlAtom = atom();
599
- const internalPlpIdAtom = atom();
600
- const internalUrlAtom = atom();
601
- const internalPageVisitCategoryAtom = atom();
602
- const internalVariantAtom = atom("pdp");
603
- const variantIdAtom = atom((get) => get(internalVariantIdAtom));
604
- const productIdAtom = atom((get) => get(internalProductIdAtom));
605
- const parentProductIdAtom = atom((get) => get(internalParentProductIdAtom));
606
- const productUrlAtom = atom((get) => get(internalProductUrlAtom));
607
- const plpIdAtom = atom((get) => get(internalPlpIdAtom));
608
- const urlAtom = atom((get) => get(internalUrlAtom));
609
- const pageVisitCategoryAtom = atom((get) => get(internalPageVisitCategoryAtom));
610
- const variantAtom = atom((get) => get(internalVariantAtom));
611
- const hasParsedVariantInfoAtom = atom(false);
612
- const variantInfoAtom = atom((get) => {
613
- const variant = get(variantAtom);
614
- if (variant === VariantTypeEnum.Pdp) return {
615
- variantId: get(variantIdAtom),
616
- variant,
617
- productId: get(productIdAtom),
618
- parentProductId: get(parentProductIdAtom),
619
- url: get(urlAtom)
620
- };
621
- if (variant === VariantTypeEnum.Plp) return {
622
- variantId: get(variantIdAtom),
623
- variant,
624
- plpId: get(plpIdAtom),
625
- url: get(urlAtom)
626
- };
627
- if (variant === VariantTypeEnum.PageVisit) return {
628
- variantId: get(variantIdAtom),
629
- variant,
630
- url: get(urlAtom),
631
- pageVisitCategory: get(pageVisitCategoryAtom)
632
- };
633
- throw new Error("Invalid variantInfo details");
634
- }, (_, set, newVariant) => {
635
- set(internalVariantAtom, newVariant.variant);
636
- set(internalVariantIdAtom, newVariant.variantId);
637
- if (newVariant.variant === VariantTypeEnum.Pdp) {
638
- set(internalProductIdAtom, newVariant.productId);
639
- set(internalParentProductIdAtom, newVariant.parentProductId);
640
- set(internalUrlAtom, newVariant.url);
641
- }
642
- if (newVariant.variant === VariantTypeEnum.Plp) {
643
- set(internalPlpIdAtom, newVariant.plpId);
644
- set(internalUrlAtom, newVariant.url);
645
- }
646
- if (newVariant.variant === VariantTypeEnum.PageVisit) {
647
- set(internalUrlAtom, newVariant.url);
648
- set(internalPageVisitCategoryAtom, newVariant.pageVisitCategory);
649
- }
650
- });
651
-
652
- //#endregion
653
- //#region src/atoms/app/index.ts
654
- const internalUserIdAtom = atom(void 0);
655
- const userIdAtom = atom((get) => {
656
- const maybeUserId = get(internalUserIdAtom);
657
- if (maybeUserId) return maybeUserId;
658
- const { getUserIdOrDefault } = useUserIdentity();
659
- return getUserIdOrDefault();
660
- }, (_, set, value) => {
661
- set(internalUserIdAtom, value);
662
- });
663
- const userIdentityAtom = atom(void 0);
664
- const appSourceAtom = atom((get) => get(contextSourceAtom) ?? ContextSourceEnum.App);
665
- const chatIdAtom = atomWithStorage("v1-spiffy-chat-session-id", v4(), void 0, { getOnInit: true });
666
-
667
- //#endregion
668
- //#region src/contexts/amplitudeContext/amplitudeContext.tsx
669
- let SpiffyMetricsEventName = /* @__PURE__ */ function(SpiffyMetricsEventName$1) {
670
- SpiffyMetricsEventName$1["BundleLoaded"] = "Bundle Loaded";
671
- SpiffyMetricsEventName$1["ChatLiveAgentBtnClick"] = "Chat Live Agent Btn Click";
672
- SpiffyMetricsEventName$1["ChatFloatingButtonVisible"] = "Chat Floating Button Visible";
673
- SpiffyMetricsEventName$1["ChatComponentVisible"] = "Chat Component Visible";
674
- SpiffyMetricsEventName$1["ChatComponentExpanded"] = "Chat Component Expanded";
675
- SpiffyMetricsEventName$1["ChatComponentCollapsed"] = "Chat Component Collapsed";
676
- SpiffyMetricsEventName$1["ChatUserMessageInput"] = "Chat User Message Input";
677
- SpiffyMetricsEventName$1["ChatSuggestionClicked"] = "Chat Suggestion Clicked";
678
- SpiffyMetricsEventName$1["ChatAssistantResponse"] = "Chat Assistant Response";
679
- SpiffyMetricsEventName$1["ProductCardClicked"] = "Product Card Clicked";
680
- SpiffyMetricsEventName$1["ProductReviewCardClicked"] = "Product Review Card Clicked";
681
- SpiffyMetricsEventName$1["AddToCartClicked"] = "Add to Cart Clicked";
682
- SpiffyMetricsEventName$1["PromptCardClicked"] = "Prompt Card Clicked";
683
- SpiffyMetricsEventName$1["SupportedEvent"] = "Supported Event";
684
- SpiffyMetricsEventName$1["SearchBackToResponseClicked"] = "Search Back to Response Clicked";
685
- SpiffyMetricsEventName$1["PerformanceMetrics"] = "Performance Metrics";
686
- SpiffyMetricsEventName$1["SearchBarClicked"] = "Search Bar Clicked";
687
- SpiffyMetricsEventName$1["OrderLookupStarted"] = "Order Lookup Started";
688
- SpiffyMetricsEventName$1["OrderLookupFormSubmitted"] = "Order Lookup Form Submitted";
689
- SpiffyMetricsEventName$1["SearchComponentVisible"] = "Search Component Visible";
690
- SpiffyMetricsEventName$1["SearchZeroStateSuggestionClicked"] = "Search Zero State Suggestion Clicked";
691
- SpiffyMetricsEventName$1["SearchInputStarted"] = "Search Input Started";
692
- SpiffyMetricsEventName$1["SearchQuerySubmitted"] = "Search Query Submitted";
693
- SpiffyMetricsEventName$1["SearchResultsViewed"] = "Search Results Viewed";
694
- SpiffyMetricsEventName$1["SearchTimeToFirstClick"] = "Search Time to First Click";
695
- SpiffyMetricsEventName$1["SearchZeroResultsRate"] = "Search Zero Results Rate";
696
- SpiffyMetricsEventName$1["SearchFilterClicked"] = "Search Filter Clicked";
697
- SpiffyMetricsEventName$1["SearchSortClicked"] = "Search Sort Clicked";
698
- return SpiffyMetricsEventName$1;
699
- }({});
700
- const AmplitudeContext = createContext(null);
701
- const AmplitudeProvider = ({ children }) => {
702
- const userId = useAtomValue(userIdAtom);
703
- const amplitudeApiKey = useAtomValue(amplitudeApiKeyAtom);
704
- const dataResidency = useAtomValue(dataResidencyAtom);
705
- const orgGaConfig = useAtomValue(orgAnalyticsGoogleAnalyticsConfigAtom);
706
- const env = useAtomValue(envAtom);
707
- const contextSource = useAtomValue(contextSourceAtom);
708
- useAtomValue(identifyingPrefixAtom);
709
- const { getItem } = useLocalStorage();
710
- const { publicKey, featureOverrides, variantUrlOverride, variantInfoOverride, show, orgShortName, featureGates } = useEnviveConfig();
711
- const { featureFlagService } = useFeatureFlagService();
712
- const [amplitudeClient, setAmplitudeClient] = React.useState(void 0);
713
- const [internalEventTrackingEnrichment, setInternalEventTrackingEnrichment] = React.useState(void 0);
714
- const [supplementalDefaultProps, setSupplementalDefaultProps] = React.useState({});
715
- const isReady = Boolean(userId && featureFlagService && amplitudeApiKey && userId);
716
- const getDefaultTrackingProps = useCallback(() => {
717
- const gatesProps = featureGates ? featureGates.reduce((acc, curr) => {
718
- if (curr.name && curr.value != null) return {
719
- ...acc,
720
- [`feature_gate.${curr.name}`]: curr.value
721
- };
722
- return acc;
723
- }, {}) : {};
724
- const experimentProps = {};
725
- return {
726
- ...gatesProps,
727
- ...experimentProps,
728
- ...supplementalDefaultProps,
729
- app_id: "commerce-chat-react-component",
730
- chat_id: getItem(LocalStorageKeys.ChatId),
731
- env: env || "unknown",
732
- app_source: contextSource,
733
- "org.short_name": orgShortName,
734
- "user.id": userId,
735
- "cdp.user_id": null,
736
- "cdp.provider": null,
737
- "event.source": "web-browser",
738
- "event.type": "user-activity",
739
- "event.id": null,
740
- "event.channel": "web",
741
- "event.timestamp": null
742
- };
743
- }, [
744
- featureGates,
745
- supplementalDefaultProps,
746
- env,
747
- contextSource,
748
- orgShortName,
749
- userId
750
- ]);
751
- const eventPropsToPrefixedEventProps = useCallback((eventName, eventProps) => {
752
- const prefix = eventName.toLowerCase().replace(/\s+/g, "_");
753
- return Object.entries(eventProps).reduce((acc, [key, value$1]) => {
754
- acc[`${prefix}.${key}`] = value$1;
755
- return acc;
756
- }, {});
757
- }, []);
758
- const amplitudeSessionReplayInit = useCallback(() => {
759
- const isEnabled = Boolean(orgShortName === OrgShortName.UniqueVintage && featureFlagService?.isClientSessionEnabled() && featureFlagService?.isFeatureGateEnabled(FeatureGates.IsNewFeatureEnabled));
760
- const sampleRate = 1;
761
- try {
762
- logger_default.logDebug(`[spiffy-ai] amplitude session-replay initializing isEnabled=${isEnabled} sampleRate=${sampleRate}`);
763
- if (!isEnabled) return isEnabled;
764
- return isEnabled;
765
- } catch (e) {
766
- logger_default.logError("[spiffy-ai] Error initializing amplitude session-replay", e);
767
- return false;
768
- }
769
- }, [orgShortName, featureFlagService]);
770
- const getEventTrackingEnrichment = useCallback(() => {
771
- if (internalEventTrackingEnrichment !== void 0) return internalEventTrackingEnrichment;
772
- const enrichment = {
773
- name: "page-view-tracking-enrichment",
774
- type: "enrichment",
775
- setup: async () => void 0,
776
- execute: async (event) => {
777
- let enrichedEvent;
778
- if (["[Amplitude] Page Viewed", `[Spiffy] ${SpiffyMetricsEventName.BundleLoaded}`].includes(event.event_type)) {
779
- const globalProperties = {};
780
- if (publicKey) globalProperties["globalProperties.publicKey"] = publicKey;
781
- if (featureOverrides) Object.entries(featureOverrides).forEach(([key, value$1]) => {
782
- globalProperties[`globalProperties.featureOverrides.${key}`] = String(value$1);
783
- });
784
- if (variantUrlOverride) globalProperties["globalProperties.variantUrlOverride"] = variantUrlOverride;
785
- if (variantInfoOverride) globalProperties["globalProperties.variantInfoOverride"] = JSON.stringify(variantInfoOverride);
786
- if (show != null) globalProperties["globalProperties.show"] = String(show);
787
- const enabledFeatures = featureFlagService.getFeatureFlags();
788
- const enabledFeaturesProperties = Object.entries(enabledFeatures).reduce((acc, [key, value$1]) => ({
789
- ...acc,
790
- [`enabledFeatures.${key}`]: `${value$1}`
791
- }), {});
792
- const timingProperties = { "timing.enriched_at_ms": window.performance?.now() };
793
- enrichedEvent = {
794
- ...event,
795
- event_properties: {
796
- ...event.event_properties,
797
- ...getDefaultTrackingProps(),
798
- ...globalProperties,
799
- ...enabledFeaturesProperties,
800
- ...timingProperties
801
- }
802
- };
803
- } else enrichedEvent = event;
804
- EventsDispatcher.dispatch(SpiffyEvent.AMPLITUDE_EVENT, enrichedEvent);
805
- return enrichedEvent;
806
- }
807
- };
808
- setInternalEventTrackingEnrichment(enrichment);
809
- return enrichment;
810
- }, [
811
- internalEventTrackingEnrichment,
812
- getDefaultTrackingProps,
813
- featureFlagService,
814
- publicKey,
815
- featureOverrides,
816
- variantUrlOverride,
817
- variantInfoOverride,
818
- show
819
- ]);
820
- useEffect(() => {
821
- if (isReady && !amplitudeClient) {
822
- const currentAmplitudeInstance = createInstance();
823
- const isSessionsEnabled = amplitudeSessionReplayInit();
824
- currentAmplitudeInstance.add(getEventTrackingEnrichment());
825
- currentAmplitudeInstance.init(amplitudeApiKey, userId, {
826
- serverZone: dataResidency,
827
- trackingOptions: { ipAddress: true },
828
- autocapture: {
829
- attribution: true,
830
- pageViews: { trackHistoryChanges: "pathOnly" },
831
- sessions: isSessionsEnabled,
832
- formInteractions: false,
833
- fileDownloads: false
834
- }
835
- });
836
- setAmplitudeClient(currentAmplitudeInstance);
837
- }
838
- }, [
839
- isReady,
840
- amplitudeClient,
841
- amplitudeApiKey,
842
- userId,
843
- dataResidency,
844
- amplitudeSessionReplayInit,
845
- getEventTrackingEnrichment
846
- ]);
847
- const trackEvent = useCallback(async ({ eventName, eventProps, eventGroups, alsoSendToGoogleAnalytics = false }) => {
848
- logger_default.logDebug("Submitting event", eventName);
849
- try {
850
- const decoratedEventName = `[Spiffy] ${eventName}`;
851
- if (!amplitudeClient) {
852
- logger_default.logWarn("amplitude client undefined", void 0, { event_name: decoratedEventName });
853
- return;
854
- }
855
- const eventData = JSON.stringify({
856
- eventName,
857
- eventProps,
858
- created_at: (/* @__PURE__ */ new Date()).toISOString()
859
- });
860
- const data = new TextEncoder().encode(eventData);
861
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
862
- const currentInsertId = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
863
- logger_default.logDebug(`amplitude tracking ${decoratedEventName}`, null, {
864
- event_name: decoratedEventName,
865
- props: eventProps
866
- });
867
- amplitudeClient.track(decoratedEventName, {
868
- ...getDefaultTrackingProps(),
869
- ...eventProps,
870
- ...eventProps ? eventPropsToPrefixedEventProps(eventName, eventProps) : {}
871
- }, {
872
- ...eventGroups,
873
- insert_id: currentInsertId
874
- });
875
- if (alsoSendToGoogleAnalytics && orgGaConfig) {
876
- logger_default.logDebug("[spiffy-ai] GA tracking", decoratedEventName);
877
- if (window.dataLayer) window.dataLayer.push({
878
- event: decoratedEventName,
879
- eventProps
880
- });
881
- }
882
- } catch (err) {
883
- logger_default.logError("[spiffy-ai] Error tracking event", err, {
884
- eventName,
885
- eventProps
886
- });
887
- }
888
- }, [
889
- amplitudeClient,
890
- getDefaultTrackingProps,
891
- eventPropsToPrefixedEventProps,
892
- orgGaConfig
893
- ]);
894
- const value = useMemo(() => ({
895
- trackEvent,
896
- isReady,
897
- setSupplementalDefaultProps: (props) => setSupplementalDefaultProps(props)
898
- }), [
899
- trackEvent,
900
- isReady,
901
- setSupplementalDefaultProps
902
- ]);
903
- return /* @__PURE__ */ jsx(AmplitudeContext.Provider, {
904
- value,
905
- children
906
- });
907
- };
908
- const useAmplitude = () => {
909
- const context = useContext(AmplitudeContext);
910
- if (!context) throw new Error("useAmplitude must be used within AmplitudeProvider");
911
- return context;
912
- };
913
-
914
- //#endregion
915
- //#region src/application/utils/analyticsUtils.ts
916
- const NORMALIZED_ADD_TO_CART_EVENT_NAMES = ["addtocart", "addedtocart"];
917
- const CHECK_DATA_LAYER_INTERVAL_MS = 500;
918
- const CHECK_DATA_LAYER_MAX_ATTEMPTS = 10;
919
- /**
920
- * Checks if a Google Analytics event is an add_to_cart event.
921
- *
922
- * @param event The event name to check.
923
- *
924
- * @returns True if the event is an add_to_cart event, false otherwise.
925
- */
926
- const isAddToCartEvent = (event) => {
927
- const normalizedEvent = event.replace(/[-_]/g, "").toLowerCase();
928
- return NORMALIZED_ADD_TO_CART_EVENT_NAMES.some((name) => normalizedEvent.includes(name));
929
- };
930
- /**
931
- * Tracks an add_to_cart event in Amplitude.
932
- *
933
- * @param event The event to track.
934
- */
935
- const handleAddToCartEvent = (event, track) => {
936
- let eventProps;
937
- if (isLegacyUAEcommerceEvent(event)) eventProps = {
938
- items: event.ecommerce.add.products.map((product) => ({
939
- item_name: product.name,
940
- item_category: product.category,
941
- price: product.price,
942
- quantity: product.quantity
943
- })),
944
- currency: event.ecommerce.add.currencyCode,
945
- event_format_version: "legacy_universal_analytics"
946
- };
947
- else if (isGA4EcommerceEvent(event)) eventProps = {
948
- items: event.ecommerce.items.map((item) => ({
949
- item_name: item.item_name,
950
- item_category: item.item_category,
951
- price: item.price,
952
- quantity: item.quantity
953
- })),
954
- currency: event.ecommerce.currency,
955
- event_format_version: "google_analytics_4"
956
- };
957
- else eventProps = {
958
- event_properties: { ...event },
959
- event_format_version: "unknown"
960
- };
961
- track(SpiffyMetricsEventName.AddToCartClicked, { eventProps });
962
- };
963
- /**
964
- * Wraps the window.dataLayer.push method to intercept add_to_cart events and send them to Amplitude.
965
- * This function runs on an interval until the dataLayer is available.
966
- */
967
- const initDataLayerWrapper = (track) => {
968
- let attempts = 0;
969
- const checkAndInitialize = () => {
970
- if (!window.dataLayer || !window.dataLayer.push) {
971
- attempts += 1;
972
- if (attempts >= CHECK_DATA_LAYER_MAX_ATTEMPTS) {
973
- logger_default.logDebug(`[spiffy-ai] dataLayer not available after ${CHECK_DATA_LAYER_MAX_ATTEMPTS} attempts`);
974
- return;
975
- }
976
- setTimeout(checkAndInitialize, CHECK_DATA_LAYER_INTERVAL_MS);
977
- return;
978
- }
979
- logger_default.logDebug("[spiffy-ai] dataLayer is available, wrapping push function...");
980
- const originalPush = window.dataLayer.push;
981
- window.dataLayer.push = (...args) => {
982
- if (isBaseEcommerceEvent(args[0]) && isAddToCartEvent(args[0].event)) handleAddToCartEvent(args[0], track);
983
- return originalPush.apply(window.dataLayer, args);
984
- };
985
- };
986
- checkAndInitialize();
987
- };
988
- const initAmplitude = (track) => {
989
- track(SpiffyMetricsEventName.BundleLoaded);
990
- };
991
-
992
- //#endregion
993
- //#region src/application/utils/divideArray.ts
994
- const divideArray = (array, size) => {
995
- const rows = [];
996
- for (let i = 0; i < size; i += 1) rows.push(array.filter((_, index) => index % size === i));
997
- return rows;
998
- };
999
-
1000
- //#endregion
1001
- //#region src/application/utils/imageFilter.ts
1002
- const getRecentProductImageUrls = (lastMessages, currentProductId) => {
1003
- const productMessages = lastMessages.filter((message) => message.type === MessageType.Product && message.metadata?.imageUrl).map((m) => m);
1004
- return [...productMessages.filter((m) => m.metadata?.id === currentProductId), ...productMessages.filter((m) => m.metadata?.id !== currentProductId)].map((m) => m.metadata.imageUrl);
1005
- };
1006
-
1007
- //#endregion
1008
- //#region src/application/utils/merchantUtils.ts
1009
- const prepareMerchantPage = () => {
1010
- let metaViewport = document.querySelector("meta[name='viewport']");
1011
- if (metaViewport) {
1012
- const content = metaViewport.getAttribute("content");
1013
- if (!content?.includes("maximum-scale=1")) metaViewport.setAttribute("content", `${content}, maximum-scale=1`);
1014
- return;
1015
- }
1016
- metaViewport = document.createElement("meta");
1017
- metaViewport.setAttribute("name", "viewport");
1018
- metaViewport.setAttribute("content", "width=device-width, initial-scale=1, maximum-scale=1");
1019
- document.head.appendChild(metaViewport);
1020
- };
1021
-
1022
- //#endregion
1023
- //#region src/application/utils/messageFromQueryEvent.ts
1024
- /**
1025
- * Transforms a query UserEvent object into a Message object for presentation.
1026
- *
1027
- * @param event The user event object received from the server
1028
- *
1029
- * @returns A Message if the event is a query event, otherwise undefined
1030
- */
1031
- const messageFromQueryEvent = (event) => {
1032
- if (event.category === UserEventCategory.QueryTyped) return {
1033
- id: event.eventId,
1034
- role: MessageRole.User,
1035
- type: MessageType.QueryTyped,
1036
- createdAt: event.createdAt,
1037
- metadata: { content: event.attributes.query }
1038
- };
1039
- if (event.category === UserEventCategory.Search) return {
1040
- id: event.eventId,
1041
- role: MessageRole.User,
1042
- type: MessageType.Search,
1043
- createdAt: event.createdAt,
1044
- metadata: {
1045
- searchTerm: event.attributes.searchTerm || "",
1046
- selectedFilters: event.attributes.selectedFilters || []
1047
- }
1048
- };
1049
- };
1050
-
1051
- //#endregion
1052
- //#region src/application/utils/messageFromResponse.ts
1053
- /**
1054
- * Transforms a server Response object into a Message object for presentation.
1055
- *
1056
- * @param response The response object received from the server containing model generated content
1057
- *
1058
- * @returns A Message if the response contains known attributes, undefined otherwise
1059
- */
1060
- const messageFromResponse = (response) => {
1061
- if (response == null) return;
1062
- if (response.category === ResponseCategory.Text) return {
1063
- id: response.id,
1064
- createdAt: response.createdAt,
1065
- type: MessageType.Text,
1066
- role: MessageRole.Assistant,
1067
- metadata: { content: response.attributes.content }
1068
- };
1069
- if (response.category === ResponseCategory.Product) return {
1070
- id: response.id,
1071
- createdAt: response.createdAt,
1072
- role: MessageRole.Assistant,
1073
- type: MessageType.Product,
1074
- metadata: { ...response.attributes }
1075
- };
1076
- if (response.category === ResponseCategory.Review) return {
1077
- id: response.id,
1078
- createdAt: response.createdAt,
1079
- type: MessageType.Review,
1080
- role: MessageRole.Assistant,
1081
- metadata: {
1082
- review: response.attributes.review,
1083
- reviewer: response.attributes.reviewer,
1084
- stars: response.attributes.stars,
1085
- title: response.attributes.title,
1086
- richInformation: response.attributes.richInformation
1087
- }
1088
- };
1089
- if (response.category === ResponseCategory.Separator) return {
1090
- id: response.id,
1091
- createdAt: response.createdAt,
1092
- type: MessageType.Separator,
1093
- role: MessageRole.Assistant
1094
- };
1095
- if (response.category === ResponseCategory.Page) return {
1096
- id: response.id,
1097
- createdAt: response.createdAt,
1098
- role: MessageRole.Assistant,
1099
- type: MessageType.Page,
1100
- metadata: { ...response.attributes }
1101
- };
1102
- if (response.category === ResponseCategory.ProductSearch) return {
1103
- id: response.id,
1104
- createdAt: response.createdAt,
1105
- role: MessageRole.Assistant,
1106
- type: MessageType.ProductSearch,
1107
- metadata: { ...response.attributes }
1108
- };
1109
- if (response.category === ResponseCategory.ProductSearchFilter) return {
1110
- id: response.id,
1111
- createdAt: response.createdAt,
1112
- role: MessageRole.Assistant,
1113
- type: MessageType.ProductSearchFilter,
1114
- metadata: { ...response.attributes }
1115
- };
1116
- if (response.category === ResponseCategory.Form) return {
1117
- id: response.id,
1118
- createdAt: response.createdAt,
1119
- role: MessageRole.Assistant,
1120
- type: MessageType.Form,
1121
- metadata: {
1122
- formType: response.attributes.formCategory?.formType,
1123
- fields: Object.entries(response.attributes.schema.properties).map(([key, value]) => ({
1124
- key,
1125
- title: value.title,
1126
- type: value.type,
1127
- format: value.format,
1128
- required: response.attributes.schema.required.includes(key)
1129
- }))
1130
- }
1131
- };
1132
- if (response.category === ResponseCategory.Order) return {
1133
- id: response.id,
1134
- createdAt: response.createdAt,
1135
- role: MessageRole.Assistant,
1136
- type: MessageType.Order,
1137
- metadata: { ...response.attributes }
1138
- };
1139
- };
1140
-
1141
- //#endregion
1142
- //#region src/application/utils/messageFromSuggestionEvent.ts
1143
- /**
1144
- * Transforms a UserEvent object into a Message object for presentation.
1145
- *
1146
- * @param event The UserEvent object received from the server
1147
- * @param suggestions A list of generated suggestions to match the event to
1148
- *
1149
- * @returns A Message if the event is a suggestion click event, undefined otherwise
1150
- */
1151
- const messageFromSuggestionEvent = (event, suggestions) => {
1152
- if (event.category === UserEventCategory.SuggestionClicked) {
1153
- const { suggestionId } = event.attributes;
1154
- return {
1155
- id: event.eventId,
1156
- role: MessageRole.User,
1157
- type: MessageType.SuggestionClicked,
1158
- createdAt: event.createdAt,
1159
- metadata: {
1160
- suggestionId,
1161
- suggestionContent: suggestions.find((s) => s.id === suggestionId)?.content ?? ""
1162
- }
1163
- };
1164
- }
1165
- };
1166
-
1167
- //#endregion
1168
- //#region src/application/utils/nodeSelector.ts
1169
- var NodeSelector = class {
1170
- constructor(pattern) {
1171
- this.pattern = pattern;
1172
- this.root = document;
1173
- }
1174
- getPattern() {
1175
- return this.pattern;
1176
- }
1177
- setRoot(root) {
1178
- this.root = root;
1179
- }
1180
- getRoot() {
1181
- return this.root;
1182
- }
1183
- };
1184
- var QuerySelector = class extends NodeSelector {
1185
- parse() {
1186
- return this.getRoot().querySelector(this.getPattern());
1187
- }
1188
- };
1189
- var IDSelector = class extends NodeSelector {
1190
- parse() {
1191
- return this.getRoot().getElementById(this.getPattern());
1192
- }
1193
- };
1194
- var XpathSelector = class extends NodeSelector {
1195
- parse() {
1196
- return this.getRoot()?.evaluate(this.getPattern(), this.getRoot(), null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)?.singleNodeValue;
1197
- }
1198
- };
1199
- var ChainSelector = class extends NodeSelector {
1200
- parse() {
1201
- let selectorIndex = 0;
1202
- const selectors = this.getPattern().split("@");
1203
- const lastIndex = selectors.length - 1;
1204
- const parseChain = (pattern, prevNode) => {
1205
- const selector = SelectorFactory.parse(pattern);
1206
- if (prevNode) selector.setRoot(prevNode);
1207
- const currentNode = selector.parse();
1208
- if (selectorIndex === lastIndex) return currentNode;
1209
- let node = currentNode || document;
1210
- if (currentNode?.shadowRoot) node = currentNode.shadowRoot;
1211
- if (currentNode?.contentWindow) node = currentNode.contentWindow?.document;
1212
- return parseChain(selectors[++selectorIndex].trim(), node);
1213
- };
1214
- return parseChain(selectors[selectorIndex].trim());
1215
- }
1216
- };
1217
- var Empty = class extends NodeSelector {
1218
- constructor() {
1219
- super("");
1220
- }
1221
- parse() {
1222
- return null;
1223
- }
1224
- };
1225
- var SelectorFactory = class {
1226
- static parse(composedSelector) {
1227
- if (!composedSelector) return new Empty();
1228
- const split = composedSelector.split("|");
1229
- const type = split[0];
1230
- const selector = split[1];
1231
- switch (type) {
1232
- case "id": return this.id(selector);
1233
- case "query": return this.query(selector);
1234
- case "xpath": return this.xpath(selector);
1235
- default: return new Empty();
1236
- }
1237
- }
1238
- static check(selector) {
1239
- return selector ?? new Empty();
1240
- }
1241
- static chain(pattern) {
1242
- return pattern ? new ChainSelector(pattern) : new Empty();
1243
- }
1244
- static id(pattern) {
1245
- return pattern ? new IDSelector(pattern) : new Empty();
1246
- }
1247
- static query(pattern) {
1248
- return pattern ? new QuerySelector(pattern) : new Empty();
1249
- }
1250
- static xpath(pattern) {
1251
- return pattern ? new XpathSelector(pattern) : new Empty();
1252
- }
1253
- };
1254
-
1255
- //#endregion
1256
- //#region src/application/utils/overrides.ts
1257
- function isPlainObject(x) {
1258
- return !!x && typeof x === "object" && !Array.isArray(x) && !(x instanceof Date) && !(x instanceof RegExp);
1259
- }
1260
- function isReplace(x) {
1261
- return !!x && typeof x === "object" && "$replace" in x;
1262
- }
1263
- function isDelete(x) {
1264
- return !!x && typeof x === "object" && x.$delete === true;
1265
- }
1266
- function isPrimitiveValue(x) {
1267
- const t = typeof x;
1268
- return x === null || t === "string" || t === "number" || t === "boolean" || t === "bigint" || t === "symbol" || t === "undefined";
1269
- }
1270
- function isArrayOfPrimitives(arr) {
1271
- if (arr.length === 0) return false;
1272
- for (let i = 0; i < arr.length; i += 1) {
1273
- const v = arr[i];
1274
- if (v !== void 0 && !isPrimitiveValue(v)) return false;
1275
- }
1276
- return true;
1277
- }
1278
- function mergeAny(baseAny, patchAny, opts) {
1279
- if (isReplace(patchAny)) return patchAny.$replace;
1280
- if (isDelete(patchAny)) return void 0;
1281
- if (Array.isArray(baseAny)) {
1282
- if (Array.isArray(patchAny)) {
1283
- const baseArr = baseAny;
1284
- const patchArr = patchAny;
1285
- if (opts.arrayStrategy === "replace" || isArrayOfPrimitives(baseArr) || isArrayOfPrimitives(patchArr)) return patchAny;
1286
- const out = baseArr.slice();
1287
- const max = Math.max(out.length, patchArr.length);
1288
- for (let i = 0; i < max; i += 1) {
1289
- const pVal = patchArr[i];
1290
- if (pVal !== void 0) out[i] = mergeAny(out[i], pVal, opts);
1291
- }
1292
- return out;
1293
- }
1294
- return baseAny;
1295
- }
1296
- if (isPlainObject(baseAny) && isPlainObject(patchAny)) {
1297
- const baseObj = baseAny;
1298
- const patchObj = patchAny;
1299
- const out = { ...baseObj };
1300
- for (const key of Object.keys(patchObj)) {
1301
- const pVal = patchObj[key];
1302
- if (pVal === void 0) {} else if (opts.nullDeletes && pVal === null) delete out[key];
1303
- else if (isReplace(pVal)) out[key] = pVal.$replace;
1304
- else if (isDelete(pVal)) delete out[key];
1305
- else out[key] = mergeAny(baseObj?.[key], pVal, opts);
1306
- }
1307
- return out;
1308
- }
1309
- return patchAny ?? baseAny;
1310
- }
1311
- function applyOverrides(base, patch, opts = {}) {
1312
- const { arrayStrategy = "mergeByIndex", nullDeletes = false } = opts;
1313
- if (isReplace(patch)) return patch.$replace;
1314
- if (isDelete(patch)) return void 0;
1315
- if (Array.isArray(base)) {
1316
- if (isReplace(patch)) return patch.$replace;
1317
- if (Array.isArray(patch)) {
1318
- if (arrayStrategy === "replace") return patch;
1319
- const out = base.slice();
1320
- const max = Math.max(out.length, patch.length);
1321
- for (let i = 0; i < max; i += 1) {
1322
- const pVal = patch[i];
1323
- if (pVal !== void 0) out[i] = mergeAny(out[i], pVal, opts);
1324
- }
1325
- return out;
1326
- }
1327
- return base;
1328
- }
1329
- if (isPlainObject(base) && isPlainObject(patch)) {
1330
- const out = { ...base };
1331
- const patchObj = patch;
1332
- for (const key of Object.keys(patchObj)) {
1333
- const pVal = patchObj[key];
1334
- if (pVal === void 0) {} else if (nullDeletes && pVal === null) delete out[key];
1335
- else if (isReplace(pVal)) out[key] = pVal.$replace;
1336
- else if (isDelete(pVal)) delete out[key];
1337
- else {
1338
- const bVal = base[key];
1339
- out[key] = mergeAny(bVal, pVal, opts);
1340
- }
1341
- }
1342
- return out;
1343
- }
1344
- return patch ?? base;
1345
- }
1346
-
1347
- //#endregion
1348
- //#region src/application/utils/stringUtils.ts
1349
- var StringUtils = class StringUtils {
1350
- static isNullOrEmpty(value) {
1351
- const valueTrimmed = value?.trim();
1352
- return value === void 0 || valueTrimmed === "";
1353
- }
1354
- static trimToNull(value) {
1355
- const valueTrimmed = value?.trim();
1356
- return StringUtils.isNullOrEmpty(valueTrimmed) ? void 0 : valueTrimmed;
1357
- }
1358
- static capitalize(type) {
1359
- if (type === void 0) return "";
1360
- return type.charAt(0).toUpperCase() + type.substring(1);
1361
- }
1362
- /**
1363
- * Finds the first pattern in an array that matches a given URL.
1364
- * Patterns can include a single wildcard '*' which matches any sequence of characters.
1365
- *
1366
- * @param patterns
1367
- * @param urlToTest
1368
- * @returns
1369
- */
1370
- static findMatchingPattern(patterns, urlToTest) {
1371
- if (!urlToTest) return;
1372
- for (const pattern of patterns) if (urlToTest.pathname !== "/") {
1373
- const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
1374
- if ((/* @__PURE__ */ new RegExp(`^${regexPattern}$`)).test(urlToTest.pathname)) return pattern;
1375
- } else if (pattern.startsWith(urlToTest.hostname)) return pattern;
1376
- }
1377
- };
1378
-
1379
- //#endregion
1380
- //#region src/application/utils/validation.ts
1381
- const validateEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
1382
-
1383
- //#endregion
1384
- export { AmplitudeProvider, NodeSelector, SelectorFactory, SessionRestartRequired, SpiffyMetricsEventName, StringUtils, UnsupportedProductException, UserIdentityProvider, appSourceAtom, applyOverrides, chatIdAtom, commerce_api_default, coreContextToApiContext, coreSupportedEventRequestToApiRequest, coreUserEventToApiUserEvent, divideArray, getRecentProductImageUrls, hasParsedVariantInfoAtom, initAmplitude, initDataLayerWrapper, messageFromFormSubmittedEvent, messageFromQueryEvent, messageFromResponse, messageFromSuggestionEvent, messageRequestToCommerceMessageRequest, prepareMerchantPage, supportedEventAtom, useAmplitude, useUserIdentity, userIdAtom, userIdentityAtom, validateEmail, variantInfoAtom };
1385
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMtall0RDNobUEuanMiLCJuYW1lcyI6WyJjb25maWc6IENvbmZpZ3VyYXRpb24iLCJjb250ZXh0OiBDb250ZXh0IiwiZXJyOiB1bmtub3duIiwiZXJyb3I6IHVua25vd24iLCJkYXRhOiBWMUdldFNlc3Npb25NZXNzYWdlczIwMFJlc3BvbnNlIiwicmVzcG9uc2VzOiBSZXNwb25zZVtdW10iLCJzdWdnZXN0aW9uczogU3VnZ2VzdGlvbltdIiwidXNlckV2ZW50czogVXNlckV2ZW50W10iLCJhc3Npc3RhbnRNZXNzYWdlczogTWVzc2FnZVtdW10iLCJ1c2VyTWVzc2FnZXM6IE1lc3NhZ2VbXVtdIiwicmVxdWVzdDogVjFPcmdDb25maWdHZXRSZXF1ZXN0IiwiVXNlcklkZW50aXR5UHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiIsInV1aWQiLCJDb21tZXJjZUFwaUNsaWVudCIsInV1aWQiLCJBbXBsaXR1ZGVQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+IiwidmFsdWUiLCJlbnJpY2htZW50OiBFbnJpY2htZW50UGx1Z2luIiwiZW5yaWNoZWRFdmVudDogRXZlbnQiLCJnbG9iYWxQcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IiwiY3VycmVudEFtcGxpdHVkZUluc3RhbmNlOiBCcm93c2VyQ2xpZW50IiwiZXZlbnRQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4iLCJub2RlOiBOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCIsIm91dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4iXSwic291cmNlcyI6WyIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50LnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL25leHRNZXNzYWdlUmVxdWVzdFRvQXBpUmVxdWVzdC50cyIsIi4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9jb3JlQ29udGV4dFRvQXBpQ29udGV4dC50cyIsIi4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9zdXBwb3J0ZWRFdmVudFJlcXVlc3RUb0FwaVJlcXVlc3QudHMiLCIuLi9zcmMvdHlwZXMvZXhjZXB0aW9ucy9zZXNzaW9uRXhjZXB0aW9ucy50cyIsIi4uL3NyYy90eXBlcy9leGNlcHRpb25zL3Vuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbnMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vY29tbWVyY2UtYXBpLnRzIiwiLi4vc3JjL2NvbnRleHRzL3VzZXJJZGVudGl0eUNvbnRleHQvdXNlcklkZW50aXR5Q29udGV4dC50c3giLCIuLi9zcmMvYXRvbXMvYXBwL3ZhcmlhbnQudHMiLCIuLi9zcmMvYXRvbXMvYXBwL2luZGV4LnRzIiwiLi4vc3JjL2NvbnRleHRzL2FtcGxpdHVkZUNvbnRleHQvYW1wbGl0dWRlQ29udGV4dC50c3giLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvYW5hbHl0aWNzVXRpbHMudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvZGl2aWRlQXJyYXkudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvaW1hZ2VGaWx0ZXIudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVyY2hhbnRVdGlscy50cyIsIi4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9tZXNzYWdlRnJvbVF1ZXJ5RXZlbnQudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvbWVzc2FnZUZyb21SZXNwb25zZS50cyIsIi4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9tZXNzYWdlRnJvbVN1Z2dlc3Rpb25FdmVudC50cyIsIi4uL3NyYy9hcHBsaWNhdGlvbi91dGlscy9ub2RlU2VsZWN0b3IudHMiLCIuLi9zcmMvYXBwbGljYXRpb24vdXRpbHMvb3ZlcnJpZGVzLnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL3N0cmluZ1V0aWxzLnRzIiwiLi4vc3JjL2FwcGxpY2F0aW9uL3V0aWxzL3ZhbGlkYXRpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgVXNlckV2ZW50IGFzIEFwaVVzZXJFdmVudCxcbiAgUExQQXR0cmlidXRlQ2F0ZWdvcnksXG4gIFBMUElkQXR0cmlidXRlcyxcbiAgVXNlckV2ZW50Q2F0ZWdvcnksXG59IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQgeyBVc2VyRXZlbnQgYXMgQ29yZVVzZXJFdmVudCB9IGZyb20gJy4uL21vZGVscyc7XG5cbmV4cG9ydCBjb25zdCBjb3JlVXNlckV2ZW50VG9BcGlVc2VyRXZlbnQgPSAoZGF0YTogQ29yZVVzZXJFdmVudCk6IEFwaVVzZXJFdmVudCA9PiB7XG4gIGlmIChcbiAgICBkYXRhLmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5QZHBWaXNpdCB8fFxuICAgIGRhdGEuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LkFkZFRvQ2FydFxuICApIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXZlbnRfaWQ6IGRhdGEuZXZlbnRJZCxcbiAgICAgIGNyZWF0ZWRfYXQ6IGRhdGEuY3JlYXRlZEF0LFxuICAgICAgY2F0ZWdvcnk6IGRhdGEuY2F0ZWdvcnksXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIHByb2R1Y3RfaWQ6IGRhdGEuYXR0cmlidXRlcy5wcm9kdWN0SWQsXG4gICAgICAgIHBhcmVudF9wcm9kdWN0X2lkOiBkYXRhLmF0dHJpYnV0ZXMucGFyZW50UHJvZHVjdElkLFxuICAgICAgICB1cmw6IGRhdGEuYXR0cmlidXRlcy51cmwsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAoZGF0YS5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuUGxwVmlzaXQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXZlbnRfaWQ6IGRhdGEuZXZlbnRJZCxcbiAgICAgIGNyZWF0ZWRfYXQ6IGRhdGEuY3JlYXRlZEF0LFxuICAgICAgY2F0ZWdvcnk6IGRhdGEuY2F0ZWdvcnksXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIGNhdGVnb3J5OiBQTFBBdHRyaWJ1dGVDYXRlZ29yeS5JZCxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgIC8vIHdlJ3JlIG9ubHkgaGFuZGxpbmcgaWQgYXR0cmlidXRlcyBmb3Igbm93XG4gICAgICAgICAgaWQ6IChkYXRhLmF0dHJpYnV0ZXMuYXR0cmlidXRlcyBhcyBQTFBJZEF0dHJpYnV0ZXMpLmlkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGRhdGEuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlF1ZXJ5VHlwZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXZlbnRfaWQ6IGRhdGEuZXZlbnRJZCxcbiAgICAgIGNyZWF0ZWRfYXQ6IGRhdGEuY3JlYXRlZEF0LFxuICAgICAgY2F0ZWdvcnk6IGRhdGEuY2F0ZWdvcnksXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIHF1ZXJ5OiBkYXRhLmF0dHJpYnV0ZXMucXVlcnksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAoZGF0YS5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuU2VhcmNoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBzZWFyY2hfdGVybTogZGF0YS5hdHRyaWJ1dGVzLnNlYXJjaFRlcm0sXG4gICAgICAgIHNlbGVjdGVkX2ZpbHRlcnM6IGRhdGEuYXR0cmlidXRlcy5zZWxlY3RlZEZpbHRlcnMsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAoZGF0YS5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuU3VnZ2VzdGlvbkNsaWNrZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXZlbnRfaWQ6IGRhdGEuZXZlbnRJZCxcbiAgICAgIGNyZWF0ZWRfYXQ6IGRhdGEuY3JlYXRlZEF0LFxuICAgICAgY2F0ZWdvcnk6IGRhdGEuY2F0ZWdvcnksXG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIHN1Z2dlc3Rpb25faWQ6IGRhdGEuYXR0cmlidXRlcy5zdWdnZXN0aW9uSWQsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAoZGF0YS5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuUGFnZVZpc2l0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICB1cmw6IGRhdGEuYXR0cmlidXRlcy51cmwsXG4gICAgICAgIHBhZ2VfdmlzaXRfY2F0ZWdvcnk6IGRhdGEuYXR0cmlidXRlcy5wYWdlVmlzaXRDYXRlZ29yeSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChkYXRhLmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5Gb3JtU3VibWl0dGVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2ZW50X2lkOiBkYXRhLmV2ZW50SWQsXG4gICAgICBjcmVhdGVkX2F0OiBkYXRhLmNyZWF0ZWRBdCxcbiAgICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBmaWxsZWRfc2NoZW1hOiB7IC4uLmRhdGEuYXR0cmlidXRlcy5maWxsZWRTY2hlbWEgfSxcbiAgICAgICAgZm9ybV9yZXNwb25zZV9pZDogZGF0YS5hdHRyaWJ1dGVzLmZvcm1SZXNwb25zZUlkLFxuICAgICAgICBmb3JtX3R5cGU6IGRhdGEuYXR0cmlidXRlcy5mb3JtVHlwZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQgYXBwX2xvYWRlZCBldmVudCwgd2hlbiB3ZSBzdGFydCB0byB1c2UgYXBwX3VubG9hZGVkIHdlIG5lZWQgdG8gaGFuZGxlIGl0IGhlcmVcbiAgcmV0dXJuIHtcbiAgICBldmVudF9pZDogZGF0YS5ldmVudElkLFxuICAgIGNyZWF0ZWRfYXQ6IGRhdGEuY3JlYXRlZEF0LFxuICAgIGNhdGVnb3J5OiBkYXRhLmNhdGVnb3J5LFxuICB9O1xufTtcbiIsImltcG9ydCB7IE5leHRNZXNzYWdlUmVxdWVzdCBhcyBBcGlOZXh0TWVzc2FnZVJlcXVlc3QgfSBmcm9tICdAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnQnO1xuaW1wb3J0IHsgTmV4dE1lc3NhZ2VSZXF1ZXN0IH0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7IGNvcmVVc2VyRXZlbnRUb0FwaVVzZXJFdmVudCB9IGZyb20gJy4vY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50JztcblxuZXhwb3J0IGNvbnN0IG1lc3NhZ2VSZXF1ZXN0VG9Db21tZXJjZU1lc3NhZ2VSZXF1ZXN0ID0gKFxuICBkYXRhOiBOZXh0TWVzc2FnZVJlcXVlc3QsXG4pOiBBcGlOZXh0TWVzc2FnZVJlcXVlc3QgPT4gKHtcbiAgY29udGV4dDoge1xuICAgIGNoYXRfaWQ6IGRhdGEuY29udGV4dC5jaGF0SWQsXG4gICAgb3JnX2lkOiBkYXRhLmNvbnRleHQub3JnSWQsXG4gICAgb3JnX3Nob3J0X25hbWU6IGRhdGEuY29udGV4dC5vcmdTaG9ydE5hbWUsXG4gICAgdXNlcl9pZDogZGF0YS5jb250ZXh0LnVzZXJJZCxcbiAgICBzb3VyY2U6IGRhdGEuY29udGV4dC5zb3VyY2UsXG4gICAgZW52OiBkYXRhLmNvbnRleHQuZW52LFxuICB9LFxuICBpZDogZGF0YS5pZCxcbiAgZmVhdHVyZV9mbGFnczogZGF0YS5mZWF0dXJlRmxhZ3MsXG4gIHVzZXJfZXZlbnRzOiBkYXRhLnVzZXJFdmVudHM/Lm1hcCgodXNlckV2ZW50KSA9PiBjb3JlVXNlckV2ZW50VG9BcGlVc2VyRXZlbnQodXNlckV2ZW50KSksXG4gIGdlbmVyYXRpb25fcGFyYW1zOiB7XG4gICAgbW9kZWw6IGRhdGEuZ2VuZXJhdGlvblBhcmFtcz8ubW9kZWwsXG4gICAgbWF4X3Rva2VuczogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5tYXhUb2tlbnMsXG4gICAgc3RvcDogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5zdG9wLFxuICAgIHN0cmVhbTogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5zdHJlYW0sXG4gICAgdGVtcGVyYXR1cmU6IGRhdGEuZ2VuZXJhdGlvblBhcmFtcz8udGVtcGVyYXR1cmUsXG4gICAgdG9wX3A6IGRhdGEuZ2VuZXJhdGlvblBhcmFtcz8udG9wUCxcbiAgICBudW1fc3VnZ2VzdGlvbnM6IGRhdGEuZ2VuZXJhdGlvblBhcmFtcz8ubnVtU3VnZ2VzdGlvbnMsXG4gICAgcmVzcG9uc2Vfc3lzdGVtX3Byb21wdDogZGF0YS5nZW5lcmF0aW9uUGFyYW1zPy5yZXNwb25zZVN5c3RlbVByb21wdCxcbiAgICBzdWdnZXN0aW9uX3N5c3RlbV9wcm9tcHQ6IGRhdGEuZ2VuZXJhdGlvblBhcmFtcz8uc3VnZ2VzdGlvblN5c3RlbVByb21wdCxcbiAgICByZXNwb25zZV9jYWNoaW5nOiBkYXRhLmdlbmVyYXRpb25QYXJhbXM/LnJlc3BvbnNlQ2FjaGluZyxcbiAgfSxcbn0pO1xuIiwiaW1wb3J0IHsgQ29udGV4dCBhcyBBcGlDb250ZXh0IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IENvbnRleHQgYXMgQ29yZUNvbnRleHQgfSBmcm9tICcuLi9tb2RlbHMnO1xuXG5leHBvcnQgY29uc3QgY29yZUNvbnRleHRUb0FwaUNvbnRleHQgPSAoY29udGV4dDogQ29yZUNvbnRleHQpOiBBcGlDb250ZXh0ID0+ICh7XG4gIGNoYXRfaWQ6IGNvbnRleHQuY2hhdElkLFxuICBvcmdfaWQ6IGNvbnRleHQub3JnSWQsXG4gIHVzZXJfaWQ6IGNvbnRleHQudXNlcklkLFxuICBvcmdfc2hvcnRfbmFtZTogY29udGV4dC5vcmdTaG9ydE5hbWUsXG4gIHNvdXJjZTogY29udGV4dC5zb3VyY2UsXG4gIGVudjogY29udGV4dC5lbnYsXG59KTtcbiIsImltcG9ydCB7IFN1cHBvcnRlZEV2ZW50UmVxdWVzdCBhcyBBcGlTdXBwb3J0ZWRFdmVudFJlcXVlc3QgfSBmcm9tICdAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnQnO1xuaW1wb3J0IHsgU3VwcG9ydGVkRXZlbnRSZXF1ZXN0IGFzIENvcmVTdXBwb3J0ZWRFdmVudFJlcXVlc3QgfSBmcm9tICcuLi9tb2RlbHMvYXBpL3N1cHBvcnRlZEV2ZW50UmVxdWVzdCc7XG5pbXBvcnQgeyBjb3JlVXNlckV2ZW50VG9BcGlVc2VyRXZlbnQgfSBmcm9tICcuL2NvcmVVc2VyRXZlbnRUb0FwaVVzZXJFdmVudCc7XG5pbXBvcnQgeyBjb3JlQ29udGV4dFRvQXBpQ29udGV4dCB9IGZyb20gJy4vY29yZUNvbnRleHRUb0FwaUNvbnRleHQnO1xuXG5leHBvcnQgY29uc3QgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdFRvQXBpUmVxdWVzdCA9IChcbiAgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdDogQ29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdCxcbik6IEFwaVN1cHBvcnRlZEV2ZW50UmVxdWVzdCA9PiAoe1xuICBpZDogY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdC5pZCxcbiAgdXNlcl9ldmVudDogY29yZVVzZXJFdmVudFRvQXBpVXNlckV2ZW50KGNvcmVTdXBwb3J0ZWRFdmVudFJlcXVlc3QudXNlckV2ZW50KSxcbiAgY29udGV4dDogY29yZUNvbnRleHRUb0FwaUNvbnRleHQoY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdC5jb250ZXh0KSxcbn0pO1xuIiwiZXhwb3J0IGNsYXNzIFNlc3Npb25SZXN0YXJ0UmVxdWlyZWQgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCdTZXNzaW9uIHJlc3RhcnQgcmVxdWlyZWQnKTtcbiAgICB0aGlzLm5hbWUgPSAnU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCc7XG4gIH1cbn1cbiIsImV4cG9ydCBjbGFzcyBVbnN1cHBvcnRlZFByb2R1Y3RFeGNlcHRpb24gZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCdVbnN1cHBvcnRlZCBwcm9kdWN0Jyk7XG4gICAgdGhpcy5uYW1lID0gJ1Vuc3VwcG9ydGVkUHJvZHVjdCc7XG4gIH1cbn0iLCJpbXBvcnQgeyBVc2VyRXZlbnRDYXRlZ29yeSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQge1xuICBGb3JtUmVzcG9uc2VBdHRyaWJ1dGVzLFxuICBNZXNzYWdlLFxuICBNZXNzYWdlUm9sZSxcbiAgTWVzc2FnZVR5cGUsXG4gIFVzZXJFdmVudCxcbn0gZnJvbSAnc3JjL2FwcGxpY2F0aW9uL21vZGVscyc7XG5cbmV4cG9ydCBjb25zdCBtZXNzYWdlRnJvbUZvcm1TdWJtaXR0ZWRFdmVudCA9IChcbiAgZXZlbnQ6IFVzZXJFdmVudCxcbiAgZm9ybVJlc3BvbnNlQXR0cmlidXRlczogRm9ybVJlc3BvbnNlQXR0cmlidXRlc1snYXR0cmlidXRlcyddLFxuKTogTWVzc2FnZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChldmVudC5jYXRlZ29yeSAhPT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBmb3JtU3RyaW5nQ29udGVudHMgPSBPYmplY3QuZW50cmllcyhmb3JtUmVzcG9uc2VBdHRyaWJ1dGVzLnNjaGVtYS5wcm9wZXJ0aWVzKVxuICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7dmFsdWUudGl0bGV9OiAke2V2ZW50LmF0dHJpYnV0ZXMuZmlsbGVkU2NoZW1hW2tleV19YClcbiAgICAuam9pbignXFxuJyk7XG5cbiAgcmV0dXJuIHtcbiAgICBpZDogZXZlbnQuZXZlbnRJZCxcbiAgICByb2xlOiBNZXNzYWdlUm9sZS5Vc2VyLFxuICAgIHR5cGU6IE1lc3NhZ2VUeXBlLlF1ZXJ5VHlwZWQsXG4gICAgY3JlYXRlZEF0OiBldmVudC5jcmVhdGVkQXQsXG4gICAgbWV0YWRhdGE6IHtcbiAgICAgIGNvbnRlbnQ6IGZvcm1TdHJpbmdDb250ZW50cyxcbiAgICB9LFxuICB9O1xufTtcbiIsImltcG9ydCBMb2dnZXIgZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9sb2dnaW5nL2xvZ2dlclwiO1xuaW1wb3J0IHtcbiAgQ29uZmlndXJhdGlvbixcbiAgQ3VzdG9tZXJTZXJ2aWNlQXBpLFxuICBEZWZhdWx0QXBpLFxuICBJbmZlcmVuY2VBcGksXG4gIFJlcG9ydFNlc3Npb25SZXF1ZXN0LFxuICBSZXNwb25zZUVycm9yLFxuICBVc2VyRXZlbnRDYXRlZ29yeSxcbiAgVjFHZXRTZXNzaW9uTWVzc2FnZXMyMDBSZXNwb25zZSxcbiAgVjFPcmdDb25maWdHZXRSZXF1ZXN0LFxuICBDb250ZXh0U291cmNlRW51bSxcbiAgVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLFxuICBDdXN0b21lclNlcnZpY2VQcm92aWRlcixcbiAgUmVzcG9uc2VDYXRlZ29yeSxcbiAgRm9ybVR5cGUsXG59IGZyb20gXCJAc3BpZmZ5LWFpL2NvbW1lcmNlLWFwaS1jbGllbnRcIjtcbmltcG9ydCB7IHZhbGlkYXRlU3VnZ2VzdGlvbiB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3ZhbGlkYXRvcnMvdmFsaWRhdGVTdWdnZXN0aW9uXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZVVzZXJFdmVudCB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3ZhbGlkYXRvcnMvdmFsaWRhdGVVc2VyRXZlbnRcIjtcbmltcG9ydCB7XG4gIG1lc3NhZ2VGcm9tUXVlcnlFdmVudCxcbiAgbWVzc2FnZUZyb21SZXNwb25zZSxcbiAgbWVzc2FnZUZyb21TdWdnZXN0aW9uRXZlbnQsXG59IGZyb20gXCJzcmMvYXBwbGljYXRpb24vdXRpbHNcIjtcbmltcG9ydCB7XG4gIE1lc3NhZ2UsXG4gIE5leHRNZXNzYWdlUmVxdWVzdCxcbiAgUmVzcG9uc2UsXG4gIFN1Z2dlc3Rpb24sXG4gIFN1cHBvcnRlZEV2ZW50UmVxdWVzdCxcbiAgVXNlckV2ZW50LFxufSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVsc1wiO1xuaW1wb3J0IHsgbWVzc2FnZVJlcXVlc3RUb0NvbW1lcmNlTWVzc2FnZVJlcXVlc3QgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL3V0aWxzL25leHRNZXNzYWdlUmVxdWVzdFRvQXBpUmVxdWVzdFwiO1xuaW1wb3J0IHsgdmFsaWRhdGVSZXNwb25zZSB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3ZhbGlkYXRvcnMvdmFsaWRhdGVSZXNwb25zZVwiO1xuaW1wb3J0IHsgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdFRvQXBpUmVxdWVzdCB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vdXRpbHMvc3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0XCI7XG5pbXBvcnQgeyBTZXNzaW9uUmVzdGFydFJlcXVpcmVkIH0gZnJvbSBcInNyYy90eXBlcy9leGNlcHRpb25zL3Nlc3Npb25FeGNlcHRpb25zXCI7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZFByb2R1Y3RFeGNlcHRpb24gfSBmcm9tIFwic3JjL3R5cGVzL2V4Y2VwdGlvbnMvdW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgQ2xpZW50RGV0YWlscyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2NsaWVudERldGFpbHNcIjtcbmltcG9ydCB7IGdldEF0b21TdG9yZSB9IGZyb20gXCJzcmMvYXRvbXMvYXRvbVN0b3JlL2F0b21TdG9yZVwiO1xuaW1wb3J0IHsgUHJvZHVjdEV4cGVyaW1lbnQgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9wcm9kdWN0RXhwZXJpbWVudFwiO1xuaW1wb3J0IHsgRmVhdHVyZUdhdGVzIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvZmVhdHVyZUdhdGVzXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZU9yZ0NvbmZpZ1Jlc3VsdHMgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy92YWxpZGF0b3JzL3ZhbGlkYXRlT3JnQ29uZmlnUmVzdWx0c1wiO1xuaW1wb3J0IHsgT3JnQ29uZmlnIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvYXBpL29yZ0NvbmZpZ1Jlc3VsdHNcIjtcbmltcG9ydCB7IFN1cHBvcnRlZEV2ZW50IH0gZnJvbSBcInNyYy9hdG9tcy9hcHAvdmFyaWFudFwiO1xuaW1wb3J0IHsgbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL3V0aWxzL21lc3NhZ2VGcm9tRm9ybVN1Ym1pdHRlZEV2ZW50XCI7XG5pbXBvcnQgdHlwZSB7IENvbnRleHQgfSBmcm9tIFwiQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50L2Rpc3QvbW9kZWxzL0NvbnRleHRcIjtcbmltcG9ydCB7IENvbnRleHRFbnZFbnVtIH0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiOyAvLyBJbXBvcnQgQ29udGV4dEVudkVudW1cbmltcG9ydCB7XG4gIGJhc2VVcmxBdG9tLFxuICByZWFjdEFwcE5hbWVBdG9tLFxuICBjb250ZXh0U291cmNlQXRvbSxcbiAgb3JnU2hvcnROYW1lQXRvbSxcbiAgZW52QXRvbSwgLy8gSW1wb3J0IGVudkF0b21cbn0gZnJvbSBcInNyYy9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5pbXBvcnQgeyB1c2VySWRBdG9tLCBjaGF0SWRBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9hcHBcIjsgLy8gSW1wb3J0IHVzZXJJZEF0b20gYW5kIGNoYXRJZEF0b21cbmltcG9ydCB7IG9yZ0lkQXRvbSwgZmVhdHVyZUZsYWdTZXJ2aWNlQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvb3JnL2dyYXBocWxDb25maWdcIjsgLy8gSW1wb3J0IG5ldyBvcmdJZEF0b20gYW5kIGZlYXR1cmVGbGFnU2VydmljZUF0b21cblxuYXN5bmMgZnVuY3Rpb24gZXJyb3JSZXNwb25zZUJvZHkoZXJyb3I6IFJlc3BvbnNlRXJyb3IpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgZXJyb3IucmVzcG9uc2UuanNvbigpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoZXJyb3JNc2c6IHN0cmluZywgZXJyb3I6IHVua25vd24pIHtcbiAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBSZXNwb25zZUVycm9yKSkge1xuICAgIExvZ2dlci5sb2dJbmZvKGVycm9yTXNnLCBlcnJvcik7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBjb25zdCBlcnJvclJlc3BvbnNlID0gYXdhaXQgZXJyb3JSZXNwb25zZUJvZHkoZXJyb3IpO1xuICBpZiAoXG4gICAgZXJyb3JSZXNwb25zZT8ubWVzc2FnZT8udG9Mb3dlckNhc2UoKSA9PT0gXCJ1bnN1cHBvcnRlZCBwcm9kdWN0XCIgfHwgLy8gZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuIG5ld2VyIHZlcnNpb25zIG9mIHRoZSBBUEkgcmV0dXJuIHN1Yl9jb2RlIGluc3RlYWQgb2YgbWVzc2FnZVxuICAgIGVycm9yUmVzcG9uc2U/LmFwcF9jb2RlPy50b1VwcGVyQ2FzZSgpID09PSBcIlBST0RVQ1RfTk9UX0ZPVU5EXCJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkUHJvZHVjdEV4Y2VwdGlvbigpO1xuICB9IGVsc2UgaWYgKFxuICAgIGVycm9yUmVzcG9uc2U/LmFwcF9jb2RlPy50b1VwcGVyQ2FzZSgpID09PSBcIlJFU1RBUlRfU0VTU0lPTlwiIHx8XG4gICAgZXJyb3JSZXNwb25zZT8uc3ViX2NvZGU/LnRvVXBwZXJDYXNlKCkgPT09IFwiTk9UX0ZPVU5EXCIgLy8gZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuIG5ldyBBUEkgcmVzcG9uc2VzIHdpbGwgY29udGFpbiBcImFwcF9jb2RlXCJcbiAgKSB7XG4gICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICBcIlNlc3Npb24gZG9lcyBub3QgZXhpc3QuIFJlLXN0YXJ0IHNlc3Npb25cIixcbiAgICAgIGVycm9yLFxuICAgICAgZXJyb3IucmVzcG9uc2UsXG4gICAgICBlcnJvclJlc3BvbnNlXG4gICAgKTtcbiAgICB0aHJvdyBuZXcgU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCgpO1xuICB9XG5cbiAgTG9nZ2VyLmxvZ0luZm8oZXJyb3JNc2csIGVycm9yKTtcbiAgdGhyb3cgZXJyb3I7XG59XG5cbmNsYXNzIENvbW1lcmNlQXBpQ2xpZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWZhdWx0QXBpOiBEZWZhdWx0QXBpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY3VzdG9tZXJTZXJ2aWNlQXBpOiBDdXN0b21lclNlcnZpY2VBcGk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpbmZlcmVuY2VBcGk6IEluZmVyZW5jZUFwaTtcblxuICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogQ29tbWVyY2VBcGlDbGllbnQgfCB1bmRlZmluZWQ7XG5cbiAgcHJpdmF0ZSBzdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBwcml2YXRlIHJlc3BvbnNlc0Fib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICBwcml2YXRlIHN0YXRpYyBnZXRJbnN0YW5jZSA9ICgpOiBDb21tZXJjZUFwaUNsaWVudCA9PiB7XG4gICAgaWYgKCFDb21tZXJjZUFwaUNsaWVudC5pbnN0YW5jZSkge1xuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuaW5zdGFuY2UgPSBuZXcgQ29tbWVyY2VBcGlDbGllbnQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gQ29tbWVyY2VBcGlDbGllbnQuaW5zdGFuY2U7XG4gIH07XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihiYXNlUGF0aD86IHN0cmluZykge1xuICAgIGNvbnN0IGF0b21TdG9yZSA9IGdldEF0b21TdG9yZSgpO1xuICAgIGNvbnN0IGJhc2VVcmwgPSBhdG9tU3RvcmUuZ2V0KGJhc2VVcmxBdG9tKTtcbiAgICBjb25zdCBwYXRoID0gYmFzZVBhdGggfHwgYmFzZVVybDtcbiAgICAvLyBBUEkgS2V5IGlzIG5vdyBoYW5kbGVkIGF0IHRoZSBFbnZpdmVDb25maWdQcm92aWRlciBsZXZlbFxuICAgIGNvbnN0IGNvbmZpZzogQ29uZmlndXJhdGlvbiA9IG5ldyBDb25maWd1cmF0aW9uKHtcbiAgICAgIGJhc2VQYXRoOiBwYXRoLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgdGhpcy5kZWZhdWx0QXBpID0gbmV3IERlZmF1bHRBcGkoY29uZmlnKTtcbiAgICB0aGlzLmluZmVyZW5jZUFwaSA9IG5ldyBJbmZlcmVuY2VBcGkoY29uZmlnKTtcbiAgICB0aGlzLmN1c3RvbWVyU2VydmljZUFwaSA9IG5ldyBDdXN0b21lclNlcnZpY2VBcGkoY29uZmlnKTtcbiAgfVxuXG4gIHN0YXRpYyByZXNvbHZlVXJsID0gYXN5bmMgKHVybDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgY29uc3Qgb3JnU2hvcnROYW1lID0gYXRvbVN0b3JlLmdldChvcmdTaG9ydE5hbWVBdG9tKTtcbiAgICBjb25zdCBvcmdJZCA9IGF0b21TdG9yZS5nZXQob3JnSWRBdG9tKTtcbiAgICBjb25zdCB1c2VySWQgPSBhdG9tU3RvcmUuZ2V0KHVzZXJJZEF0b20pO1xuICAgIGNvbnN0IGNoYXRJZCA9IGF0b21TdG9yZS5nZXQoY2hhdElkQXRvbSk7XG4gICAgY29uc3Qgc291cmNlID0gYXRvbVN0b3JlLmdldChjb250ZXh0U291cmNlQXRvbSk7XG4gICAgY29uc3QgZW52ID0gYXRvbVN0b3JlLmdldChlbnZBdG9tKTtcblxuICAgIGNvbnN0IGZlYXR1cmVGbGFnU2VydmljZSA9IGF0b21TdG9yZS5nZXQoZmVhdHVyZUZsYWdTZXJ2aWNlQXRvbSk7XG5cbiAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0ge1xuICAgICAgdXNlcl9pZDogdXNlcklkID8/IFwiXCIsXG4gICAgICBvcmdfaWQ6IG9yZ0lkID8/IFwiXCIsXG4gICAgICBvcmdfc2hvcnRfbmFtZTogb3JnU2hvcnROYW1lID8/IFwiXCIsXG4gICAgICBjaGF0X2lkOiBjaGF0SWQgPz8gXCJcIixcbiAgICAgIHNvdXJjZTogc291cmNlID8/IENvbnRleHRTb3VyY2VFbnVtLkFwcCxcbiAgICAgIGVudjogKGVudiBhcyBDb250ZXh0RW52RW51bSkgPz8gQ29udGV4dEVudkVudW0uRGV2LCAvLyBDYXN0IGVudiB0byBDb250ZXh0RW52RW51bVxuICAgIH07XG5cbiAgICBjb25zdCBmZWF0dXJlR2F0ZXMgPVxuICAgICAgZmVhdHVyZUZsYWdTZXJ2aWNlPy5mZWF0dXJlRmxhZ1NlcnZpY2U/LmdldEZlYXR1cmVGbGFncygpIHx8IHt9O1xuICAgIGNvbnN0IHVybFJlc29sdmluZ1JlcXVlc3QgPSB7XG4gICAgICB1cmwsXG4gICAgICBjb250ZXh0LFxuICAgICAgZmVhdHVyZV9nYXRlczogZmVhdHVyZUdhdGVzLFxuICAgIH07XG5cbiAgICBjb25zdCByYXdSZXNwb25zZSA9XG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MVVybFJlc29sdmluZ1Bvc3RSYXcoe1xuICAgICAgICBVcmxSZXNvbHZpbmdSZXF1ZXN0OiB1cmxSZXNvbHZpbmdSZXF1ZXN0LFxuICAgICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZUJvZHkgPSBhd2FpdCByYXdSZXNwb25zZS5yYXcuanNvbigpO1xuXG4gICAgcmV0dXJuIHJlc3BvbnNlQm9keTtcbiAgfTtcblxuICBzdGF0aWMgcmVwb3J0U2Vzc2lvbiA9IGFzeW5jIChcbiAgICByZXBvcnRSZXF1ZXN0OiBSZXBvcnRTZXNzaW9uUmVxdWVzdFxuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFDaGF0c1JlcG9ydFNlc3Npb25JZFBvc3QoXG4gICAgICB7XG4gICAgICAgIFJlcG9ydFNlc3Npb25SZXF1ZXN0OiByZXBvcnRSZXF1ZXN0LFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgc3RhdGljIGdldE5leHRSZXNwb25zZXMgPSBhc3luYyAoXG4gICAgcGF5bG9hZDogTmV4dE1lc3NhZ2VSZXF1ZXN0XG4gICk6IFByb21pc2U8TWVzc2FnZVtdPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGkudjFOZXh0UmVzcG9uc2VzUG9zdCh7XG4gICAgICAgICAgTmV4dE1lc3NhZ2VSZXF1ZXN0OiBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBtZXNzYWdlcyA9IHJlc3BvbnNlXG4gICAgICAgIC5tYXAoKHJlc3ApID0+IHZhbGlkYXRlUmVzcG9uc2UocmVzcCkpXG4gICAgICAgIC5tYXAoKHJlc3ApID0+IG1lc3NhZ2VGcm9tUmVzcG9uc2UocmVzcCkpO1xuXG4gICAgICByZXR1cm4gbWVzc2FnZXMuZmlsdGVyKChtKTogbSBpcyBNZXNzYWdlID0+IG0gIT0gbnVsbCk7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhcIkZhaWxlZCB0byBnZXQgbmV4dCByZXNwb25zZXNcIiwgZXJyLCB7XG4gICAgICAgIHBheWxvYWRDb250ZXh0OiBwYXlsb2FkPy5jb250ZXh0LFxuICAgICAgICB1c2VyRXZlbnRzOiBwYXlsb2FkPy51c2VyRXZlbnRzLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcIkZhaWxlZCB0byBnZXQgbmV4dCByZXNwb25zZXNcIiwgZXJyKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldE5leHRSZXNwb25zZVN0cmVhbWluZyA9IChcbiAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgKTogQXN5bmNHZW5lcmF0b3I8UmVzcG9uc2UsIHZvaWQsIHVua25vd24+ID0+IHtcbiAgICBhc3luYyBmdW5jdGlvbiogZ2VuZXJhdGUoXG4gICAgICBpbmZlcmVuY2VBcGk6IEluZmVyZW5jZUFwaSxcbiAgICAgIGFib3J0Q29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyXG4gICAgKSB7XG4gICAgICAvLyBtYWtlIHN1cmUgc3RyZWFtaW5nIGlzIGVuYWJsZWRcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgaW5mZXJlbmNlQXBpLnYxTmV4dFJlc3BvbnNlc1Bvc3RSYXcoXG4gICAgICAgICAge1xuICAgICAgICAgICAgTmV4dE1lc3NhZ2VSZXF1ZXN0OiBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgc2lnbmFsOiBhYm9ydENvbnRyb2xsZXIuc2lnbmFsIH1cbiAgICAgICAgKTtcblxuICAgICAgICAvLyBSZWFkIHRoZSByZXNwb25zZSBhcyBhIHN0cmVhbSBvZiBkYXRhXG4gICAgICAgIGlmICghcmVzcG9uc2UucmF3LmJvZHkpIHtcbiAgICAgICAgICBMb2dnZXIubG9nRXJyb3IoXG4gICAgICAgICAgICBcIltzcGlmZnktYWldIE5vIGJvZHkgaW4gdGhlIHN0cmVhbWVkIHJlc3BvbnNlXCIsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJlc3BvbnNlOiByZXNwb25zZS5yYXcsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWFkZXIgPSByZXNwb25zZS5yYXcuYm9keS5nZXRSZWFkZXIoKTtcbiAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihcInV0Zi04XCIpO1xuXG4gICAgICAgIGxldCBwYXJ0aWFsID0gXCJcIjtcbiAgICAgICAgLy8gVE9ETyB0aGlzIGZ1bmN0aW9uIGlzIHJlY3JlYXRlZCBldmVyeSB0aW1lIG5ldyBkYXRhIGNvbWVzIGZyb20gdGhlIHN0cmVhbSAtIGRlZmluZSBpdCBvdXRzaWRlIG9mIHRoZSBnZW5lcmF0b3JcbiAgICAgICAgY29uc3Qgc2FmZVBhcnNlID0gKGxpbmU6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShsaW5lKTsgLy8gUGFyc2UgdGhlIEpTT04gc3RyaW5nXG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBMb2dnZXIubG9nRXJyb3IoXCJbc3BpZmZ5LWFpXSBFcnJvciBwYXJzaW5nIHN0cmVhbWVkIGxpbmVcIiwgZXJyLCB7XG4gICAgICAgICAgICAgIGxpbmUsXG4gICAgICAgICAgICAgIHBhcnRpYWwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHN3YWxsb3cgdGhlIGVycm9yIGFuZCBzZXQgdGhlIHBhcnRpYWwgdG8gb3VyIGN1cnJlbnQgY2h1bmtcbiAgICAgICAgICAgIHBhcnRpYWwgPSBsaW5lO1xuICAgICAgICAgICAgcmV0dXJuIHBhcnRpYWw7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRPRE8gdGhpcyBmdW5jdGlvbiBpcyByZWNyZWF0ZWQgZXZlcnkgdGltZSBuZXcgZGF0YSBjb21lcyBmcm9tIHRoZSBzdHJlYW0gLSBkZWZpbmUgaXQgb3V0c2lkZSBvZiB0aGUgZ2VuZXJhdG9yXG4gICAgICAgIGNvbnN0IHByb2Nlc3NDaHVuayA9IChjaHVuazogc3RyaW5nKTogdW5rbm93bltdID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgcGFydGlhbCB3aXRoIHRoZSBpbmNvbWluZyBjaHVua1xuICAgICAgICAgIGNvbnN0IGxpbmVzID0gYCR7cGFydGlhbH0ke2NodW5rfWAuc3BsaXQoXCJcXG5cIik7XG5cbiAgICAgICAgICBjb25zdCBwYXJzZWRMaW5lcyA9IGxpbmVzXG4gICAgICAgICAgICAubWFwKChsaW5lKSA9PiBsaW5lLnJlcGxhY2UoL15kYXRhOiAvLCBcIlwiKS50cmltKCkpIC8vIFJlbW92ZSB0aGUgXCJkYXRhOiBcIiBwcmVmaXhcbiAgICAgICAgICAgIC5maWx0ZXIoKGxpbmUpID0+IGxpbmUgIT09IFwiXCIgJiYgbGluZSAhPT0gXCJbRE9ORV1cIikgLy8gUmVtb3ZlIGVtcHR5IGxpbmVzIGFuZCBcIltET05FXVwiXG4gICAgICAgICAgICAubWFwKHNhZmVQYXJzZSlcbiAgICAgICAgICAgIC5maWx0ZXIoKHYpID0+IHYpOyAvLyBhbmQgZmlsdGVyIG91dCB0aGUgdW5kZWZpbmVkIHZhbHVlc1xuICAgICAgICAgIHJldHVybiBwYXJzZWRMaW5lcztcbiAgICAgICAgfTtcblxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICAgICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcblxuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBNYXNzYWdlIGFuZCBwYXJzZSB0aGUgY2h1bmsgb2YgZGF0YVxuICAgICAgICAgIGNvbnN0IGNodW5rID0gZGVjb2Rlci5kZWNvZGUodmFsdWUpO1xuICAgICAgICAgIGNvbnN0IHBhcnNlZExpbmVzID0gcHJvY2Vzc0NodW5rKGNodW5rKTtcblxuICAgICAgICAgIGZvciAoY29uc3QgcGFyc2VkTGluZSBvZiBwYXJzZWRMaW5lcykge1xuICAgICAgICAgICAgY29uc3QgdmFsaWRhdGVkUmVzcG9uc2UgPSB2YWxpZGF0ZVJlc3BvbnNlKHBhcnNlZExpbmUpO1xuXG4gICAgICAgICAgICBpZiAodmFsaWRhdGVkUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgeWllbGQgdmFsaWRhdGVkUmVzcG9uc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBMb2dnZXIubG9nRXJyb3IoXG4gICAgICAgICAgXCJbc3BpZmZ5LWFpXSBGYWlsZWQgdG8gZ2V0IG5leHQgc3RyZWFtaW5nIHJlc3BvbnNlc1wiLFxuICAgICAgICAgIGVycm9yLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHBheWxvYWRDb250ZXh0OiBwYXlsb2FkPy5jb250ZXh0LFxuICAgICAgICAgICAgdXNlckV2ZW50czogcGF5bG9hZD8udXNlckV2ZW50cyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFxuICAgICAgICAgIFwiRmFpbGVkIHRvIGdldCBuZXh0IHN0cmVhbWluZyByZXNwb25zZXNcIixcbiAgICAgICAgICBlcnJvclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkucmVzcG9uc2VzQWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5yZXNwb25zZXNBYm9ydENvbnRyb2xsZXIgPVxuICAgICAgbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gICAgcmV0dXJuIGdlbmVyYXRlKFxuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGksXG4gICAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnJlc3BvbnNlc0Fib3J0Q29udHJvbGxlclxuICAgICk7XG4gIH07XG5cbiAgc3RhdGljIGdldE5leHRTdWdnZXN0aW9ucyA9IGFzeW5jIChcbiAgICBwYXlsb2FkOiBOZXh0TWVzc2FnZVJlcXVlc3RcbiAgKTogUHJvbWlzZTxTdWdnZXN0aW9uW10+ID0+IHtcbiAgICB0cnkge1xuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5zdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5zdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlciA9XG4gICAgICAgIG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmluZmVyZW5jZUFwaS52MU5leHRTdWdnZXN0aW9uc1Bvc3QoXG4gICAgICAgICAge1xuICAgICAgICAgICAgTmV4dE1lc3NhZ2VSZXF1ZXN0OiBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNpZ25hbDpcbiAgICAgICAgICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5zdWdnZXN0aW9uc0Fib3J0Q29udHJvbGxlci5zaWduYWwsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICBjb25zdCBzdWdnZXN0aW9ucyA9IHJlc3BvbnNlXG4gICAgICAgIC5tYXAoKHJlc3ApID0+IHZhbGlkYXRlU3VnZ2VzdGlvbihyZXNwKSlcbiAgICAgICAgLmZpbHRlcigoc3VnZ2VzdGlvbik6IHN1Z2dlc3Rpb24gaXMgU3VnZ2VzdGlvbiA9PiBzdWdnZXN0aW9uICE9IG51bGwpO1xuXG4gICAgICByZXR1cm4gc3VnZ2VzdGlvbnM7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIExvZ2dlci5sb2dJbmZvKFwiRmFpbGVkIHRvIGdldCBzdWdnZXN0aW9uc1wiLCBlcnJvciwge1xuICAgICAgICBwYXlsb2FkQ29udGV4dDogcGF5bG9hZD8uY29udGV4dCxcbiAgICAgICAgdXNlckV2ZW50czogcGF5bG9hZD8udXNlckV2ZW50cyxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcIkZhaWxlZCB0byBnZXQgc3VnZ2VzdGlvbnNcIiwgZXJyb3IpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogRmV0Y2hlcyB0aGUgZXhpc3RpbmcgY2hhdCBkYXRhIGZvciBhIGdpdmVuIHNlc3Npb24gYW5kIHRyYW5zZm9ybXMgdGhlbSB0byByZWNvbnN0cnVjdCB0aGUgY2hhdCBoaXN0b3J5LlxuICAgKlxuICAgKiBAcGFyYW0gb3JnSWQgVGhlIG9yZ2FuaXphdGlvbiBJZFxuICAgKiBAcGFyYW0gY2hhdElkIFRoZSBleGlzdGluZyBjaGF0IElkXG4gICAqIEBwYXJhbSB1c2VySWQgVGhlIHVzZXIgSWRcbiAgICpcbiAgICogQHJldHVybnMgQSBsaXN0IG9mIG1lc3NhZ2VzIHRoYXQgd2VyZSBleGNoYW5nZWQgaW4gdGhlIGNoYXQsIHRocm93cyBhbiBlcnJvciBpZiB0aGUgY2hhdCBzZXNzaW9uIGhhcyBleHBpcmVkLlxuICAgKi9cbiAgc3RhdGljIGdldFJlc3BvbnNlcyA9IGFzeW5jIChcbiAgICBvcmdJZDogc3RyaW5nLFxuICAgIGNoYXRJZDogc3RyaW5nLFxuICAgIHVzZXJJZDogc3RyaW5nXG4gICk6IFByb21pc2U8e1xuICAgIHJlc3BvbnNlczogUmVzcG9uc2VbXVtdO1xuICAgIHVzZXJFdmVudHM6IFVzZXJFdmVudFtdO1xuICAgIHN1Z2dlc3Rpb25zOiBTdWdnZXN0aW9uW107XG4gICAgbWVzc2FnZXM6IE1lc3NhZ2VbXVtdO1xuICB9PiA9PiB7XG4gICAgbGV0IGRhdGE6IFYxR2V0U2Vzc2lvbk1lc3NhZ2VzMjAwUmVzcG9uc2UgPSB7XG4gICAgICByZXNwb25zZXM6IFtdLFxuICAgICAgc3VnZ2VzdGlvbnM6IFtdLFxuICAgICAgdXNlcl9ldmVudHM6IFtdLFxuICAgIH07XG4gICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgIG9yZ19pZDogb3JnSWQsXG4gICAgICBjaGF0X2lkOiBjaGF0SWQsXG4gICAgICB1c2VyX2lkOiB1c2VySWQsXG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgZGF0YSA9XG4gICAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuZGVmYXVsdEFwaS52MUdldFNlc3Npb25NZXNzYWdlcyhcbiAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGF3YWl0IHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKFxuICAgICAgICBcIkZhaWxlZCB0byBnZXQgY2hhdCByZXNwb25zZXNcIixcbiAgICAgICAgZXJyb3JcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2VzOiBSZXNwb25zZVtdW10gPSBkYXRhPy5yZXNwb25zZXM/Lm1hcCgodHVybikgPT5cbiAgICAgIHR1cm5cbiAgICAgICAgLm1hcCgocmVzcG9uc2UpID0+IHZhbGlkYXRlUmVzcG9uc2UocmVzcG9uc2UpKVxuICAgICAgICAuZmlsdGVyKChyZXNwb25zZSk6IHJlc3BvbnNlIGlzIFJlc3BvbnNlID0+IHJlc3BvbnNlICE9IG51bGwpXG4gICAgKTtcblxuICAgIGNvbnN0IHN1Z2dlc3Rpb25zOiBTdWdnZXN0aW9uW10gPSBkYXRhPy5zdWdnZXN0aW9uc1xuICAgICAgLm1hcCgoc3VnZ2VzdGlvbikgPT4gdmFsaWRhdGVTdWdnZXN0aW9uKHN1Z2dlc3Rpb24pKVxuICAgICAgLmZpbHRlcigoc3VnZ2VzdGlvbik6IHN1Z2dlc3Rpb24gaXMgU3VnZ2VzdGlvbiA9PiBzdWdnZXN0aW9uICE9IG51bGwpO1xuXG4gICAgY29uc3QgdXNlckV2ZW50czogVXNlckV2ZW50W10gPSBkYXRhPy51c2VyX2V2ZW50c1xuICAgICAgLm1hcCgoZXZlbnQpID0+IHZhbGlkYXRlVXNlckV2ZW50KGV2ZW50KSlcbiAgICAgIC5maWx0ZXIoKGV2ZW50KTogZXZlbnQgaXMgVXNlckV2ZW50ID0+IGV2ZW50ICE9IG51bGwpO1xuXG4gICAgLy8gaWYgYSBmb3JtIGhhcyBhbHJlYWR5IGJlZW4gc3VibWl0dGVkLCBkb24ndCBzaG93IGl0IGluIHRoZSBjaGF0IGhpc3RvcnlcbiAgICBjb25zdCBmb3JtU3VibWl0dGVkVXNlckV2ZW50c0Zvcm1JZHMgPSB1c2VyRXZlbnRzXG4gICAgICAuZmlsdGVyKChldmVudCkgPT4gZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LkZvcm1TdWJtaXR0ZWQpXG4gICAgICAubWFwKChldmVudCkgPT4gZXZlbnQuYXR0cmlidXRlcy5mb3JtUmVzcG9uc2VJZCk7XG5cbiAgICBjb25zdCBhc3Npc3RhbnRNZXNzYWdlczogTWVzc2FnZVtdW10gPSByZXNwb25zZXNcbiAgICAgIC5tYXAoKHR1cm4pID0+XG4gICAgICAgIHR1cm5cbiAgICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgICAgKHJlc3BvbnNlKSA9PlxuICAgICAgICAgICAgICAhKFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LkZvcm0gJiZcbiAgICAgICAgICAgICAgICBmb3JtU3VibWl0dGVkVXNlckV2ZW50c0Zvcm1JZHMuaW5jbHVkZXMocmVzcG9uc2UuaWQpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLm1hcCgocmVzcG9uc2UpID0+IG1lc3NhZ2VGcm9tUmVzcG9uc2UocmVzcG9uc2UpKVxuICAgICAgICAgIC5maWx0ZXIoKG1lc3NhZ2UpOiBtZXNzYWdlIGlzIE1lc3NhZ2UgPT4gbWVzc2FnZSAhPSBudWxsKVxuICAgICAgKVxuICAgICAgLmZpbHRlcigodHVybikgPT4gdHVybi5sZW5ndGggPiAwKTtcblxuICAgIGNvbnN0IHVzZXJNZXNzYWdlczogTWVzc2FnZVtdW10gPSB1c2VyRXZlbnRzXG4gICAgICAubWFwKChldmVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgW1VzZXJFdmVudENhdGVnb3J5LlF1ZXJ5VHlwZWQsIFVzZXJFdmVudENhdGVnb3J5LlNlYXJjaF0uaW5jbHVkZXMoXG4gICAgICAgICAgICBldmVudC5jYXRlZ29yeVxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIFttZXNzYWdlRnJvbVF1ZXJ5RXZlbnQoZXZlbnQpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuU3VnZ2VzdGlvbkNsaWNrZWQpIHtcbiAgICAgICAgICByZXR1cm4gW21lc3NhZ2VGcm9tU3VnZ2VzdGlvbkV2ZW50KGV2ZW50LCBzdWdnZXN0aW9ucyldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5Gb3JtU3VibWl0dGVkKSB7XG4gICAgICAgICAgY29uc3QgZm9ybVJlc3BvbnNlID0gcmVzcG9uc2VzXG4gICAgICAgICAgICAuZmxhdCgpXG4gICAgICAgICAgICAuZmluZChcbiAgICAgICAgICAgICAgKHJlc3BvbnNlKSA9PlxuICAgICAgICAgICAgICAgIHJlc3BvbnNlLmlkID09PSBldmVudC5hdHRyaWJ1dGVzLmZvcm1SZXNwb25zZUlkICYmXG4gICAgICAgICAgICAgICAgZXZlbnQuYXR0cmlidXRlcy5mb3JtVHlwZSAhPT0gRm9ybVR5cGUuRXNjYWxhdGlvblxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChmb3JtUmVzcG9uc2UgJiYgZm9ybVJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LkZvcm0pIHtcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgIG1lc3NhZ2VGcm9tRm9ybVN1Ym1pdHRlZEV2ZW50KGV2ZW50LCBmb3JtUmVzcG9uc2UuYXR0cmlidXRlcyksXG4gICAgICAgICAgICBdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKChtZXNzYWdlKTogbWVzc2FnZSBpcyBNZXNzYWdlW10gPT4gbWVzc2FnZS5sZW5ndGggPiAwKTtcblxuICAgIC8vIFNvcnQgdGhlIG1lc3NhZ2VzIGNocm9ub2xvZ2ljYWxseSB0byByZWNvbnN0cnVjdCB0aGUgY2hhdCBoaXN0b3J5XG4gICAgY29uc3Qgc29ydGVkTWVzc2FnZXMgPSBbLi4uYXNzaXN0YW50TWVzc2FnZXMsIC4uLnVzZXJNZXNzYWdlc10uc29ydChcbiAgICAgIChhLCBiKSA9PlxuICAgICAgICBuZXcgRGF0ZShhWzBdLmNyZWF0ZWRBdCkuZ2V0VGltZSgpIC0gbmV3IERhdGUoYlswXS5jcmVhdGVkQXQpLmdldFRpbWUoKVxuICAgICk7XG5cbiAgICByZXR1cm4geyByZXNwb25zZXMsIHVzZXJFdmVudHMsIHN1Z2dlc3Rpb25zLCBtZXNzYWdlczogc29ydGVkTWVzc2FnZXMgfTtcbiAgfTtcblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHBheWxvYWRcbiAgICogQHJldHVybnNcbiAgICovXG4gIHN0YXRpYyBpc1N1cHBvcnRlZEV2ZW50ID0gYXN5bmMgKFxuICAgIHBheWxvYWQ6IFN1cHBvcnRlZEV2ZW50UmVxdWVzdFxuICApOiBQcm9taXNlPFN1cHBvcnRlZEV2ZW50PiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhd1Jlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGkudjFTdXBwb3J0ZWRFdmVudFBvc3RSYXcoXG4gICAgICAgICAge1xuICAgICAgICAgICAgU3VwcG9ydGVkRXZlbnRSZXF1ZXN0OlxuICAgICAgICAgICAgICBjb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0KHBheWxvYWQpLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgLy8gR2V0IHRoZSBhY3R1YWwgSFRUUCByZXNwb25zZSBKU09OXG4gICAgICBjb25zdCBodHRwUmVzcG9uc2VUZXh0ID0gYXdhaXQgcmF3UmVzcG9uc2UucmF3LnRleHQoKTtcbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZUpzb24gPSBKU09OLnBhcnNlKGh0dHBSZXNwb25zZVRleHQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5odHRwUmVzcG9uc2VKc29uLFxuICAgICAgICBudW1iZXJPZlJldmlld3M6IGh0dHBSZXNwb25zZUpzb24ubnVtX29mX3Jldmlld3MsXG4gICAgICAgIG1lcmNoYW50X3RhZ3M6IGh0dHBSZXNwb25zZUpzb24ubWVyY2hhbnRfdGFncyB8fCBbXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gZ2V0IHJlc3BvbnNlIGZvciB2MVN1cHBvcnRlZEV2ZW50UG9zdFwiLCB7XG4gICAgICAgIGVycixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VwcG9ydGVkOiBmYWxzZSxcbiAgICAgICAgcmVhZHk6IGZhbHNlLFxuICAgICAgICBjYXRlZ29yeTogdW5kZWZpbmVkLFxuICAgICAgICBjb2xsZWN0aW9uczogW10sXG4gICAgICAgIG51bWJlck9mUmV2aWV3czogdW5kZWZpbmVkLFxuICAgICAgICB0b3BfY2F0ZWdvcnk6IHVuZGVmaW5lZCxcbiAgICAgICAgbWVyY2hhbnRfdGFnczogW10sXG4gICAgICB9O1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgaWRlbnRpZnlVc2VyID0gYXN5bmMgKFxuICAgIHNwaWZmeVVzZXJJZDogc3RyaW5nLFxuICAgIG1lcmNoYW50VXNlcklkOiBzdHJpbmcsXG4gICAgdWFEZXRhaWxzOiBDbGllbnREZXRhaWxzXG4gICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFBbmFseXRpY3NJZGVudGlmeVBvc3Qoe1xuICAgICAgICBBbmFseXRpY3NJZGVudGlmeVJlcXVlc3Q6IHtcbiAgICAgICAgICB1c2VyX2lkOiBzcGlmZnlVc2VySWQsXG4gICAgICAgICAgb3NfbmFtZTogdWFEZXRhaWxzLm9zLFxuICAgICAgICAgIG9zX3ZlcnNpb246IHVhRGV0YWlscy5vc1ZlcnNpb24sXG4gICAgICAgICAgcGxhdGZvcm06IHVhRGV0YWlscy5vcyxcbiAgICAgICAgICBkZXZpY2VfaWQ6IHVhRGV0YWlscy5kZXZpY2VNb2RlbCxcbiAgICAgICAgICBkZXZpY2VfYnJhbmQ6IHVhRGV0YWlscy5kZXZpY2VCcmFuZCxcbiAgICAgICAgICBkZXZpY2VfbWFudWZhY3R1cmVyOiB1YURldGFpbHMuZGV2aWNlTWFudWZhY3R1cmVyLFxuICAgICAgICAgIGRldmljZV9tb2RlbDogdWFEZXRhaWxzLmRldmljZU1vZGVsLFxuICAgICAgICAgIHVzZXJfcHJvcGVydGllczoge1xuICAgICAgICAgICAgY2RwX3VzZXJfaWQ6IG1lcmNoYW50VXNlcklkLFxuICAgICAgICAgICAgYnJvd3NlcjogdWFEZXRhaWxzLmJyb3dzZXIsXG4gICAgICAgICAgICBicm93c2VyX3ZlcnNpb246IHVhRGV0YWlscy5icm93c2VyVmVyc2lvbixcbiAgICAgICAgICAgIHVzZXJfYWdlbnQ6IHVhRGV0YWlscy51c2VyQWdlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiRmFpbGVkIHRvIGlkZW50aWZ5IHVzZXJcIiwgZXJyKTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbWFwQ29udGV4dFNvdXJjZVRvVjFPcmdDb25maWdHZXRTb3VyY2UgPSAoXG4gICAgc291cmNlOiBDb250ZXh0U291cmNlRW51bSB8IHVuZGVmaW5lZFxuICApOiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0gfCB1bmRlZmluZWQgPT4ge1xuICAgIGlmIChzb3VyY2UgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBzd2l0Y2ggKHNvdXJjZSkge1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5Gb3JrOlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLkZvcms7XG4gICAgICBjYXNlIENvbnRleHRTb3VyY2VFbnVtLlBsYXlncm91bmQ6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uUGxheWdyb3VuZDtcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uQXBwOlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLkFwcDtcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uVGVzdDpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5UZXN0O1xuICAgICAgZGVmYXVsdDoge1xuICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCBpZiBuZXcgdmFsdWVzIGFyZSBhZGRlZCB0byBDb250ZXh0U291cmNlRW51bSwgd2UgY2F0Y2ggaXRcbiAgICAgICAgY29uc3QgZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHNvdXJjZTtcbiAgICAgICAgcmV0dXJuIGV4aGF1c3RpdmVDaGVjaztcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldE9yZ0NvbmZpZyA9IGFzeW5jIChcbiAgICB1c2VyX2lkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxPcmdDb25maWcgfCB1bmRlZmluZWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgICBjb25zdCByZWFjdEFwcE5hbWUgPSBhdG9tU3RvcmUuZ2V0KHJlYWN0QXBwTmFtZUF0b20pO1xuICAgICAgY29uc3QgY29udGV4dFNvdXJjZSA9IGF0b21TdG9yZS5nZXQoY29udGV4dFNvdXJjZUF0b20pO1xuICAgICAgY29uc3QgZmVhdHVyZUZsYWdTZXJ2aWNlID0gYXRvbVN0b3JlLmdldChmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tKTsgLy8gR2V0IGZlYXR1cmVGbGFnU2VydmljZVxuICAgICAgY29uc3QgcmVxdWVzdDogVjFPcmdDb25maWdHZXRSZXF1ZXN0ID0ge1xuICAgICAgICBuYW1lc3BhY2U6IHJlYWN0QXBwTmFtZSxcbiAgICAgICAgdXNlcl9pZCxcbiAgICAgICAgc291cmNlOiB0aGlzLm1hcENvbnRleHRTb3VyY2VUb1YxT3JnQ29uZmlnR2V0U291cmNlKGNvbnRleHRTb3VyY2UpLFxuICAgICAgICBpbmNsdWRlX2V4cGVyaW1lbnRzOiBPYmplY3QudmFsdWVzKFByb2R1Y3RFeHBlcmltZW50KSxcbiAgICAgICAgaW5jbHVkZV9mZWF0dXJlX2dhdGVzOiBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmZlYXR1cmVGbGFnU2VydmljZT8uZ2V0RmVhdHVyZUZsYWdzKCkgfHwge31cbiAgICAgICAgKVxuICAgICAgICAgIC5maWx0ZXIoKFssIGlzRW5hYmxlZF0pID0+IGlzRW5hYmxlZClcbiAgICAgICAgICAubWFwKChbZmVhdHVyZUdhdGVOYW1lXSkgPT4gZmVhdHVyZUdhdGVOYW1lKSwgLy8gVXNlIGZlYXR1cmVGbGFnU2VydmljZVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxT3JnQ29uZmlnR2V0KFxuICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgKTtcblxuICAgICAgcmV0dXJuIHZhbGlkYXRlT3JnQ29uZmlnUmVzdWx0cyhyZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoYEZhaWxlZCB0byBnZXQgb3JnIGNvbmZpZ2AsIGVyciwgeyBlcnIgfSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgYWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uID0gYXN5bmMgKFxuICAgIHNwaWZmeVVzZXJJZDogc3RyaW5nLFxuICAgIGVtYWlsOiBzdHJpbmcsXG4gICAgY3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXI6IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyXG4gICkgPT4ge1xuICAgIExvZ2dlci5sb2dJbmZvKFxuICAgICAgYGFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvbiAtIHVzZXJfaWQ9JHtzcGlmZnlVc2VySWR9IGVtYWlsPSR7ZW1haWx9IGN1c3RvbWVyX3NlcnZpY2VfcHJvdmlkZXI9JHtjdXN0b21lclNlcnZpY2VQcm92aWRlcn1gXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5jdXN0b21lclNlcnZpY2VBcGkudjFDdXN0c2VydmljZUFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvblBvc3QoXG4gICAgICAgIHtcbiAgICAgICAgICBBZGROb3RlVG9MYXRlc3RDb252ZXJzYXRpb25SZXF1ZXN0OiB7XG4gICAgICAgICAgICBzcGlmZnlfdXNlcl9pZDogc3BpZmZ5VXNlcklkLFxuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgICBjdXN0b21lcl9zZXJ2aWNlX3Byb3ZpZGVyOiBjdXN0b21lclNlcnZpY2VQcm92aWRlcixcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiRmFpbGVkIHRvIGFkZCBub3RlIHRvIGxhdGVzdCBjb252ZXJzYXRpb25cIiwgeyBlcnIgfSk7XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBnZXRDdXN0b21lclNlcnZpY2VBcGkgPSAoKSA9PlxuICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuY3VzdG9tZXJTZXJ2aWNlQXBpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDb21tZXJjZUFwaUNsaWVudDtcbiIsImltcG9ydCBSZWFjdCwge1xuICBjcmVhdGVDb250ZXh0LFxuICB1c2VDYWxsYmFjayxcbiAgdXNlQ29udGV4dCxcbiAgdXNlTWVtbyxcbiAgdXNlU3RhdGUsXG4gIHVzZUVmZmVjdCxcbn0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgVUFQYXJzZXIgZnJvbSBcInVhLXBhcnNlci1qc1wiO1xuaW1wb3J0IExvZ2dlciBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5pbXBvcnQgQ29tbWVyY2VBcGlDbGllbnQgZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9jb21tZXJjZS1hcGlcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tIFwidXVpZFwiO1xuaW1wb3J0IHsgQ2xpZW50RGV0YWlscyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL2NsaWVudERldGFpbHNcIjtcbmltcG9ydCB7IHVzZUxvY2FsU3RvcmFnZSB9IGZyb20gXCJzcmMvY29udGV4dHMvbG9jYWxTdG9yYWdlQ29udGV4dFwiO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb24gZnJvbSB0aGUgb3JpZ2luYWwgc2VydmljZVxuY29uc3QgZ2V0VXNlckFnZW50RGV0YWlscyA9ICgpOiBDbGllbnREZXRhaWxzID0+IHtcbiAgY29uc3QgdWFQYXJzZXIgPSBuZXcgVUFQYXJzZXIoKTtcbiAgY29uc3QgcmVzdWx0ID0gdWFQYXJzZXIuZ2V0UmVzdWx0KCk7XG5cbiAgcmV0dXJuIHtcbiAgICBvczogcmVzdWx0Py5vcz8ubmFtZSxcbiAgICBvc1ZlcnNpb246IHJlc3VsdD8ub3M/LnZlcnNpb24sXG4gICAgZGV2aWNlQnJhbmQ6IHJlc3VsdD8uZGV2aWNlPy52ZW5kb3IsXG4gICAgZGV2aWNlTWFudWZhY3R1cmVyOiByZXN1bHQ/LmRldmljZT8udmVuZG9yLFxuICAgIGRldmljZU1vZGVsOiByZXN1bHQ/LmRldmljZT8ubW9kZWwsXG4gICAgYnJvd3NlcjogcmVzdWx0Py5icm93c2VyPy5uYW1lLFxuICAgIGJyb3dzZXJWZXJzaW9uOiByZXN1bHQ/LmJyb3dzZXI/LnZlcnNpb24sXG4gICAgdXNlckFnZW50OiByZXN1bHQ/LnVhLFxuICB9O1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBVc2VySWRlbnRpdHlDb250ZXh0VHlwZSB7XG4gIGlkZW50aWZ5VXNlcjogKCkgPT4gUHJvbWlzZTx2b2lkPjtcbiAgZ2V0VXNlcklkT3JEZWZhdWx0OiAoKSA9PiBzdHJpbmc7XG4gIGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZTogKCkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZTogKCkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2U6ICh1c2VySWQ6IHN0cmluZykgPT4gc3RyaW5nO1xuICBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlOiAodXNlcklkOiBzdHJpbmcpID0+IHN0cmluZztcbiAgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlOiAoKSA9PiB2b2lkO1xuICBpc1JlYWR5OiBib29sZWFuO1xufVxuXG5jb25zdCBVc2VySWRlbnRpdHlDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxVc2VySWRlbnRpdHlDb250ZXh0VHlwZSB8IHVuZGVmaW5lZD4oXG4gIHVuZGVmaW5lZFxuKTtcblxuZXhwb3J0IGNvbnN0IFVzZXJJZGVudGl0eVByb3ZpZGVyOiBSZWFjdC5GQzx7IGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGUgfT4gPSAoe1xuICBjaGlsZHJlbixcbn0pID0+IHtcbiAgY29uc3Qge1xuICAgIGdldEl0ZW0sXG4gICAgc2V0SXRlbSxcbiAgICBpc0F2YWlsYWJsZTogbG9jYWxTdG9yYWdlSXNSZWFkeSxcbiAgfSA9IHVzZUxvY2FsU3RvcmFnZSgpO1xuXG4gIGNvbnN0IFtpc1JlYWR5LCBzZXRJc1JlYWR5XSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIC8vIEFzc3VtaW5nIENvbW1lcmNlQXBpQ2xpZW50IGFuZCBvdGhlciBkZXBlbmRlbmNpZXMgYXJlIHJlYWR5IGlmIGxvY2FsU3RvcmFnZSBpcy5cbiAgICAvLyBJbiBhIG1vcmUgY29tcGxleCBzY2VuYXJpbywgeW91IG1pZ2h0IGhhdmUgbW9yZSBjaGVja3MgaGVyZS5cbiAgICBzZXRJc1JlYWR5KGxvY2FsU3RvcmFnZUlzUmVhZHkpO1xuICB9LCBbbG9jYWxTdG9yYWdlSXNSZWFkeV0pO1xuXG4gIGNvbnN0IFVTRVJfSURfT1ZFUlJJREVfS0VZID0gXCJ2MS1zcGlmZnktdXNlci1pZC1vdmVycmlkZVwiO1xuICBjb25zdCBVU0VSX0lEX0RFRkFVTFRfS0VZID0gXCJ2MS1zcGlmZnktdXNlci1pZC1kZWZhdWx0XCI7XG5cbiAgY29uc3QgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soKCk6XG4gICAgfCBzdHJpbmdcbiAgICB8IHVuZGVmaW5lZCA9PiB7XG4gICAgcmV0dXJuIGdldEl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVkpID8/IHVuZGVmaW5lZDtcbiAgfSwgW2dldEl0ZW1dKTtcblxuICBjb25zdCBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKCgpOlxuICAgIHwgc3RyaW5nXG4gICAgfCB1bmRlZmluZWQgPT4ge1xuICAgIHJldHVybiBnZXRJdGVtKFVTRVJfSURfREVGQVVMVF9LRVkpID8/IHVuZGVmaW5lZDtcbiAgfSwgW2dldEl0ZW1dKTtcblxuICBjb25zdCBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICAgIGBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UgLSBTZXR0aW5nIHVzZXJfaWQ9JHt1c2VySWR9YFxuICAgICAgKTtcbiAgICAgIHNldEl0ZW0oVVNFUl9JRF9ERUZBVUxUX0tFWSwgdXNlcklkKTtcbiAgICAgIC8vIHdpbmRvdy5kaXNwYXRjaEV2ZW50IGlzIGhhbmRsZWQgYnkgdXNlTG9jYWxTdG9yYWdlIG5vd1xuICAgICAgcmV0dXJuIHVzZXJJZDtcbiAgICB9LFxuICAgIFtzZXRJdGVtLCBVU0VSX0lEX0RFRkFVTFRfS0VZXVxuICApO1xuXG4gIGNvbnN0IHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oXG4gICAgICAgIGBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlIC0gU2V0dGluZyB1c2VyX2lkPSR7dXNlcklkfWBcbiAgICAgICk7XG4gICAgICBzZXRJdGVtKFVTRVJfSURfT1ZFUlJJREVfS0VZLCB1c2VySWQpO1xuICAgICAgLy8gd2luZG93LmRpc3BhdGNoRXZlbnQgaXMgaGFuZGxlZCBieSB1c2VMb2NhbFN0b3JhZ2Ugbm93XG4gICAgICByZXR1cm4gdXNlcklkO1xuICAgIH0sXG4gICAgW3NldEl0ZW0sIFVTRVJfSURfT1ZFUlJJREVfS0VZXVxuICApO1xuXG4gIGNvbnN0IGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBMb2dnZXIubG9nSW5mbyhgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlIC0gQ2xlYXJpbmcgdXNlcl9pZGApO1xuICAgIC8vIExvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0TG9jYWxTdG9yYWdlKCk/LnJlbW92ZUl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVkpO1xuICAgIC8vIHdpbmRvdy5kaXNwYXRjaEV2ZW50IGlzIGhhbmRsZWQgYnkgdXNlTG9jYWxTdG9yYWdlIG5vd1xuICAgIHNldEl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVksIFwiXCIpOyAvLyBTZXQgdG8gZW1wdHkgc3RyaW5nIHRvIGNsZWFyXG4gIH0sIFtzZXRJdGVtLCBVU0VSX0lEX09WRVJSSURFX0tFWV0pO1xuXG4gIGNvbnN0IGdldFVzZXJJZE9yRGVmYXVsdCA9IHVzZUNhbGxiYWNrKCgpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IHVzZXJJZE92ZXJyaWRlID0gZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlKCk7XG4gICAgaWYgKHVzZXJJZE92ZXJyaWRlKSB7XG4gICAgICByZXR1cm4gdXNlcklkT3ZlcnJpZGU7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdFVzZXJJZCA9IGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlKCk7XG4gICAgaWYgKGRlZmF1bHRVc2VySWQpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0VXNlcklkO1xuICAgIH1cblxuICAgIHJldHVybiBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UoYHNwaWZmeS11c2VyLWlkLSR7dXVpZCgpfWApO1xuICB9LCBbXG4gICAgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlLFxuICAgIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlLFxuICAgIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSxcbiAgXSk7XG5cbiAgY29uc3QgaWRlbnRpZnlVc2VyID0gdXNlQ2FsbGJhY2soYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmICghaXNSZWFkeSkge1xuICAgICAgTG9nZ2VyLmxvZ1dhcm4oXG4gICAgICAgIFwiW1VzZXJJZGVudGl0eUNvbnRleHRdIENvbnRleHQgbm90IHJlYWR5LCBza2lwcGluZyBpZGVudGlmeVVzZXJcIixcbiAgICAgICAgdW5kZWZpbmVkXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBUZW1wb3JhcmlseSBjb21tZW50ZWQgb3V0IHVudGlsIFdpbmRvd0RhdGFMYXllclNlcnZpY2UgaXMgcmVzb2x2ZWRcbiAgICAgIC8vIGNvbnN0IGNkcFVzZXJJZCA9IFdpbmRvd0RhdGFMYXllclNlcnZpY2UuZ2V0R29vZ2xlQW5hbHl0aWNzQ2xpZW50SWQoKTtcbiAgICAgIGNvbnN0IGNkcFVzZXJJZCA9IFwiVU5LTk9XTl9DRFBfVVNFUl9JRFwiOyAvLyBQbGFjZWhvbGRlclxuICAgICAgY29uc3QgdXNlcklkID0gZ2V0VXNlcklkT3JEZWZhdWx0KCk7XG4gICAgICBjb25zdCB1c2VyQWdlbnREZXRhaWxzID0gZ2V0VXNlckFnZW50RGV0YWlscygpO1xuXG4gICAgICBpZiAoIWNkcFVzZXJJZCkge1xuICAgICAgICBMb2dnZXIubG9nV2FybihcbiAgICAgICAgICBcIltzcGlmZnktYWldIE5vIEdBIENsaWVudCBJRCBmb3VuZCwgc2tpcHBpbmcgaWRlbnRpZnlVc2VyXCIsXG4gICAgICAgICAgdW5kZWZpbmVkXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuaWRlbnRpZnlVc2VyKHVzZXJJZCwgY2RwVXNlcklkLCB1c2VyQWdlbnREZXRhaWxzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiW3NwaWZmeS1haV0gRXJyb3IgaWRlbnRpZnlpbmcgdXNlclwiLCBlcnJvcik7XG4gICAgfVxuICB9LCBbaXNSZWFkeSwgZ2V0VXNlcklkT3JEZWZhdWx0XSk7XG5cbiAgY29uc3QgdmFsdWUgPSB1c2VNZW1vKFxuICAgICgpID0+ICh7XG4gICAgICBpZGVudGlmeVVzZXIsXG4gICAgICBnZXRVc2VySWRPckRlZmF1bHQsXG4gICAgICBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgICBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSxcbiAgICAgIHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBpc1JlYWR5LFxuICAgIH0pLFxuICAgIFtcbiAgICAgIGlkZW50aWZ5VXNlcixcbiAgICAgIGdldFVzZXJJZE9yRGVmYXVsdCxcbiAgICAgIGdldFVzZXJJZE92ZXJyaWRlRnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkRGVmYXVsdEluTG9jYWxTdG9yYWdlLFxuICAgICAgc2V0VXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGNsZWFyVXNlcklkT3ZlcnJpZGVJbkxvY2FsU3RvcmFnZSxcbiAgICAgIGlzUmVhZHksXG4gICAgXVxuICApO1xuXG4gIHJldHVybiAoXG4gICAgPFVzZXJJZGVudGl0eUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3ZhbHVlfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L1VzZXJJZGVudGl0eUNvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG5leHBvcnQgY29uc3QgdXNlVXNlcklkZW50aXR5ID0gKCkgPT4ge1xuICBjb25zdCBjb250ZXh0ID0gdXNlQ29udGV4dChVc2VySWRlbnRpdHlDb250ZXh0KTtcbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJ1c2VVc2VySWRlbnRpdHkgbXVzdCBiZSB1c2VkIHdpdGhpbiBhIFVzZXJJZGVudGl0eVByb3ZpZGVyXCJcbiAgICApO1xuICB9XG4gIHJldHVybiBjb250ZXh0O1xufTtcbiIsImltcG9ydCB7IGF0b21XaXRoU3RvcmFnZSB9IGZyb20gJ2pvdGFpL3V0aWxzJztcbmltcG9ydCB7IGF0b20gfSBmcm9tICdqb3RhaSc7XG5pbXBvcnQgeyBTdXBwb3J0ZWRFdmVudFJlc3BvbnNlLCBQYWdlVmlzaXRDYXRlZ29yeSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQge1xuICBQYWdlVmlzaXRWYXJpYW50SW5mbyxcbiAgUERQVmFyaWFudEluZm8sXG4gIFBMUFZhcmlhbnRJbmZvLFxuICBWYXJpYW50SW5mbyxcbiAgVmFyaWFudFR5cGVFbnVtLFxufSBmcm9tICdzcmMvYXBwbGljYXRpb24vbW9kZWxzJztcbmltcG9ydCB7IHNlc3Npb25TdG9yYWdlVXRpbCB9IGZyb20gJ3NyYy9hdG9tcy9hdG9tU3RvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN1cHBvcnRlZEV2ZW50XG4gIGV4dGVuZHMgUGljazxcbiAgICBTdXBwb3J0ZWRFdmVudFJlc3BvbnNlLFxuICAgICdzdXBwb3J0ZWQnIHwgJ3JlYWR5JyB8ICdjYXRlZ29yeScgfCAnY29sbGVjdGlvbnMnIHwgJ3RvcF9jYXRlZ29yeSdcbiAgPiB7XG4gIG51bWJlck9mUmV2aWV3czogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICBtZXJjaGFudF90YWdzPzogc3RyaW5nW107XG59XG5cbmludGVyZmFjZSBQRFBBdHRyaWJ1dGVzIHtcbiAgcHJvZHVjdF9pZD86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFBMUEF0dHJpYnV0ZXMge1xuICBhdHRyaWJ1dGVzPzoge1xuICAgIGlkPzogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVybFJlc29sdmluZ1BEUENvbmZpZyB7XG4gIHBkcF9hdHRyaWJ1dGVzOiBQRFBBdHRyaWJ1dGVzO1xuICBudW1iZXJfb2ZfcmV2aWV3cz86IG51bWJlcjtcbiAgY29sbGVjdGlvbnM/OiBzdHJpbmdbXTtcbiAgbWVyY2hhbnRfdGFncz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFVybFJlc29sdmluZ1BMUENvbmZpZyB7XG4gIHBscF9hdHRyaWJ1dGVzOiBQTFBBdHRyaWJ1dGVzO1xuICB0b3BfY2F0ZWdvcnk/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBVcmxSZXNvbHZpbmdHZW5lcmljQ29uZmlnIHtcbiAgZGV0YWlscz86IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgUGFnZVZhcmlhbnRDaGVja0NvbmZpZyA9IHtcbiAgY2hlY2tfdHlwZTogc3RyaW5nO1xuICBmZWF0dXJlX2dhdGU/OiBzdHJpbmc7XG4gIGV4dHJhY3Rvcj86IHtcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgbWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+O1xuICAgIHZhbHVlPzogc3RyaW5nO1xuICB9O1xuICBwcm9kdWN0X2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcHJvZHVjdF9pZHM/OiBzdHJpbmdbXTtcbiAgcGxwX2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcGxwX2lkcz86IHN0cmluZ1tdO1xuICBjb2xsZWN0aW9ucz86IHN0cmluZ1tdO1xuICBxdWVyeV9wYXJhbT86IHN0cmluZztcbiAgY2F0ZWdvcnk/OiBzdHJpbmc7XG4gIHRvcF9jYXRlZ29yeT86IHN0cmluZ1tdO1xuICByZXZpZXdfbWluaW11bT86IG51bWJlcjtcbiAgbWVyY2hhbnRfdGFncz86IHN0cmluZ1tdO1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2VuZFdpZGdldE1vdW50aW5nQ29uZmlnID0ge1xuICBtb3VudGluZ19jb25maWdfaWQ6IHN0cmluZztcbiAgd2lkZ2V0X2NvbmZpZ19pZD86IHN0cmluZztcbiAgbW91bnRpbmdfcG9pbnRfd2lkZ2V0cz86IEFycmF5PHtcbiAgICBjaGVja3M6IFBhZ2VWYXJpYW50Q2hlY2tDb25maWdbXTtcbiAgICB3aWRnZXRfY29uZmlnX2lkOiBzdHJpbmc7XG4gIH0+O1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2VuZFBhZ2VWYXJpYW50Q29uZmlnID0ge1xuICB2YXJpYW50X2lkOiBzdHJpbmc7XG4gIHZhcmlhbnRfdHlwZTogc3RyaW5nO1xuICB2YXJpYW50X2NoZWNrczogUGFnZVZhcmlhbnRDaGVja0NvbmZpZ1tdO1xuICB3aWRnZXRfbW91bnRpbmc6IEJhY2tlbmRXaWRnZXRNb3VudGluZ0NvbmZpZ1tdO1xuICBwbHBfaWRfZXh0cmFjdG9yPzogc3RyaW5nO1xuICBwcm9kdWN0X2lkX2V4dHJhY3Rvcj86IHN0cmluZztcbiAgcGFyZW50X3Byb2R1Y3RfaWRfZXh0cmFjdG9yPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBVcmxSZXNvbHZlclJlc3BvbnNlIHtcbiAgdmFyaWFudF90eXBlOiBzdHJpbmc7XG4gIHNwZWNpZmljX2RldGFpbHM6IFVybFJlc29sdmluZ1BEUENvbmZpZyB8IFVybFJlc29sdmluZ1BMUENvbmZpZyB8IFVybFJlc29sdmluZ0dlbmVyaWNDb25maWc7XG4gIHJlYWR5OiBib29sZWFuO1xuICB1c2VyX2V2ZW50Pzoge1xuICAgIGV2ZW50X2lkPzogc3RyaW5nO1xuICAgIGF0dHJpYnV0ZXM/OiBQRFBBdHRyaWJ1dGVzIHwgUExQQXR0cmlidXRlcztcbiAgICBjYXRlZ29yeT86IHN0cmluZztcbiAgICBjcmVhdGVkX2F0Pzogc3RyaW5nO1xuICB9O1xuICBwYWdlX3ZhcmlhbnQ/OiBCYWNrZW5kUGFnZVZhcmlhbnRDb25maWc7XG59XG5cbi8vIFVzZSBhIG1hcCBmb3IgcGVyLVVSTCBjYWNoZVxuZXhwb3J0IHR5cGUgVXJsUmVzb2x2ZXJDYWNoZSA9IFJlY29yZDxzdHJpbmcsIFVybFJlc29sdmVyUmVzcG9uc2UgfCB1bmRlZmluZWQ+O1xuXG5jb25zdCBpbnRlcm5hbFN0b3JhZ2VVcmxSZXNvbHZlckF0b20gPSBhdG9tV2l0aFN0b3JhZ2U8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgJ3NwaWZmeS11cmwtcmVzb2x2ZXInLFxuICB1bmRlZmluZWQsXG4gIHNlc3Npb25TdG9yYWdlVXRpbCxcbiAge1xuICAgIGdldE9uSW5pdDogdHJ1ZSxcbiAgfSxcbik7XG5cbmV4cG9ydCBjb25zdCB1cmxSZXNvbHZlckF0b20gPSBhdG9tKFxuICAoZ2V0KTogVXJsUmVzb2x2ZXJDYWNoZSA9PiB7XG4gICAgY29uc3QgbWF5YmVVcmxSZXNvbHZlciA9IGdldChpbnRlcm5hbFN0b3JhZ2VVcmxSZXNvbHZlckF0b20pO1xuICAgIGlmIChtYXliZVVybFJlc29sdmVyID09IG51bGwpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgcmV0dXJuIEpTT04ucGFyc2UobWF5YmVVcmxSZXNvbHZlcik7XG4gIH0sXG4gIChnZXQsIHNldCwgdmFsdWU6IHsgdXJsOiBzdHJpbmc7IHJlc3BvbnNlOiBVcmxSZXNvbHZlclJlc3BvbnNlIHwgdW5kZWZpbmVkIH0pID0+IHtcbiAgICAvLyBHZXQgY3VycmVudCBjYWNoZSBmcm9tIHN0b3JhZ2VcbiAgICBjb25zdCBjdXJyZW50Q2FjaGUgPSBnZXQodXJsUmVzb2x2ZXJBdG9tKTtcbiAgICBjb25zdCBuZXdDYWNoZSA9IHsgLi4uY3VycmVudENhY2hlLCBbdmFsdWUudXJsXTogdmFsdWUucmVzcG9uc2UgfTtcblxuICAgIHNldChpbnRlcm5hbFN0b3JhZ2VVcmxSZXNvbHZlckF0b20sIEpTT04uc3RyaW5naWZ5KG5ld0NhY2hlKSk7XG4gIH0sXG4pO1xuXG5jb25zdCBpbnRlcm5hbFN0b3JhZ2VTdXBwb3J0ZWRFdmVudEF0b20gPSBhdG9tV2l0aFN0b3JhZ2U8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgJ3NwaWZmeS1zdXBwb3J0ZWQtZXZlbnQnLFxuICB1bmRlZmluZWQsXG4gIHNlc3Npb25TdG9yYWdlVXRpbCxcbiAge1xuICAgIGdldE9uSW5pdDogdHJ1ZSxcbiAgfSxcbik7XG5jb25zdCBpbnRlcm5hbFN1cHBvcnRlZEV2ZW50QXRvbSA9IGF0b208U3VwcG9ydGVkRXZlbnQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbmV4cG9ydCBjb25zdCBzdXBwb3J0ZWRFdmVudEF0b20gPSBhdG9tKFxuICAoZ2V0KTogU3VwcG9ydGVkRXZlbnQgfCB1bmRlZmluZWQgPT4ge1xuICAgIGNvbnN0IG1heWJlU3VwcG9ydGVkRXZlbnQgPSBnZXQoaW50ZXJuYWxTdG9yYWdlU3VwcG9ydGVkRXZlbnRBdG9tKTtcbiAgICBpZiAobWF5YmVTdXBwb3J0ZWRFdmVudCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8vIFRPRE8gdGhpcyBpcyBhbiB1bnZhbGlkYXRlZCBwYXJzZS4gSXQgbWF5IGJlIGJldHRlciB0byBpbXBsZW1lbnQgYSBjdXN0b20gc3RvcmFnZSB1dGlsXG4gICAgLy8gYW5kIHBlcmZvcm0gdGhlIG9iamVjdCB2YWxpZGF0aW9uIG9uIFwiZ2V0XCIgdGhlcmUuXG4gICAgcmV0dXJuIEpTT04ucGFyc2UobWF5YmVTdXBwb3J0ZWRFdmVudCk7XG4gIH0sXG4gIChfLCBzZXQsIHZhbHVlOiBTdXBwb3J0ZWRFdmVudCB8IHVuZGVmaW5lZCkgPT4ge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICBzZXQoaW50ZXJuYWxTdG9yYWdlU3VwcG9ydGVkRXZlbnRBdG9tLCB1bmRlZmluZWQpO1xuICAgICAgc2V0KGludGVybmFsU3VwcG9ydGVkRXZlbnRBdG9tLCB1bmRlZmluZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNldChpbnRlcm5hbFN1cHBvcnRlZEV2ZW50QXRvbSwgdmFsdWUpO1xuICAgIHNldChpbnRlcm5hbFN0b3JhZ2VTdXBwb3J0ZWRFdmVudEF0b20sIEpTT04uc3RyaW5naWZ5KHZhbHVlKSk7XG4gIH0sXG4pO1xuXG5jb25zdCBpbnRlcm5hbFZhcmlhbnRJZEF0b20gPSBhdG9tPHN0cmluZz4oKTtcbmNvbnN0IGludGVybmFsUHJvZHVjdElkQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxQYXJlbnRQcm9kdWN0SWRBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFByb2R1Y3RVcmxBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFBscElkQXRvbSA9IGF0b208c3RyaW5nPigpO1xuY29uc3QgaW50ZXJuYWxVcmxBdG9tID0gYXRvbTxzdHJpbmc+KCk7XG5jb25zdCBpbnRlcm5hbFBhZ2VWaXNpdENhdGVnb3J5QXRvbSA9IGF0b208UGFnZVZpc2l0Q2F0ZWdvcnk+KCk7XG5jb25zdCBpbnRlcm5hbFZhcmlhbnRBdG9tID0gYXRvbTwncGRwJyB8ICdwbHAnIHwgJ3NlYXJjaCcgfCAncGFnZV92aXNpdCc+KCdwZHAnKTtcblxuZXhwb3J0IGNvbnN0IHZhcmlhbnRJZEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFZhcmlhbnRJZEF0b20pKTtcbmV4cG9ydCBjb25zdCBwcm9kdWN0SWRBdG9tID0gYXRvbSgoZ2V0KSA9PiBnZXQoaW50ZXJuYWxQcm9kdWN0SWRBdG9tKSk7XG5leHBvcnQgY29uc3QgcGFyZW50UHJvZHVjdElkQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUGFyZW50UHJvZHVjdElkQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHByb2R1Y3RVcmxBdG9tID0gYXRvbSgoZ2V0KSA9PiBnZXQoaW50ZXJuYWxQcm9kdWN0VXJsQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHBscElkQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUGxwSWRBdG9tKSk7XG5leHBvcnQgY29uc3QgdXJsQXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsVXJsQXRvbSkpO1xuZXhwb3J0IGNvbnN0IHBhZ2VWaXNpdENhdGVnb3J5QXRvbSA9IGF0b20oKGdldCkgPT4gZ2V0KGludGVybmFsUGFnZVZpc2l0Q2F0ZWdvcnlBdG9tKSk7XG5leHBvcnQgY29uc3QgdmFyaWFudEF0b20gPSBhdG9tKChnZXQpID0+IGdldChpbnRlcm5hbFZhcmlhbnRBdG9tKSk7XG5leHBvcnQgY29uc3QgaGFzUGFyc2VkVmFyaWFudEluZm9BdG9tID0gYXRvbShmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCB2YXJpYW50SW5mb0F0b20gPSBhdG9tKFxuICAoZ2V0KTogVmFyaWFudEluZm8gPT4ge1xuICAgIGNvbnN0IHZhcmlhbnQgPSBnZXQodmFyaWFudEF0b20pO1xuICAgIGlmICh2YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGRwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YXJpYW50SWQ6IGdldCh2YXJpYW50SWRBdG9tKSxcbiAgICAgICAgdmFyaWFudCxcbiAgICAgICAgcHJvZHVjdElkOiBnZXQocHJvZHVjdElkQXRvbSksXG4gICAgICAgIHBhcmVudFByb2R1Y3RJZDogZ2V0KHBhcmVudFByb2R1Y3RJZEF0b20pLFxuICAgICAgICB1cmw6IGdldCh1cmxBdG9tKSxcbiAgICAgIH0gYXMgUERQVmFyaWFudEluZm87XG4gICAgfVxuICAgIGlmICh2YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGxwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YXJpYW50SWQ6IGdldCh2YXJpYW50SWRBdG9tKSxcbiAgICAgICAgdmFyaWFudCxcbiAgICAgICAgcGxwSWQ6IGdldChwbHBJZEF0b20pLFxuICAgICAgICB1cmw6IGdldCh1cmxBdG9tKSxcbiAgICAgIH0gYXMgUExQVmFyaWFudEluZm87XG4gICAgfVxuICAgIGlmICh2YXJpYW50ID09PSBWYXJpYW50VHlwZUVudW0uUGFnZVZpc2l0KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YXJpYW50SWQ6IGdldCh2YXJpYW50SWRBdG9tKSxcbiAgICAgICAgdmFyaWFudCxcbiAgICAgICAgdXJsOiBnZXQodXJsQXRvbSksXG4gICAgICAgIHBhZ2VWaXNpdENhdGVnb3J5OiBnZXQocGFnZVZpc2l0Q2F0ZWdvcnlBdG9tKSxcbiAgICAgIH0gYXMgUGFnZVZpc2l0VmFyaWFudEluZm87XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB2YXJpYW50SW5mbyBkZXRhaWxzJyk7XG4gIH0sXG4gIChfLCBzZXQsIG5ld1ZhcmlhbnQ6IFZhcmlhbnRJbmZvKSA9PiB7XG4gICAgc2V0KGludGVybmFsVmFyaWFudEF0b20sIG5ld1ZhcmlhbnQudmFyaWFudCk7XG4gICAgc2V0KGludGVybmFsVmFyaWFudElkQXRvbSwgbmV3VmFyaWFudC52YXJpYW50SWQpO1xuICAgIGlmIChuZXdWYXJpYW50LnZhcmlhbnQgPT09IFZhcmlhbnRUeXBlRW51bS5QZHApIHtcbiAgICAgIHNldChpbnRlcm5hbFByb2R1Y3RJZEF0b20sIG5ld1ZhcmlhbnQucHJvZHVjdElkKTtcbiAgICAgIHNldChpbnRlcm5hbFBhcmVudFByb2R1Y3RJZEF0b20sIG5ld1ZhcmlhbnQucGFyZW50UHJvZHVjdElkKTtcbiAgICAgIHNldChpbnRlcm5hbFVybEF0b20sIG5ld1ZhcmlhbnQudXJsKTtcbiAgICB9XG4gICAgaWYgKG5ld1ZhcmlhbnQudmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBscCkge1xuICAgICAgc2V0KGludGVybmFsUGxwSWRBdG9tLCBuZXdWYXJpYW50LnBscElkKTtcbiAgICAgIHNldChpbnRlcm5hbFVybEF0b20sIG5ld1ZhcmlhbnQudXJsKTtcbiAgICB9XG4gICAgaWYgKG5ld1ZhcmlhbnQudmFyaWFudCA9PT0gVmFyaWFudFR5cGVFbnVtLlBhZ2VWaXNpdCkge1xuICAgICAgc2V0KGludGVybmFsVXJsQXRvbSwgbmV3VmFyaWFudC51cmwpO1xuICAgICAgc2V0KGludGVybmFsUGFnZVZpc2l0Q2F0ZWdvcnlBdG9tLCBuZXdWYXJpYW50LnBhZ2VWaXNpdENhdGVnb3J5KTtcbiAgICB9XG4gIH0sXG4pO1xuIiwiaW1wb3J0IHtcbiAgQ29udGV4dEVudkVudW0sXG4gIENvbnRleHRTb3VyY2VFbnVtLFxufSBmcm9tIFwiQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50XCI7XG5pbXBvcnQgeyBhdG9tIH0gZnJvbSBcImpvdGFpXCI7XG5pbXBvcnQgeyBhdG9tV2l0aFN0b3JhZ2UgfSBmcm9tIFwiam90YWkvdXRpbHNcIjtcbmltcG9ydCB7IFZhcmlhbnRJbmZvIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHNcIjtcbmltcG9ydCB7IFVzZXJJZGVudGl0eUNvbnRleHRUeXBlLCB1c2VVc2VySWRlbnRpdHkgfSBmcm9tIFwic3JjL2NvbnRleHRzL3VzZXJJZGVudGl0eUNvbnRleHQvdXNlcklkZW50aXR5Q29udGV4dFwiO1xuaW1wb3J0IHsgdmFyaWFudEluZm9BdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9hcHAvdmFyaWFudFwiO1xuaW1wb3J0IHsgdjQgYXMgdXVpZCB9IGZyb20gXCJ1dWlkXCI7XG5pbXBvcnQgeyBjb250ZXh0U291cmNlQXRvbSB9IGZyb20gXCIuLi9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwRGV0YWlscyB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIG9yZ1Nob3J0TmFtZTogc3RyaW5nO1xuICBjaGF0SWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIHNvdXJjZTogQ29udGV4dFNvdXJjZUVudW07XG4gIGVudjogQ29udGV4dEVudkVudW07XG4gIHZhcmlhbnRJbmZvOiBWYXJpYW50SW5mbztcbn1cblxuZXhwb3J0IHsgdmFyaWFudEluZm9BdG9tIH0gZnJvbSBcIi4vdmFyaWFudFwiO1xuXG5jb25zdCBpbnRlcm5hbFVzZXJJZEF0b20gPSBhdG9tPHN0cmluZyB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuZXhwb3J0IGNvbnN0IHVzZXJJZEF0b20gPSBhdG9tKFxuICAoZ2V0KSA9PiB7XG4gICAgY29uc3QgbWF5YmVVc2VySWQgPSBnZXQoaW50ZXJuYWxVc2VySWRBdG9tKTtcblxuICAgIGlmIChtYXliZVVzZXJJZCkge1xuICAgICAgcmV0dXJuIG1heWJlVXNlcklkO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZ2V0VXNlcklkT3JEZWZhdWx0IH0gPSB1c2VVc2VySWRlbnRpdHkoKTtcbiAgICByZXR1cm4gZ2V0VXNlcklkT3JEZWZhdWx0KCk7XG4gIH0sXG4gIChfLCBzZXQsIHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpID0+IHtcbiAgICBzZXQoaW50ZXJuYWxVc2VySWRBdG9tLCB2YWx1ZSk7XG4gIH1cbik7XG5cbmV4cG9ydCBjb25zdCB1c2VySWRlbnRpdHlBdG9tID0gYXRvbTxVc2VySWRlbnRpdHlDb250ZXh0VHlwZSB8IHVuZGVmaW5lZD4oXG4gIHVuZGVmaW5lZFxuKTtcblxuZXhwb3J0IGNvbnN0IGFwcFNvdXJjZUF0b20gPSBhdG9tPENvbnRleHRTb3VyY2VFbnVtPihcbiAgKGdldCk6IENvbnRleHRTb3VyY2VFbnVtID0+IGdldChjb250ZXh0U291cmNlQXRvbSkgPz8gQ29udGV4dFNvdXJjZUVudW0uQXBwXG4pO1xuZXhwb3J0IGNvbnN0IGNoYXRJZEF0b20gPSBhdG9tV2l0aFN0b3JhZ2U8c3RyaW5nPihcbiAgXCJ2MS1zcGlmZnktY2hhdC1zZXNzaW9uLWlkXCIsXG4gIHV1aWQoKSxcbiAgdW5kZWZpbmVkLFxuICB7XG4gICAgZ2V0T25Jbml0OiB0cnVlLFxuICB9XG4pO1xuIiwiaW1wb3J0IFJlYWN0LCB7XG4gIGNyZWF0ZUNvbnRleHQsXG4gIHVzZUNvbnRleHQsXG4gIHVzZUNhbGxiYWNrLFxuICB1c2VNZW1vLFxuICB1c2VFZmZlY3QsXG59IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlQXRvbVZhbHVlIH0gZnJvbSBcImpvdGFpXCI7XG5pbXBvcnQgeyBjcmVhdGVJbnN0YW5jZSB9IGZyb20gXCJAYW1wbGl0dWRlL2FuYWx5dGljcy1icm93c2VyXCI7XG5pbXBvcnQgeyBGZWF0dXJlR2F0ZXMgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9mZWF0dXJlR2F0ZXNcIjtcbmltcG9ydCB7IE9yZ1Nob3J0TmFtZSB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzXCI7XG5pbXBvcnQgeyBFdmVudHNEaXNwYXRjaGVyLCBTcGlmZnlFdmVudCB9IGZyb20gXCJzcmMvZXZlbnRzXCI7XG5pbXBvcnQge1xuICBhbXBsaXR1ZGVBcGlLZXlBdG9tLFxuICBjb250ZXh0U291cmNlQXRvbSxcbiAgZGF0YVJlc2lkZW5jeUF0b20sXG4gIGlkZW50aWZ5aW5nUHJlZml4QXRvbSxcbn0gZnJvbSBcInNyYy9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5pbXBvcnQge1xuICBMb2NhbFN0b3JhZ2VLZXlzLFxuICB1c2VMb2NhbFN0b3JhZ2UsXG59IGZyb20gXCJzcmMvY29udGV4dHMvbG9jYWxTdG9yYWdlQ29udGV4dFwiO1xuaW1wb3J0IHsgb3JnQW5hbHl0aWNzR29vZ2xlQW5hbHl0aWNzQ29uZmlnQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvb3JnL29yZ0FuYWx5dGljc0NvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlcklkQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvYXBwXCI7XG5pbXBvcnQgeyBlbnZBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5pbXBvcnQgTG9nZ2VyIGZyb20gXCJzcmMvYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXJcIjtcbmltcG9ydCB0eXBlIHtcbiAgQnJvd3NlckNsaWVudCxcbiAgRW5yaWNobWVudFBsdWdpbixcbiAgRXZlbnQsXG4gIFNlcnZlclpvbmVUeXBlLFxufSBmcm9tIFwiQGFtcGxpdHVkZS9hbmFseXRpY3MtdHlwZXNcIjtcbmltcG9ydCB7IHVzZUVudml2ZUNvbmZpZyB9IGZyb20gXCJzcmMvY29udGV4dHMvZW52aXZlQ29uZmlnQ29udGV4dC9lbnZpdmVDb25maWdDb250ZXh0XCI7XG5pbXBvcnQge1xuICB1c2VGZWF0dXJlRmxhZ1NlcnZpY2UsXG59IGZyb20gXCJzcmMvY29udGV4dHMvZmVhdHVyZUZsYWdTZXJ2aWNlQ29udGV4dC9mZWF0dXJlRmxhZ1NlcnZpY2VDb250ZXh0XCI7XG5pbXBvcnQgeyB1c2VVc2VySWRlbnRpdHkgfSBmcm9tIFwic3JjL2NvbnRleHRzL3VzZXJJZGVudGl0eUNvbnRleHQvdXNlcklkZW50aXR5Q29udGV4dFwiO1xuXG5leHBvcnQgZW51bSBTcGlmZnlNZXRyaWNzRXZlbnROYW1lIHtcbiAgQnVuZGxlTG9hZGVkID0gXCJCdW5kbGUgTG9hZGVkXCIsXG4gIENoYXRMaXZlQWdlbnRCdG5DbGljayA9IFwiQ2hhdCBMaXZlIEFnZW50IEJ0biBDbGlja1wiLFxuICBDaGF0RmxvYXRpbmdCdXR0b25WaXNpYmxlID0gXCJDaGF0IEZsb2F0aW5nIEJ1dHRvbiBWaXNpYmxlXCIsXG4gIENoYXRDb21wb25lbnRWaXNpYmxlID0gXCJDaGF0IENvbXBvbmVudCBWaXNpYmxlXCIsXG4gIENoYXRDb21wb25lbnRFeHBhbmRlZCA9IFwiQ2hhdCBDb21wb25lbnQgRXhwYW5kZWRcIixcbiAgQ2hhdENvbXBvbmVudENvbGxhcHNlZCA9IFwiQ2hhdCBDb21wb25lbnQgQ29sbGFwc2VkXCIsXG4gIENoYXRVc2VyTWVzc2FnZUlucHV0ID0gXCJDaGF0IFVzZXIgTWVzc2FnZSBJbnB1dFwiLFxuICBDaGF0U3VnZ2VzdGlvbkNsaWNrZWQgPSBcIkNoYXQgU3VnZ2VzdGlvbiBDbGlja2VkXCIsXG4gIENoYXRBc3Npc3RhbnRSZXNwb25zZSA9IFwiQ2hhdCBBc3Npc3RhbnQgUmVzcG9uc2VcIixcbiAgUHJvZHVjdENhcmRDbGlja2VkID0gXCJQcm9kdWN0IENhcmQgQ2xpY2tlZFwiLFxuICBQcm9kdWN0UmV2aWV3Q2FyZENsaWNrZWQgPSBcIlByb2R1Y3QgUmV2aWV3IENhcmQgQ2xpY2tlZFwiLFxuICBBZGRUb0NhcnRDbGlja2VkID0gXCJBZGQgdG8gQ2FydCBDbGlja2VkXCIsXG4gIFByb21wdENhcmRDbGlja2VkID0gXCJQcm9tcHQgQ2FyZCBDbGlja2VkXCIsXG4gIFN1cHBvcnRlZEV2ZW50ID0gXCJTdXBwb3J0ZWQgRXZlbnRcIixcbiAgU2VhcmNoQmFja1RvUmVzcG9uc2VDbGlja2VkID0gXCJTZWFyY2ggQmFjayB0byBSZXNwb25zZSBDbGlja2VkXCIsXG4gIFBlcmZvcm1hbmNlTWV0cmljcyA9IFwiUGVyZm9ybWFuY2UgTWV0cmljc1wiLFxuICBTZWFyY2hCYXJDbGlja2VkID0gXCJTZWFyY2ggQmFyIENsaWNrZWRcIixcbiAgT3JkZXJMb29rdXBTdGFydGVkID0gXCJPcmRlciBMb29rdXAgU3RhcnRlZFwiLFxuICBPcmRlckxvb2t1cEZvcm1TdWJtaXR0ZWQgPSBcIk9yZGVyIExvb2t1cCBGb3JtIFN1Ym1pdHRlZFwiLFxuICBTZWFyY2hDb21wb25lbnRWaXNpYmxlID0gXCJTZWFyY2ggQ29tcG9uZW50IFZpc2libGVcIixcbiAgU2VhcmNoWmVyb1N0YXRlU3VnZ2VzdGlvbkNsaWNrZWQgPSBcIlNlYXJjaCBaZXJvIFN0YXRlIFN1Z2dlc3Rpb24gQ2xpY2tlZFwiLCAvLyBUaGlzIGlzIHRoZSBzY3JvbGxpbmcgbGlzdCBvZiBzdWdnZXN0aW9uIGJ1dHRvbnMgaW4gZ2xvYmFsIHNlYXJjaFxuICBTZWFyY2hJbnB1dFN0YXJ0ZWQgPSBcIlNlYXJjaCBJbnB1dCBTdGFydGVkXCIsXG4gIFNlYXJjaFF1ZXJ5U3VibWl0dGVkID0gXCJTZWFyY2ggUXVlcnkgU3VibWl0dGVkXCIsXG4gIC8vIFNlYXJjaEF1dG9jb21wbGV0ZVZpZXdlZCA9ICdTZWFyY2ggQXV0b2NvbXBsZXRlIFZpZXdlZCcsIC8vIFRPRE86IGFkZCB0aGlzIHdoZW4gYXV0b2NvbXBsZXRlIGlzIGFkZGVkXG4gIC8vIFNlYXJjaEF1dG9jb21wbGV0ZUNsaWNrZWQgPSAnU2VhcmNoIEF1dG9jb21wbGV0ZSBDbGlja2VkJywgLy8gVE9ETzogYWRkIHRoaXMgd2hlbiBhdXRvY29tcGxldGUgaXMgYWRkZWRcbiAgU2VhcmNoUmVzdWx0c1ZpZXdlZCA9IFwiU2VhcmNoIFJlc3VsdHMgVmlld2VkXCIsXG4gIFNlYXJjaFRpbWVUb0ZpcnN0Q2xpY2sgPSBcIlNlYXJjaCBUaW1lIHRvIEZpcnN0IENsaWNrXCIsXG4gIFNlYXJjaFplcm9SZXN1bHRzUmF0ZSA9IFwiU2VhcmNoIFplcm8gUmVzdWx0cyBSYXRlXCIsXG4gIFNlYXJjaEZpbHRlckNsaWNrZWQgPSBcIlNlYXJjaCBGaWx0ZXIgQ2xpY2tlZFwiLFxuICBTZWFyY2hTb3J0Q2xpY2tlZCA9IFwiU2VhcmNoIFNvcnQgQ2xpY2tlZFwiLFxufVxuXG5pbnRlcmZhY2UgVHJhY2tFdmVudFBhcmFtcyB7XG4gIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZTtcbiAgZXZlbnRQcm9wcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBldmVudEdyb3Vwcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzPzogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIEFtcGxpdHVkZUNvbnRleHRUeXBlIHtcbiAgdHJhY2tFdmVudDogKHBhcmFtczogVHJhY2tFdmVudFBhcmFtcykgPT4gUHJvbWlzZTx2b2lkPjtcbiAgaXNSZWFkeTogYm9vbGVhbjtcbiAgc2V0U3VwcGxlbWVudGFsRGVmYXVsdFByb3BzOiAocHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB2b2lkO1xufVxuXG5jb25zdCBBbXBsaXR1ZGVDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxBbXBsaXR1ZGVDb250ZXh0VHlwZSB8IG51bGw+KG51bGwpO1xuXG5leHBvcnQgY29uc3QgQW1wbGl0dWRlUHJvdmlkZXI6IFJlYWN0LkZDPHsgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZSB9PiA9ICh7XG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCB1c2VySWQgPSB1c2VBdG9tVmFsdWUodXNlcklkQXRvbSk7XG4gIGNvbnN0IGFtcGxpdHVkZUFwaUtleSA9IHVzZUF0b21WYWx1ZShhbXBsaXR1ZGVBcGlLZXlBdG9tKTtcbiAgY29uc3QgZGF0YVJlc2lkZW5jeSA9IHVzZUF0b21WYWx1ZShkYXRhUmVzaWRlbmN5QXRvbSk7XG4gIGNvbnN0IG9yZ0dhQ29uZmlnID0gdXNlQXRvbVZhbHVlKG9yZ0FuYWx5dGljc0dvb2dsZUFuYWx5dGljc0NvbmZpZ0F0b20pO1xuICBjb25zdCBlbnYgPSB1c2VBdG9tVmFsdWUoZW52QXRvbSk7XG4gIGNvbnN0IGNvbnRleHRTb3VyY2UgPSB1c2VBdG9tVmFsdWUoY29udGV4dFNvdXJjZUF0b20pO1xuICBjb25zdCBpZGVudGlmeWluZ1ByZWZpeCA9IHVzZUF0b21WYWx1ZShpZGVudGlmeWluZ1ByZWZpeEF0b20pO1xuICBjb25zdCB7IGdldEl0ZW0gfSA9IHVzZUxvY2FsU3RvcmFnZSgpO1xuICBjb25zdCB7XG4gICAgcHVibGljS2V5LFxuICAgIGZlYXR1cmVPdmVycmlkZXMsXG4gICAgdmFyaWFudFVybE92ZXJyaWRlLFxuICAgIHZhcmlhbnRJbmZvT3ZlcnJpZGUsXG4gICAgc2hvdyxcbiAgICBvcmdTaG9ydE5hbWUsXG4gICAgZmVhdHVyZUdhdGVzLFxuICB9ID0gdXNlRW52aXZlQ29uZmlnKCk7XG5cbiAgY29uc3QgeyBmZWF0dXJlRmxhZ1NlcnZpY2UgfSA9IHVzZUZlYXR1cmVGbGFnU2VydmljZSgpO1xuXG4gIGNvbnN0IFthbXBsaXR1ZGVDbGllbnQsIHNldEFtcGxpdHVkZUNsaWVudF0gPSBSZWFjdC51c2VTdGF0ZTxcbiAgICBCcm93c2VyQ2xpZW50IHwgdW5kZWZpbmVkXG4gID4odW5kZWZpbmVkKTtcbiAgY29uc3QgW2ludGVybmFsRXZlbnRUcmFja2luZ0VucmljaG1lbnQsIHNldEludGVybmFsRXZlbnRUcmFja2luZ0VucmljaG1lbnRdID1cbiAgICBSZWFjdC51c2VTdGF0ZTxFbnJpY2htZW50UGx1Z2luIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBjb25zdCBbc3VwcGxlbWVudGFsRGVmYXVsdFByb3BzLCBzZXRTdXBwbGVtZW50YWxEZWZhdWx0UHJvcHNdID1cbiAgICBSZWFjdC51c2VTdGF0ZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oe30pO1xuXG4gIGNvbnN0IGlzUmVhZHkgPSBCb29sZWFuKFxuICAgIHVzZXJJZCAmJiBmZWF0dXJlRmxhZ1NlcnZpY2UgJiYgYW1wbGl0dWRlQXBpS2V5ICYmIHVzZXJJZFxuICApO1xuXG4gIGNvbnN0IGdldERlZmF1bHRUcmFja2luZ1Byb3BzID0gdXNlQ2FsbGJhY2soKCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+IHtcbiAgICBjb25zdCBnYXRlc1Byb3BzID0gZmVhdHVyZUdhdGVzXG4gICAgICA/IGZlYXR1cmVHYXRlcy5yZWR1Y2U8UmVjb3JkPHN0cmluZywgYm9vbGVhbj4+KChhY2MsIGN1cnIpID0+IHtcbiAgICAgICAgICBpZiAoY3Vyci5uYW1lICYmIGN1cnIudmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4uYWNjLCBbYGZlYXR1cmVfZ2F0ZS4ke2N1cnIubmFtZX1gXTogY3Vyci52YWx1ZSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCB7fSlcbiAgICAgIDoge307XG4gICAgY29uc3QgZXhwZXJpbWVudFByb3BzID0ge307IC8vIE5vIGRpcmVjdCBlcXVpdmFsZW50IGZvciBleHBlcmltZW50cyBpbiBFbnZpdmVDb25maWcgeWV0XG5cbiAgICBjb25zdCBvcmdMZXZlbEFtcGxpdHVkZVRyYWNraW5nUHJvcHMgPSB7XG4gICAgICAuLi5nYXRlc1Byb3BzLFxuICAgICAgLi4uZXhwZXJpbWVudFByb3BzLFxuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ub3JnTGV2ZWxBbXBsaXR1ZGVUcmFja2luZ1Byb3BzLFxuICAgICAgLi4uc3VwcGxlbWVudGFsRGVmYXVsdFByb3BzLFxuICAgICAgLy8gVE9ETzogb3JnX2lkIGlzIG5vdCBkaXJlY3RseSBhdmFpbGFibGUgaW4gRW52aXZlQ29uZmlnLiBOZWVkIHRvIGZpbmQgYSBuZXcgc291cmNlIG9yIGRlcml2ZSBpdC5cbiAgICAgIC8vIG9yZ19pZDogb3JnQ29uZmlnPy5vcmc/Lm9yZz8uaWQsXG4gICAgICBhcHBfaWQ6IFwiY29tbWVyY2UtY2hhdC1yZWFjdC1jb21wb25lbnRcIixcbiAgICAgIGNoYXRfaWQ6IGdldEl0ZW0oTG9jYWxTdG9yYWdlS2V5cy5DaGF0SWQpLFxuICAgICAgZW52OiBlbnYgfHwgXCJ1bmtub3duXCIsXG4gICAgICBhcHBfc291cmNlOiBjb250ZXh0U291cmNlLFxuICAgICAgXCJvcmcuc2hvcnRfbmFtZVwiOiBvcmdTaG9ydE5hbWUsXG4gICAgICBcInVzZXIuaWRcIjogdXNlcklkLFxuICAgICAgXCJjZHAudXNlcl9pZFwiOiBudWxsLFxuICAgICAgXCJjZHAucHJvdmlkZXJcIjogbnVsbCxcbiAgICAgIFwiZXZlbnQuc291cmNlXCI6IFwid2ViLWJyb3dzZXJcIixcbiAgICAgIFwiZXZlbnQudHlwZVwiOiBcInVzZXItYWN0aXZpdHlcIixcbiAgICAgIFwiZXZlbnQuaWRcIjogbnVsbCxcbiAgICAgIFwiZXZlbnQuY2hhbm5lbFwiOiBcIndlYlwiLFxuICAgICAgXCJldmVudC50aW1lc3RhbXBcIjogbnVsbCxcbiAgICB9O1xuICB9LCBbXG4gICAgZmVhdHVyZUdhdGVzLFxuICAgIHN1cHBsZW1lbnRhbERlZmF1bHRQcm9wcyxcbiAgICBlbnYsXG4gICAgY29udGV4dFNvdXJjZSxcbiAgICBvcmdTaG9ydE5hbWUsXG4gICAgdXNlcklkLFxuICBdKTtcblxuICBjb25zdCBldmVudFByb3BzVG9QcmVmaXhlZEV2ZW50UHJvcHMgPSB1c2VDYWxsYmFjayhcbiAgICAoXG4gICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUsXG4gICAgICBldmVudFByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICAgICk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+IHtcbiAgICAgIGNvbnN0IHByZWZpeCA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1xccysvZywgXCJfXCIpO1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGV2ZW50UHJvcHMpLnJlZHVjZSgoYWNjLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgYWNjW2Ake3ByZWZpeH0uJHtrZXl9YF0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICB9LFxuICAgIFtdXG4gICk7XG5cbiAgY29uc3QgYW1wbGl0dWRlU2Vzc2lvblJlcGxheUluaXQgPSB1c2VDYWxsYmFjaygoKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgaXNFbmFibGVkID0gQm9vbGVhbihcbiAgICAgIG9yZ1Nob3J0TmFtZSA9PT0gT3JnU2hvcnROYW1lLlVuaXF1ZVZpbnRhZ2UgJiZcbiAgICAgICAgZmVhdHVyZUZsYWdTZXJ2aWNlPy5pc0NsaWVudFNlc3Npb25FbmFibGVkKCkgJiZcbiAgICAgICAgZmVhdHVyZUZsYWdTZXJ2aWNlPy5pc0ZlYXR1cmVHYXRlRW5hYmxlZChcbiAgICAgICAgICBGZWF0dXJlR2F0ZXMuSXNOZXdGZWF0dXJlRW5hYmxlZFxuICAgICAgICApXG4gICAgKTtcbiAgICBjb25zdCBzYW1wbGVSYXRlID0gMTtcblxuICAgIHRyeSB7XG4gICAgICBMb2dnZXIubG9nRGVidWcoXG4gICAgICAgIGBbc3BpZmZ5LWFpXSBhbXBsaXR1ZGUgc2Vzc2lvbi1yZXBsYXkgaW5pdGlhbGl6aW5nIGlzRW5hYmxlZD0ke2lzRW5hYmxlZH0gc2FtcGxlUmF0ZT0ke3NhbXBsZVJhdGV9YFxuICAgICAgKTtcblxuICAgICAgaWYgKCFpc0VuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuIGlzRW5hYmxlZDtcbiAgICAgIH1cblxuICAgICAgLy8gYW1wbGl0dWRlSW5zdGFuY2UuYWRkKHNlc3Npb25SZXBsYXlQbHVnaW4oeyBzYW1wbGVSYXRlIH0pKTtcblxuICAgICAgcmV0dXJuIGlzRW5hYmxlZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoXG4gICAgICAgIFwiW3NwaWZmeS1haV0gRXJyb3IgaW5pdGlhbGl6aW5nIGFtcGxpdHVkZSBzZXNzaW9uLXJlcGxheVwiLFxuICAgICAgICBlXG4gICAgICApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSwgW29yZ1Nob3J0TmFtZSwgZmVhdHVyZUZsYWdTZXJ2aWNlXSk7XG5cbiAgY29uc3QgZ2V0RXZlbnRUcmFja2luZ0VucmljaG1lbnQgPSB1c2VDYWxsYmFjaygoKTogRW5yaWNobWVudFBsdWdpbiA9PiB7XG4gICAgaWYgKGludGVybmFsRXZlbnRUcmFja2luZ0VucmljaG1lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGludGVybmFsRXZlbnRUcmFja2luZ0VucmljaG1lbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgZW5yaWNobWVudDogRW5yaWNobWVudFBsdWdpbiA9IHtcbiAgICAgIG5hbWU6IFwicGFnZS12aWV3LXRyYWNraW5nLWVucmljaG1lbnRcIixcbiAgICAgIHR5cGU6IFwiZW5yaWNobWVudFwiLFxuICAgICAgc2V0dXA6IGFzeW5jICgpID0+IHVuZGVmaW5lZCxcbiAgICAgIGV4ZWN1dGU6IGFzeW5jIChldmVudDogRXZlbnQpOiBQcm9taXNlPEV2ZW50PiA9PiB7XG4gICAgICAgIGxldCBlbnJpY2hlZEV2ZW50OiBFdmVudDtcblxuICAgICAgICBjb25zdCBldmVudHNUb0VucmljaCA9IFtcbiAgICAgICAgICBcIltBbXBsaXR1ZGVdIFBhZ2UgVmlld2VkXCIsXG4gICAgICAgICAgYFtTcGlmZnldICR7U3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5CdW5kbGVMb2FkZWR9YCxcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAoZXZlbnRzVG9FbnJpY2guaW5jbHVkZXMoZXZlbnQuZXZlbnRfdHlwZSkpIHtcbiAgICAgICAgICBjb25zdCBnbG9iYWxQcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICAgICAgICBpZiAocHVibGljS2V5KSB7XG4gICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzW1wiZ2xvYmFsUHJvcGVydGllcy5wdWJsaWNLZXlcIl0gPSBwdWJsaWNLZXk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmZWF0dXJlT3ZlcnJpZGVzKSB7XG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhmZWF0dXJlT3ZlcnJpZGVzKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgICAgZ2xvYmFsUHJvcGVydGllc1tgZ2xvYmFsUHJvcGVydGllcy5mZWF0dXJlT3ZlcnJpZGVzLiR7a2V5fWBdID1cbiAgICAgICAgICAgICAgICBTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2YXJpYW50VXJsT3ZlcnJpZGUpIHtcbiAgICAgICAgICAgIGdsb2JhbFByb3BlcnRpZXNbXCJnbG9iYWxQcm9wZXJ0aWVzLnZhcmlhbnRVcmxPdmVycmlkZVwiXSA9XG4gICAgICAgICAgICAgIHZhcmlhbnRVcmxPdmVycmlkZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHZhcmlhbnRJbmZvT3ZlcnJpZGUpIHtcbiAgICAgICAgICAgIGdsb2JhbFByb3BlcnRpZXNbXCJnbG9iYWxQcm9wZXJ0aWVzLnZhcmlhbnRJbmZvT3ZlcnJpZGVcIl0gPVxuICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh2YXJpYW50SW5mb092ZXJyaWRlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNob3cgIT0gbnVsbCkge1xuICAgICAgICAgICAgZ2xvYmFsUHJvcGVydGllc1tcImdsb2JhbFByb3BlcnRpZXMuc2hvd1wiXSA9IFN0cmluZyhzaG93KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbmFibGVkRmVhdHVyZXMgPSBmZWF0dXJlRmxhZ1NlcnZpY2UhLmdldEZlYXR1cmVGbGFncygpO1xuICAgICAgICAgIGNvbnN0IGVuYWJsZWRGZWF0dXJlc1Byb3BlcnRpZXMgPSBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICAgIGVuYWJsZWRGZWF0dXJlc1xuICAgICAgICAgICkucmVkdWNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KFxuICAgICAgICAgICAgKGFjYywgW2tleSwgdmFsdWVdKSA9PiAoe1xuICAgICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICAgIFtgZW5hYmxlZEZlYXR1cmVzLiR7a2V5fWBdOiBgJHt2YWx1ZX1gLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB7fVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCB0aW1pbmdQcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgXCJ0aW1pbmcuZW5yaWNoZWRfYXRfbXNcIjogd2luZG93LnBlcmZvcm1hbmNlPy5ub3coKSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgZW5yaWNoZWRFdmVudCA9IHtcbiAgICAgICAgICAgIC4uLmV2ZW50LFxuICAgICAgICAgICAgZXZlbnRfcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAuLi5ldmVudC5ldmVudF9wcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAuLi5nZXREZWZhdWx0VHJhY2tpbmdQcm9wcygpLFxuICAgICAgICAgICAgICAuLi5nbG9iYWxQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAuLi5lbmFibGVkRmVhdHVyZXNQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAuLi50aW1pbmdQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVucmljaGVkRXZlbnQgPSBldmVudDtcbiAgICAgICAgfVxuXG4gICAgICAgIEV2ZW50c0Rpc3BhdGNoZXIuZGlzcGF0Y2goU3BpZmZ5RXZlbnQuQU1QTElUVURFX0VWRU5ULCBlbnJpY2hlZEV2ZW50KTtcblxuICAgICAgICByZXR1cm4gZW5yaWNoZWRFdmVudDtcbiAgICAgIH0sXG4gICAgfTtcbiAgICBzZXRJbnRlcm5hbEV2ZW50VHJhY2tpbmdFbnJpY2htZW50KGVucmljaG1lbnQpO1xuICAgIHJldHVybiBlbnJpY2htZW50O1xuICB9LCBbXG4gICAgaW50ZXJuYWxFdmVudFRyYWNraW5nRW5yaWNobWVudCxcbiAgICBnZXREZWZhdWx0VHJhY2tpbmdQcm9wcyxcbiAgICBmZWF0dXJlRmxhZ1NlcnZpY2UsXG4gICAgcHVibGljS2V5LFxuICAgIGZlYXR1cmVPdmVycmlkZXMsXG4gICAgdmFyaWFudFVybE92ZXJyaWRlLFxuICAgIHZhcmlhbnRJbmZvT3ZlcnJpZGUsXG4gICAgc2hvdyxcbiAgXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaXNSZWFkeSAmJiAhYW1wbGl0dWRlQ2xpZW50KSB7XG4gICAgICBjb25zdCBjdXJyZW50QW1wbGl0dWRlSW5zdGFuY2U6IEJyb3dzZXJDbGllbnQgPSBjcmVhdGVJbnN0YW5jZSgpO1xuICAgICAgY29uc3QgaXNTZXNzaW9uc0VuYWJsZWQgPSBhbXBsaXR1ZGVTZXNzaW9uUmVwbGF5SW5pdCgpO1xuICAgICAgY3VycmVudEFtcGxpdHVkZUluc3RhbmNlLmFkZChnZXRFdmVudFRyYWNraW5nRW5yaWNobWVudCgpKTtcbiAgICAgIGN1cnJlbnRBbXBsaXR1ZGVJbnN0YW5jZS5pbml0KGFtcGxpdHVkZUFwaUtleSEsIHVzZXJJZCEsIHtcbiAgICAgICAgc2VydmVyWm9uZTogZGF0YVJlc2lkZW5jeSBhcyBTZXJ2ZXJab25lVHlwZSxcbiAgICAgICAgdHJhY2tpbmdPcHRpb25zOiB7XG4gICAgICAgICAgaXBBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBhdXRvY2FwdHVyZToge1xuICAgICAgICAgIGF0dHJpYnV0aW9uOiB0cnVlLFxuICAgICAgICAgIHBhZ2VWaWV3czoge1xuICAgICAgICAgICAgdHJhY2tIaXN0b3J5Q2hhbmdlczogXCJwYXRoT25seVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2Vzc2lvbnM6IGlzU2Vzc2lvbnNFbmFibGVkLFxuICAgICAgICAgIGZvcm1JbnRlcmFjdGlvbnM6IGZhbHNlLFxuICAgICAgICAgIGZpbGVEb3dubG9hZHM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBzZXRBbXBsaXR1ZGVDbGllbnQoY3VycmVudEFtcGxpdHVkZUluc3RhbmNlKTtcbiAgICB9XG4gIH0sIFtcbiAgICBpc1JlYWR5LFxuICAgIGFtcGxpdHVkZUNsaWVudCxcbiAgICBhbXBsaXR1ZGVBcGlLZXksXG4gICAgdXNlcklkLFxuICAgIGRhdGFSZXNpZGVuY3ksXG4gICAgYW1wbGl0dWRlU2Vzc2lvblJlcGxheUluaXQsXG4gICAgZ2V0RXZlbnRUcmFja2luZ0VucmljaG1lbnQsXG4gIF0pO1xuXG4gIGNvbnN0IHRyYWNrRXZlbnQgPSB1c2VDYWxsYmFjayhcbiAgICBhc3luYyAoe1xuICAgICAgZXZlbnROYW1lLFxuICAgICAgZXZlbnRQcm9wcyxcbiAgICAgIGV2ZW50R3JvdXBzLFxuICAgICAgYWxzb1NlbmRUb0dvb2dsZUFuYWx5dGljcyA9IGZhbHNlLFxuICAgIH06IFRyYWNrRXZlbnRQYXJhbXMpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIExvZ2dlci5sb2dEZWJ1ZyhcIlN1Ym1pdHRpbmcgZXZlbnRcIiwgZXZlbnROYW1lKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRlY29yYXRlZEV2ZW50TmFtZSA9IGBbU3BpZmZ5XSAke2V2ZW50TmFtZX1gO1xuXG4gICAgICAgIGlmICghYW1wbGl0dWRlQ2xpZW50KSB7XG4gICAgICAgICAgTG9nZ2VyLmxvZ1dhcm4oXCJhbXBsaXR1ZGUgY2xpZW50IHVuZGVmaW5lZFwiLCB1bmRlZmluZWQsIHtcbiAgICAgICAgICAgIGV2ZW50X25hbWU6IGRlY29yYXRlZEV2ZW50TmFtZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBldmVudERhdGEgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgZXZlbnROYW1lLFxuICAgICAgICAgIGV2ZW50UHJvcHMsXG4gICAgICAgICAgY3JlYXRlZF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICAgICAgICBjb25zdCBkYXRhID0gZW5jb2Rlci5lbmNvZGUoZXZlbnREYXRhKTtcbiAgICAgICAgIC8vIGNhbGN1bGF0ZSBhIGhhc2ggb2YgdGhlIGV2ZW50IHByb3BlcnRpZXMgdG8gdXNlIGFzIHRoZSBpbnNlcnRfaWQgc28gdGhhdCBkdXBsaWNhdGUgZXZlbnRzXG4gICAgICAgIC8vIGFyZSBhdXRvbWF0aWNhbGx5IGRyb3BwZWQgYnkgQW1wbGl0dWRlXG4gICAgICAgIGNvbnN0IGhhc2hCdWZmZXIgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdChcIlNIQS0yNTZcIiwgZGF0YSk7XG4gICAgICAgIGNvbnN0IGhhc2hBcnJheSA9IEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkoaGFzaEJ1ZmZlcikpO1xuICAgICAgICBjb25zdCBjdXJyZW50SW5zZXJ0SWQgPSBoYXNoQXJyYXlcbiAgICAgICAgICAubWFwKChiKSA9PiBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCBcIjBcIikpXG4gICAgICAgICAgLmpvaW4oXCJcIik7XG5cbiAgICAgICAgTG9nZ2VyLmxvZ0RlYnVnKGBhbXBsaXR1ZGUgdHJhY2tpbmcgJHtkZWNvcmF0ZWRFdmVudE5hbWV9YCwgbnVsbCwge1xuICAgICAgICAgIGV2ZW50X25hbWU6IGRlY29yYXRlZEV2ZW50TmFtZSxcbiAgICAgICAgICBwcm9wczogZXZlbnRQcm9wcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYW1wbGl0dWRlQ2xpZW50LnRyYWNrKFxuICAgICAgICAgIGRlY29yYXRlZEV2ZW50TmFtZSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5nZXREZWZhdWx0VHJhY2tpbmdQcm9wcygpLFxuICAgICAgICAgICAgLi4uZXZlbnRQcm9wcyxcbiAgICAgICAgICAgIC4uLihldmVudFByb3BzXG4gICAgICAgICAgICAgID8gZXZlbnRQcm9wc1RvUHJlZml4ZWRFdmVudFByb3BzKGV2ZW50TmFtZSwgZXZlbnRQcm9wcylcbiAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5ldmVudEdyb3VwcyxcbiAgICAgICAgICAgIGluc2VydF9pZDogY3VycmVudEluc2VydElkLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoYWxzb1NlbmRUb0dvb2dsZUFuYWx5dGljcyAmJiBvcmdHYUNvbmZpZykge1xuICAgICAgICAgIC8vIFRPRE86IEFkZCBpbiB3aW5kb3dEYXRhTGF5ZXJTZXJ2aWNlIG9yIGNvbnRleHQgYWx0ZXJuYXRpdmUgYW5kIGhvb2sgaXQgdXAgaGVyZVxuICAgICAgICAgIExvZ2dlci5sb2dEZWJ1ZyhcIltzcGlmZnktYWldIEdBIHRyYWNraW5nXCIsIGRlY29yYXRlZEV2ZW50TmFtZSk7XG4gICAgICAgICAgaWYgKHdpbmRvdy5kYXRhTGF5ZXIpIHtcbiAgICAgICAgICAgICh3aW5kb3cuZGF0YUxheWVyIGFzIGFueVtdKS5wdXNoKHtcbiAgICAgICAgICAgICAgZXZlbnQ6IGRlY29yYXRlZEV2ZW50TmFtZSxcbiAgICAgICAgICAgICAgZXZlbnRQcm9wczogZXZlbnRQcm9wcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci5sb2dFcnJvcihcIltzcGlmZnktYWldIEVycm9yIHRyYWNraW5nIGV2ZW50XCIsIGVyciwge1xuICAgICAgICAgIGV2ZW50TmFtZSxcbiAgICAgICAgICBldmVudFByb3BzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIFtcbiAgICAgIGFtcGxpdHVkZUNsaWVudCxcbiAgICAgIGdldERlZmF1bHRUcmFja2luZ1Byb3BzLFxuICAgICAgZXZlbnRQcm9wc1RvUHJlZml4ZWRFdmVudFByb3BzLFxuICAgICAgb3JnR2FDb25maWcsXG4gICAgXVxuICApO1xuXG4gIGNvbnN0IHZhbHVlID0gdXNlTWVtbyhcbiAgICAoKSA9PiAoe1xuICAgICAgdHJhY2tFdmVudCxcbiAgICAgIGlzUmVhZHksXG4gICAgICBzZXRTdXBwbGVtZW50YWxEZWZhdWx0UHJvcHM6IChwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+XG4gICAgICAgIHNldFN1cHBsZW1lbnRhbERlZmF1bHRQcm9wcyhwcm9wcyksXG4gICAgfSksXG4gICAgW3RyYWNrRXZlbnQsIGlzUmVhZHksIHNldFN1cHBsZW1lbnRhbERlZmF1bHRQcm9wc11cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxBbXBsaXR1ZGVDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt2YWx1ZX0+XG4gICAgICB7Y2hpbGRyZW59XG4gICAgPC9BbXBsaXR1ZGVDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IHVzZUFtcGxpdHVkZSA9ICgpID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoQW1wbGl0dWRlQ29udGV4dCk7XG4gIGlmICghY29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInVzZUFtcGxpdHVkZSBtdXN0IGJlIHVzZWQgd2l0aGluIEFtcGxpdHVkZVByb3ZpZGVyXCIpO1xuICB9XG4gIHJldHVybiBjb250ZXh0O1xufTtcbiIsImltcG9ydCBMb2dnZXIgZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9sb2dnaW5nL2xvZ2dlclwiO1xuaW1wb3J0IHtcbiAgaXNMZWdhY3lVQUVjb21tZXJjZUV2ZW50LFxuICBpc0dBNEVjb21tZXJjZUV2ZW50LFxuICBpc0Jhc2VFY29tbWVyY2VFdmVudCxcbiAgQmFzZUVjb21tZXJjZUV2ZW50LFxufSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVsc1wiO1xuaW1wb3J0IHsgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSB9IGZyb20gXCJzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dC9hbXBsaXR1ZGVDb250ZXh0XCI7XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIFdpbmRvdyB7XG4gICAgZGF0YUxheWVyOiBhbnlbXTtcbiAgfVxufVxuXG5jb25zdCBOT1JNQUxJWkVEX0FERF9UT19DQVJUX0VWRU5UX05BTUVTID0gW1wiYWRkdG9jYXJ0XCIsIFwiYWRkZWR0b2NhcnRcIl07XG5jb25zdCBDSEVDS19EQVRBX0xBWUVSX0lOVEVSVkFMX01TID0gNTAwO1xuY29uc3QgQ0hFQ0tfREFUQV9MQVlFUl9NQVhfQVRURU1QVFMgPSAxMDtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBHb29nbGUgQW5hbHl0aWNzIGV2ZW50IGlzIGFuIGFkZF90b19jYXJ0IGV2ZW50LlxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgbmFtZSB0byBjaGVjay5cbiAqXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBldmVudCBpcyBhbiBhZGRfdG9fY2FydCBldmVudCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5jb25zdCBpc0FkZFRvQ2FydEV2ZW50ID0gKGV2ZW50OiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3Qgbm9ybWFsaXplZEV2ZW50ID0gZXZlbnQucmVwbGFjZSgvWy1fXS9nLCBcIlwiKS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gTk9STUFMSVpFRF9BRERfVE9fQ0FSVF9FVkVOVF9OQU1FUy5zb21lKChuYW1lKSA9PlxuICAgIG5vcm1hbGl6ZWRFdmVudC5pbmNsdWRlcyhuYW1lKVxuICApO1xufTtcblxuLyoqXG4gKiBUcmFja3MgYW4gYWRkX3RvX2NhcnQgZXZlbnQgaW4gQW1wbGl0dWRlLlxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdG8gdHJhY2suXG4gKi9cbmNvbnN0IGhhbmRsZUFkZFRvQ2FydEV2ZW50ID0gKFxuICBldmVudDogQmFzZUVjb21tZXJjZUV2ZW50LFxuICB0cmFjazogKFxuICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgICBldmVudFByb3BzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKSA9PiB2b2lkXG4pID0+IHtcbiAgbGV0IGV2ZW50UHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4gIGlmIChpc0xlZ2FjeVVBRWNvbW1lcmNlRXZlbnQoZXZlbnQpKSB7XG4gICAgZXZlbnRQcm9wcyA9IHtcbiAgICAgIGl0ZW1zOiBldmVudC5lY29tbWVyY2UuYWRkLnByb2R1Y3RzLm1hcCgocHJvZHVjdCkgPT4gKHtcbiAgICAgICAgaXRlbV9uYW1lOiBwcm9kdWN0Lm5hbWUsXG4gICAgICAgIGl0ZW1fY2F0ZWdvcnk6IHByb2R1Y3QuY2F0ZWdvcnksXG4gICAgICAgIHByaWNlOiBwcm9kdWN0LnByaWNlLFxuICAgICAgICBxdWFudGl0eTogcHJvZHVjdC5xdWFudGl0eSxcbiAgICAgIH0pKSxcbiAgICAgIGN1cnJlbmN5OiBldmVudC5lY29tbWVyY2UuYWRkLmN1cnJlbmN5Q29kZSxcbiAgICAgIGV2ZW50X2Zvcm1hdF92ZXJzaW9uOiBcImxlZ2FjeV91bml2ZXJzYWxfYW5hbHl0aWNzXCIsXG4gICAgfTtcbiAgfSBlbHNlIGlmIChpc0dBNEVjb21tZXJjZUV2ZW50KGV2ZW50KSkge1xuICAgIGV2ZW50UHJvcHMgPSB7XG4gICAgICBpdGVtczogZXZlbnQuZWNvbW1lcmNlLml0ZW1zLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgICAgaXRlbV9uYW1lOiBpdGVtLml0ZW1fbmFtZSxcbiAgICAgICAgaXRlbV9jYXRlZ29yeTogaXRlbS5pdGVtX2NhdGVnb3J5LFxuICAgICAgICBwcmljZTogaXRlbS5wcmljZSxcbiAgICAgICAgcXVhbnRpdHk6IGl0ZW0ucXVhbnRpdHksXG4gICAgICB9KSksXG4gICAgICBjdXJyZW5jeTogZXZlbnQuZWNvbW1lcmNlLmN1cnJlbmN5LFxuICAgICAgZXZlbnRfZm9ybWF0X3ZlcnNpb246IFwiZ29vZ2xlX2FuYWx5dGljc180XCIsXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBldmVudFByb3BzID0ge1xuICAgICAgZXZlbnRfcHJvcGVydGllczogeyAuLi5ldmVudCB9LFxuICAgICAgZXZlbnRfZm9ybWF0X3ZlcnNpb246IFwidW5rbm93blwiLFxuICAgIH07XG4gIH1cblxuICB0cmFjayhTcGlmZnlNZXRyaWNzRXZlbnROYW1lLkFkZFRvQ2FydENsaWNrZWQsIHtcbiAgICBldmVudFByb3BzLFxuICB9KTtcbn07XG5cbi8qKlxuICogV3JhcHMgdGhlIHdpbmRvdy5kYXRhTGF5ZXIucHVzaCBtZXRob2QgdG8gaW50ZXJjZXB0IGFkZF90b19jYXJ0IGV2ZW50cyBhbmQgc2VuZCB0aGVtIHRvIEFtcGxpdHVkZS5cbiAqIFRoaXMgZnVuY3Rpb24gcnVucyBvbiBhbiBpbnRlcnZhbCB1bnRpbCB0aGUgZGF0YUxheWVyIGlzIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGluaXREYXRhTGF5ZXJXcmFwcGVyID0gKFxuICB0cmFjazogKFxuICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgICBldmVudFByb3BzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKSA9PiB2b2lkXG4pID0+IHtcbiAgbGV0IGF0dGVtcHRzID0gMDtcblxuICAvLyBjdXJyZW50bHksIG91ciBidW5kbGUgaXMgYWx3YXlzIGxvYWRlZCBhZnRlciBHVE0gaGFzIGluaXRpYWxpemVkIEdBL2RhdGFMYXllclxuICAvLyB3ZSdsbCBuZWVkIHRoaXMgY2hlY2sgaGVyZSBpZi93aGVuIHdlIGxvYWQgc3BpZmZ5IGJlZm9yZS9vdXRzaWRlIG9mIEdUTVxuICBjb25zdCBjaGVja0FuZEluaXRpYWxpemUgPSAoKSA9PiB7XG4gICAgaWYgKCF3aW5kb3cuZGF0YUxheWVyIHx8ICEod2luZG93LmRhdGFMYXllciBhcyBhbnkpLnB1c2gpIHtcbiAgICAgIGF0dGVtcHRzICs9IDE7XG5cbiAgICAgIGlmIChhdHRlbXB0cyA+PSBDSEVDS19EQVRBX0xBWUVSX01BWF9BVFRFTVBUUykge1xuICAgICAgICBMb2dnZXIubG9nRGVidWcoXG4gICAgICAgICAgYFtzcGlmZnktYWldIGRhdGFMYXllciBub3QgYXZhaWxhYmxlIGFmdGVyICR7Q0hFQ0tfREFUQV9MQVlFUl9NQVhfQVRURU1QVFN9IGF0dGVtcHRzYFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHNldFRpbWVvdXQoY2hlY2tBbmRJbml0aWFsaXplLCBDSEVDS19EQVRBX0xBWUVSX0lOVEVSVkFMX01TKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBMb2dnZXIubG9nRGVidWcoXG4gICAgICBcIltzcGlmZnktYWldIGRhdGFMYXllciBpcyBhdmFpbGFibGUsIHdyYXBwaW5nIHB1c2ggZnVuY3Rpb24uLi5cIlxuICAgICk7XG4gICAgY29uc3Qgb3JpZ2luYWxQdXNoID0gd2luZG93LmRhdGFMYXllci5wdXNoO1xuICAgIHdpbmRvdy5kYXRhTGF5ZXIucHVzaCA9ICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgaXNCYXNlRWNvbW1lcmNlRXZlbnQoYXJnc1swXSkgJiZcbiAgICAgICAgaXNBZGRUb0NhcnRFdmVudCgoYXJnc1swXSBhcyBhbnkpLmV2ZW50KVxuICAgICAgKSB7XG4gICAgICAgIGhhbmRsZUFkZFRvQ2FydEV2ZW50KGFyZ3NbMF0gYXMgQmFzZUVjb21tZXJjZUV2ZW50LCB0cmFjayk7XG4gICAgICB9XG5cbiAgICAgIC8vIElNUE9SVEFOVDogY2FsbCB0aGUgb3JpZ2luYWwgcHVzaCBtZXRob2Qgc28gdGhhdCB0aGUgZXZlbnQgaXMgc3RpbGwgbG9nZ2VkIHRvIEdBXG4gICAgICByZXR1cm4gb3JpZ2luYWxQdXNoLmFwcGx5KHdpbmRvdy5kYXRhTGF5ZXIsIGFyZ3MpO1xuICAgIH07XG4gIH07XG5cbiAgY2hlY2tBbmRJbml0aWFsaXplKCk7XG59O1xuXG5leHBvcnQgY29uc3QgaW5pdEFtcGxpdHVkZSA9IChcbiAgdHJhY2s6IChcbiAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUsXG4gICAgZXZlbnRQcm9wcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICkgPT4gdm9pZFxuKSA9PiB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gbWlnaHQgbm90IGJlIG5lZWRlZCBhbnltb3JlIGlmIEFtcGxpdHVkZSBpcyBpbml0aWFsaXplZCB2aWEgY29udGV4dC5cbiAgLy8gRm9yIG5vdywgd2UnbGwga2VlcCBpdCBhbmQgcGFzcyB0aGUgdHJhY2sgZnVuY3Rpb24uXG4gIC8vIElmIGl0J3MgdHJ1bHkgcmVkdW5kYW50LCBpdCBjYW4gYmUgcmVtb3ZlZCBsYXRlci5cbiAgdHJhY2soU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5CdW5kbGVMb2FkZWQpOyAvLyBFeGFtcGxlIHVzYWdlLCBhZGp1c3QgYXMgbmVlZGVkXG59O1xuIiwiZXhwb3J0IGNvbnN0IGRpdmlkZUFycmF5ID0gPFQ+KGFycmF5OiBUW10sIHNpemU6IG51bWJlcikgPT4ge1xuICBjb25zdCByb3dzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSArPSAxKSB7XG4gICAgcm93cy5wdXNoKGFycmF5LmZpbHRlcigoXzogVCwgaW5kZXg6IG51bWJlcikgPT4gaW5kZXggJSBzaXplID09PSBpKSk7XG4gIH1cbiAgcmV0dXJuIHJvd3M7XG59O1xuIiwiaW1wb3J0IHsgTWVzc2FnZSwgTWVzc2FnZVR5cGUsIFByb2R1Y3RNZXNzYWdlTWV0YWRhdGEgfSBmcm9tICdzcmMvYXBwbGljYXRpb24vbW9kZWxzJztcblxuZXhwb3J0IGNvbnN0IGdldFJlY2VudFByb2R1Y3RJbWFnZVVybHMgPSAobGFzdE1lc3NhZ2VzOiBNZXNzYWdlW10sIGN1cnJlbnRQcm9kdWN0SWQ6IHN0cmluZyB8IHVuZGVmaW5lZCkgPT4ge1xuICBjb25zdCBwcm9kdWN0TWVzc2FnZXMgPSBsYXN0TWVzc2FnZXNcbiAgICAuZmlsdGVyKChtZXNzYWdlKSA9PiBtZXNzYWdlLnR5cGUgPT09IE1lc3NhZ2VUeXBlLlByb2R1Y3QgJiYgbWVzc2FnZS5tZXRhZGF0YT8uaW1hZ2VVcmwpXG4gICAgLm1hcCgobSkgPT4gbSBhcyBQcm9kdWN0TWVzc2FnZU1ldGFkYXRhKTtcbiAgLy8gcHV0IGFkZGVkIHByb2R1Y3QgaW1hZ2UgYXQgdGhlIHRvcCBvZiB0aGUgbGlzdFxuICByZXR1cm4gW1xuICAgIC4uLnByb2R1Y3RNZXNzYWdlcy5maWx0ZXIoKG0pID0+IG0ubWV0YWRhdGE/LmlkID09PSBjdXJyZW50UHJvZHVjdElkKSxcbiAgICAuLi5wcm9kdWN0TWVzc2FnZXMuZmlsdGVyKChtKSA9PiBtLm1ldGFkYXRhPy5pZCAhPT0gY3VycmVudFByb2R1Y3RJZCksXG4gIF0ubWFwKChtKSA9PiBtLm1ldGFkYXRhIS5pbWFnZVVybCEpO1xufTtcbiIsImV4cG9ydCBjb25zdCBwcmVwYXJlTWVyY2hhbnRQYWdlID0gKCkgPT4ge1xuICBsZXQgbWV0YVZpZXdwb3J0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1ldGFbbmFtZT0ndmlld3BvcnQnXVwiKTtcbiAgaWYgKG1ldGFWaWV3cG9ydCkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBtZXRhVmlld3BvcnQuZ2V0QXR0cmlidXRlKFwiY29udGVudFwiKVxuICAgIGNvbnN0IGhhc01heGltdW1TY2FsZSA9IGNvbnRlbnQ/LmluY2x1ZGVzKFwibWF4aW11bS1zY2FsZT0xXCIpXG4gICAgaWYgKCFoYXNNYXhpbXVtU2NhbGUpIHtcbiAgICAgIG1ldGFWaWV3cG9ydC5zZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIsIGAke2NvbnRlbnR9LCBtYXhpbXVtLXNjYWxlPTFgKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuXG4gIG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJtZXRhXCIpO1xuICBtZXRhVmlld3BvcnQuc2V0QXR0cmlidXRlKFwibmFtZVwiLCBcInZpZXdwb3J0XCIpXG4gIG1ldGFWaWV3cG9ydC5zZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIsIFwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEsIG1heGltdW0tc2NhbGU9MVwiKVxuICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1ldGFWaWV3cG9ydCk7XG59XG4iLCJpbXBvcnQgeyBVc2VyRXZlbnRDYXRlZ29yeSB9IGZyb20gJ0BzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudCc7XG5pbXBvcnQgeyBNZXNzYWdlLCBNZXNzYWdlUm9sZSwgTWVzc2FnZVR5cGUsIFVzZXJFdmVudCB9IGZyb20gJ3NyYy9hcHBsaWNhdGlvbi9tb2RlbHMnO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgYSBxdWVyeSBVc2VyRXZlbnQgb2JqZWN0IGludG8gYSBNZXNzYWdlIG9iamVjdCBmb3IgcHJlc2VudGF0aW9uLlxuICpcbiAqIEBwYXJhbSBldmVudCBUaGUgdXNlciBldmVudCBvYmplY3QgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyXG4gKlxuICogQHJldHVybnMgQSBNZXNzYWdlIGlmIHRoZSBldmVudCBpcyBhIHF1ZXJ5IGV2ZW50LCBvdGhlcndpc2UgdW5kZWZpbmVkXG4gKi9cbmV4cG9ydCBjb25zdCBtZXNzYWdlRnJvbVF1ZXJ5RXZlbnQgPSAoZXZlbnQ6IFVzZXJFdmVudCk6IE1lc3NhZ2UgfCB1bmRlZmluZWQgPT4ge1xuICBpZiAoZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlF1ZXJ5VHlwZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IGV2ZW50LmV2ZW50SWQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Vc2VyLFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuUXVlcnlUeXBlZCxcbiAgICAgIGNyZWF0ZWRBdDogZXZlbnQuY3JlYXRlZEF0LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgY29udGVudDogZXZlbnQuYXR0cmlidXRlcy5xdWVyeSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuU2VhcmNoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBldmVudC5ldmVudElkLFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuVXNlcixcbiAgICAgIHR5cGU6IE1lc3NhZ2VUeXBlLlNlYXJjaCxcbiAgICAgIGNyZWF0ZWRBdDogZXZlbnQuY3JlYXRlZEF0LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgc2VhcmNoVGVybTogZXZlbnQuYXR0cmlidXRlcy5zZWFyY2hUZXJtIHx8ICcnLFxuICAgICAgICBzZWxlY3RlZEZpbHRlcnM6IGV2ZW50LmF0dHJpYnV0ZXMuc2VsZWN0ZWRGaWx0ZXJzIHx8IFtdLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG4iLCJpbXBvcnQgeyBSZXNwb25zZUNhdGVnb3J5IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IE1lc3NhZ2UsIE1lc3NhZ2VSb2xlLCBNZXNzYWdlVHlwZSwgUmVzcG9uc2UgfSBmcm9tICdzcmMvYXBwbGljYXRpb24vbW9kZWxzJztcblxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgc2VydmVyIFJlc3BvbnNlIG9iamVjdCBpbnRvIGEgTWVzc2FnZSBvYmplY3QgZm9yIHByZXNlbnRhdGlvbi5cbiAqXG4gKiBAcGFyYW0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlIG9iamVjdCByZWNlaXZlZCBmcm9tIHRoZSBzZXJ2ZXIgY29udGFpbmluZyBtb2RlbCBnZW5lcmF0ZWQgY29udGVudFxuICpcbiAqIEByZXR1cm5zIEEgTWVzc2FnZSBpZiB0aGUgcmVzcG9uc2UgY29udGFpbnMga25vd24gYXR0cmlidXRlcywgdW5kZWZpbmVkIG90aGVyd2lzZVxuICovXG5leHBvcnQgY29uc3QgbWVzc2FnZUZyb21SZXNwb25zZSA9IChyZXNwb25zZT86IFJlc3BvbnNlKTogTWVzc2FnZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChyZXNwb25zZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5UZXh0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNwb25zZS5pZCxcbiAgICAgIGNyZWF0ZWRBdDogcmVzcG9uc2UuY3JlYXRlZEF0LFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuVGV4dCxcbiAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLkFzc2lzdGFudCxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIGNvbnRlbnQ6IHJlc3BvbnNlLmF0dHJpYnV0ZXMuY29udGVudCxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5Qcm9kdWN0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNwb25zZS5pZCxcbiAgICAgIGNyZWF0ZWRBdDogcmVzcG9uc2UuY3JlYXRlZEF0LFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuQXNzaXN0YW50LFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuUHJvZHVjdCxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIC4uLnJlc3BvbnNlLmF0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAocmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuUmV2aWV3KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNwb25zZS5pZCxcbiAgICAgIGNyZWF0ZWRBdDogcmVzcG9uc2UuY3JlYXRlZEF0LFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuUmV2aWV3LFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuQXNzaXN0YW50LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgcmV2aWV3OiByZXNwb25zZS5hdHRyaWJ1dGVzLnJldmlldyxcbiAgICAgICAgcmV2aWV3ZXI6IHJlc3BvbnNlLmF0dHJpYnV0ZXMucmV2aWV3ZXIsXG4gICAgICAgIHN0YXJzOiByZXNwb25zZS5hdHRyaWJ1dGVzLnN0YXJzLFxuICAgICAgICB0aXRsZTogcmVzcG9uc2UuYXR0cmlidXRlcy50aXRsZSxcbiAgICAgICAgcmljaEluZm9ybWF0aW9uOiByZXNwb25zZS5hdHRyaWJ1dGVzLnJpY2hJbmZvcm1hdGlvbixcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5TZXBhcmF0b3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5TZXBhcmF0b3IsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5QYWdlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNwb25zZS5pZCxcbiAgICAgIGNyZWF0ZWRBdDogcmVzcG9uc2UuY3JlYXRlZEF0LFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuQXNzaXN0YW50LFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuUGFnZSxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIC4uLnJlc3BvbnNlLmF0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAocmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuUHJvZHVjdFNlYXJjaCkge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogcmVzcG9uc2UuaWQsXG4gICAgICBjcmVhdGVkQXQ6IHJlc3BvbnNlLmNyZWF0ZWRBdCxcbiAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLkFzc2lzdGFudCxcbiAgICAgIHR5cGU6IE1lc3NhZ2VUeXBlLlByb2R1Y3RTZWFyY2gsXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICAuLi5yZXNwb25zZS5hdHRyaWJ1dGVzLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHJlc3BvbnNlLmNhdGVnb3J5ID09PSBSZXNwb25zZUNhdGVnb3J5LlByb2R1Y3RTZWFyY2hGaWx0ZXIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5Qcm9kdWN0U2VhcmNoRmlsdGVyLFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgLi4ucmVzcG9uc2UuYXR0cmlidXRlcyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5Gb3JtKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiByZXNwb25zZS5pZCxcbiAgICAgIGNyZWF0ZWRBdDogcmVzcG9uc2UuY3JlYXRlZEF0LFxuICAgICAgcm9sZTogTWVzc2FnZVJvbGUuQXNzaXN0YW50LFxuICAgICAgdHlwZTogTWVzc2FnZVR5cGUuRm9ybSxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIGZvcm1UeXBlOiByZXNwb25zZS5hdHRyaWJ1dGVzLmZvcm1DYXRlZ29yeT8uZm9ybVR5cGUsXG4gICAgICAgIGZpZWxkczogT2JqZWN0LmVudHJpZXMocmVzcG9uc2UuYXR0cmlidXRlcy5zY2hlbWEucHJvcGVydGllcykubWFwKChba2V5LCB2YWx1ZV0pID0+ICh7XG4gICAgICAgICAga2V5LFxuICAgICAgICAgIHRpdGxlOiB2YWx1ZS50aXRsZSxcbiAgICAgICAgICB0eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICAgIGZvcm1hdDogdmFsdWUuZm9ybWF0LFxuICAgICAgICAgIHJlcXVpcmVkOiByZXNwb25zZS5hdHRyaWJ1dGVzLnNjaGVtYS5yZXF1aXJlZC5pbmNsdWRlcyhrZXkpLFxuICAgICAgICB9KSksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBpZiAocmVzcG9uc2UuY2F0ZWdvcnkgPT09IFJlc3BvbnNlQ2F0ZWdvcnkuT3JkZXIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc3BvbnNlLmlkLFxuICAgICAgY3JlYXRlZEF0OiByZXNwb25zZS5jcmVhdGVkQXQsXG4gICAgICByb2xlOiBNZXNzYWdlUm9sZS5Bc3Npc3RhbnQsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5PcmRlcixcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIC4uLnJlc3BvbnNlLmF0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufTtcbiIsImltcG9ydCB7IFVzZXJFdmVudENhdGVnb3J5IH0gZnJvbSAnQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50JztcbmltcG9ydCB7IE1lc3NhZ2UsIE1lc3NhZ2VSb2xlLCBNZXNzYWdlVHlwZSwgU3VnZ2VzdGlvbiwgVXNlckV2ZW50IH0gZnJvbSAnc3JjL2FwcGxpY2F0aW9uL21vZGVscyc7XG5cbi8qKlxuICogVHJhbnNmb3JtcyBhIFVzZXJFdmVudCBvYmplY3QgaW50byBhIE1lc3NhZ2Ugb2JqZWN0IGZvciBwcmVzZW50YXRpb24uXG4gKlxuICogQHBhcmFtIGV2ZW50IFRoZSBVc2VyRXZlbnQgb2JqZWN0IHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlclxuICogQHBhcmFtIHN1Z2dlc3Rpb25zIEEgbGlzdCBvZiBnZW5lcmF0ZWQgc3VnZ2VzdGlvbnMgdG8gbWF0Y2ggdGhlIGV2ZW50IHRvXG4gKlxuICogQHJldHVybnMgQSBNZXNzYWdlIGlmIHRoZSBldmVudCBpcyBhIHN1Z2dlc3Rpb24gY2xpY2sgZXZlbnQsIHVuZGVmaW5lZCBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGNvbnN0IG1lc3NhZ2VGcm9tU3VnZ2VzdGlvbkV2ZW50ID0gKFxuICBldmVudDogVXNlckV2ZW50LFxuICBzdWdnZXN0aW9uczogU3VnZ2VzdGlvbltdLFxuKTogTWVzc2FnZSB8IHVuZGVmaW5lZCA9PiB7XG4gIGlmIChldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuU3VnZ2VzdGlvbkNsaWNrZWQpIHtcbiAgICBjb25zdCB7IHN1Z2dlc3Rpb25JZCB9ID0gZXZlbnQuYXR0cmlidXRlcztcblxuICAgIHJldHVybiB7XG4gICAgICBpZDogZXZlbnQuZXZlbnRJZCxcbiAgICAgIHJvbGU6IE1lc3NhZ2VSb2xlLlVzZXIsXG4gICAgICB0eXBlOiBNZXNzYWdlVHlwZS5TdWdnZXN0aW9uQ2xpY2tlZCxcbiAgICAgIGNyZWF0ZWRBdDogZXZlbnQuY3JlYXRlZEF0LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgc3VnZ2VzdGlvbklkLFxuICAgICAgICBzdWdnZXN0aW9uQ29udGVudDogc3VnZ2VzdGlvbnMuZmluZCgocykgPT4gcy5pZCA9PT0gc3VnZ2VzdGlvbklkKT8uY29udGVudCA/PyAnJyxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59O1xuIiwiZXhwb3J0IGFic3RyYWN0IGNsYXNzIE5vZGVTZWxlY3RvciB7XG4gIHByaXZhdGUgcGF0dGVybjogc3RyaW5nO1xuICBwcml2YXRlIHJvb3Q6IERvY3VtZW50O1xuXG4gIGNvbnN0cnVjdG9yKHBhdHRlcm46IHN0cmluZykge1xuICAgIHRoaXMucGF0dGVybiA9IHBhdHRlcm47XG4gICAgdGhpcy5yb290ID0gZG9jdW1lbnQ7XG4gIH1cblxuICBnZXRQYXR0ZXJuKCkge1xuICAgIHJldHVybiB0aGlzLnBhdHRlcm47XG4gIH1cblxuICBzZXRSb290KHJvb3Q6IERvY3VtZW50KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdDtcbiAgfVxuXG4gIGdldFJvb3QoKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vdDtcbiAgfVxuXG4gIGFic3RyYWN0IHBhcnNlKCk6IE5vZGUgfCBudWxsO1xufVxuXG5jbGFzcyBRdWVyeVNlbGVjdG9yIGV4dGVuZHMgTm9kZVNlbGVjdG9yIHtcbiAgcGFyc2UoKTogTm9kZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmdldFJvb3QoKS5xdWVyeVNlbGVjdG9yKHRoaXMuZ2V0UGF0dGVybigpKTtcbiAgfVxufVxuXG5jbGFzcyBJRFNlbGVjdG9yIGV4dGVuZHMgTm9kZVNlbGVjdG9yIHtcbiAgcGFyc2UoKTogTm9kZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmdldFJvb3QoKS5nZXRFbGVtZW50QnlJZCh0aGlzLmdldFBhdHRlcm4oKSkgYXMgTm9kZTtcbiAgfVxufVxuXG5jbGFzcyBYcGF0aFNlbGVjdG9yIGV4dGVuZHMgTm9kZVNlbGVjdG9yIHtcbiAgcGFyc2UoKTogTm9kZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmdldFJvb3QoKT8uZXZhbHVhdGUoXG4gICAgICB0aGlzLmdldFBhdHRlcm4oKSxcbiAgICAgIHRoaXMuZ2V0Um9vdCgpLFxuICAgICAgbnVsbCxcbiAgICAgIFhQYXRoUmVzdWx0LkZJUlNUX09SREVSRURfTk9ERV9UWVBFLFxuICAgICAgbnVsbCxcbiAgICApPy5zaW5nbGVOb2RlVmFsdWUgYXMgTm9kZTtcbiAgfVxufVxuXG5jbGFzcyBDaGFpblNlbGVjdG9yIGV4dGVuZHMgTm9kZVNlbGVjdG9yIHtcbiAgcGFyc2UoKTogTm9kZSB8IG51bGwge1xuICAgIGxldCBzZWxlY3RvckluZGV4ID0gMDtcbiAgICBjb25zdCBzZWxlY3RvcnMgPSB0aGlzLmdldFBhdHRlcm4oKS5zcGxpdCgnQCcpO1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IHNlbGVjdG9ycy5sZW5ndGggLSAxO1xuXG4gICAgY29uc3QgcGFyc2VDaGFpbiA9IChwYXR0ZXJuOiBzdHJpbmcsIHByZXZOb2RlPzogTm9kZSB8IG51bGwpOiBOb2RlIHwgbnVsbCA9PiB7XG4gICAgICBjb25zdCBzZWxlY3RvciA9IFNlbGVjdG9yRmFjdG9yeS5wYXJzZShwYXR0ZXJuKTtcblxuICAgICAgaWYgKHByZXZOb2RlKSB7XG4gICAgICAgIHNlbGVjdG9yLnNldFJvb3QocHJldk5vZGUgYXMgRG9jdW1lbnQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjdXJyZW50Tm9kZSA9IHNlbGVjdG9yLnBhcnNlKCk7XG4gICAgICBpZiAoc2VsZWN0b3JJbmRleCA9PT0gbGFzdEluZGV4KSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50Tm9kZTtcbiAgICAgIH1cblxuICAgICAgbGV0IG5vZGU6IE5vZGUgfCBudWxsIHwgdW5kZWZpbmVkID0gY3VycmVudE5vZGUgfHwgZG9jdW1lbnQ7XG4gICAgICBpZiAoKGN1cnJlbnROb2RlIGFzIEhUTUxFbGVtZW50KT8uc2hhZG93Um9vdCkge1xuICAgICAgICBub2RlID0gKGN1cnJlbnROb2RlIGFzIEhUTUxFbGVtZW50KS5zaGFkb3dSb290O1xuICAgICAgfVxuXG4gICAgICBpZiAoKGN1cnJlbnROb2RlIGFzIEhUTUxJRnJhbWVFbGVtZW50KT8uY29udGVudFdpbmRvdykge1xuICAgICAgICBub2RlID0gKGN1cnJlbnROb2RlIGFzIEhUTUxJRnJhbWVFbGVtZW50KS5jb250ZW50V2luZG93Py5kb2N1bWVudDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhcnNlQ2hhaW4oc2VsZWN0b3JzWysrc2VsZWN0b3JJbmRleF0udHJpbSgpLCBub2RlKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHBhcnNlQ2hhaW4oc2VsZWN0b3JzW3NlbGVjdG9ySW5kZXhdLnRyaW0oKSk7XG4gIH1cbn1cblxuY2xhc3MgRW1wdHkgZXh0ZW5kcyBOb2RlU2VsZWN0b3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignJyk7XG4gIH1cbiAgcGFyc2UoKTogTm9kZSB8IG51bGwge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTZWxlY3RvckZhY3Rvcnkge1xuICBzdGF0aWMgcGFyc2UoY29tcG9zZWRTZWxlY3Rvcj86IHN0cmluZykge1xuICAgIGlmICghY29tcG9zZWRTZWxlY3Rvcikge1xuICAgICAgcmV0dXJuIG5ldyBFbXB0eSgpO1xuICAgIH1cblxuICAgIGNvbnN0IHNwbGl0ID0gY29tcG9zZWRTZWxlY3Rvci5zcGxpdCgnfCcpO1xuICAgIGNvbnN0IHR5cGUgPSBzcGxpdFswXTtcbiAgICBjb25zdCBzZWxlY3RvciA9IHNwbGl0WzFdO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdpZCc6XG4gICAgICAgIHJldHVybiB0aGlzLmlkKHNlbGVjdG9yKTtcbiAgICAgIGNhc2UgJ3F1ZXJ5JzpcbiAgICAgICAgcmV0dXJuIHRoaXMucXVlcnkoc2VsZWN0b3IpO1xuICAgICAgY2FzZSAneHBhdGgnOlxuICAgICAgICByZXR1cm4gdGhpcy54cGF0aChzZWxlY3Rvcik7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbmV3IEVtcHR5KCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGNoZWNrKHNlbGVjdG9yPzogTm9kZVNlbGVjdG9yKSB7XG4gICAgcmV0dXJuIHNlbGVjdG9yID8/IG5ldyBFbXB0eSgpO1xuICB9XG5cbiAgc3RhdGljIGNoYWluKHBhdHRlcm4/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gcGF0dGVybiA/IG5ldyBDaGFpblNlbGVjdG9yKHBhdHRlcm4pIDogbmV3IEVtcHR5KCk7XG4gIH1cblxuICBzdGF0aWMgaWQocGF0dGVybj86IHN0cmluZyk6IE5vZGVTZWxlY3RvciB7XG4gICAgcmV0dXJuIHBhdHRlcm4gPyBuZXcgSURTZWxlY3RvcihwYXR0ZXJuKSA6IG5ldyBFbXB0eSgpO1xuICB9XG5cbiAgc3RhdGljIHF1ZXJ5KHBhdHRlcm4/OiBzdHJpbmcpOiBOb2RlU2VsZWN0b3Ige1xuICAgIHJldHVybiBwYXR0ZXJuID8gbmV3IFF1ZXJ5U2VsZWN0b3IocGF0dGVybikgOiBuZXcgRW1wdHkoKTtcbiAgfVxuXG4gIHN0YXRpYyB4cGF0aChwYXR0ZXJuPzogc3RyaW5nKTogTm9kZVNlbGVjdG9yIHtcbiAgICByZXR1cm4gcGF0dGVybiA/IG5ldyBYcGF0aFNlbGVjdG9yKHBhdHRlcm4pIDogbmV3IEVtcHR5KCk7XG4gIH1cbn1cbiIsImV4cG9ydCB0eXBlIFJlcGxhY2VPcDxUPiA9IHsgJHJlcGxhY2U6IFQgfTtcbmV4cG9ydCB0eXBlIERlbGV0ZU9wID0geyAkZGVsZXRlOiB0cnVlIH07XG5cbi8vIFRyZWF0IHRoZXNlIGFzIGF0b21pYyB2YWx1ZXMgKG5vdCByZWN1cnNlZCBpbnRvKVxudHlwZSBCdWlsdGluID0gRGF0ZSB8IFJlZ0V4cCB8ICgoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duKTtcblxudHlwZSBQcmltaXRpdmUgPSBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgYmlnaW50IHwgc3ltYm9sIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBPdmVycmlkZTxUPiBpcyBhIERlZXBQYXJ0aWFsLWxpa2UgdHlwZSB3aXRoIHNwZWNpYWwgb3BlcmF0b3JzOlxuICogLSB7ICRyZXBsYWNlOiBUIH0gdG8gcmVwbGFjZSBhbiBlbnRpcmUgc3VidHJlZS9hcnJheVxuICogLSB7ICRkZWxldGU6IHRydWUgfSB0byBkZWxldGUgYW4gb2JqZWN0IGtleVxuICpcbiAqIEFycmF5cyBiZWhhdmlvcjpcbiAqIC0gQXJyYXlzIG9mIG9iamVjdHM6IG1lcmdlLWJ5LWluZGV4IGJ5IGRlZmF1bHQgKHVubGVzcyBgYXJyYXlTdHJhdGVneTogJ3JlcGxhY2UnYCBvciBgJHJlcGxhY2VgIGlzIHVzZWQpXG4gKiAtIEFycmF5cyBvZiBwcmltaXRpdmVzIChzdHJpbmcvbnVtYmVyL2Jvb2xlYW4vLi4uKTogcmVwbGFjZWQgYnkgZGVmYXVsdCB3aGVuIGEgcGF0Y2ggYXJyYXkgaXMgcHJvdmlkZWRcbiAqL1xuZXhwb3J0IHR5cGUgT3ZlcnJpZGU8VD4gPVxuICAvLyBhdG9taWNcbiAgVCBleHRlbmRzIFByaW1pdGl2ZSB8IEJ1aWx0aW5cbiAgICA/IFQgfCBSZXBsYWNlT3A8VD4gfCBEZWxldGVPcFxuICAgIDogLy8gYXJyYXlzXG4gICAgICBUIGV4dGVuZHMgKGluZmVyIFUpW11cbiAgICAgID8gQXJyYXk8T3ZlcnJpZGU8VT4gfCB1bmRlZmluZWQ+IHwgUmVwbGFjZU9wPFQ+XG4gICAgICA6IC8vIG1hcHMvc2V0cyDigJMga2VlcCBzaW1wbGU6IG9ubHkgYWxsb3cgZnVsbCByZXBsYWNlXG4gICAgICAgIFQgZXh0ZW5kcyBNYXA8dW5rbm93biwgdW5rbm93bj4gfCBTZXQ8dW5rbm93bj5cbiAgICAgICAgPyBSZXBsYWNlT3A8VD5cbiAgICAgICAgOiAvLyBvYmplY3RzXG4gICAgICAgICAgVCBleHRlbmRzIG9iamVjdFxuICAgICAgICAgID8geyBbSyBpbiBrZXlvZiBUXT86IE92ZXJyaWRlPFRbS10+IHwgRGVsZXRlT3AgfCBudWxsIH0gfCBSZXBsYWNlT3A8VD5cbiAgICAgICAgICA6IFQ7XG5cbmV4cG9ydCB0eXBlIE1lcmdlT3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIEhvdyB0byB0cmVhdCBhcnJheXMgd2hlbiBwYXRjaCBwcm92aWRlcyBhbiBhcnJheSAobm90ICRyZXBsYWNlKTpcbiAgICogLSAncmVwbGFjZSc6IGFsd2F5cyB1c2UgcGF0Y2ggYXJyYXkgYXMgd2hvbGUgdmFsdWVcbiAgICogLSAnbWVyZ2VCeUluZGV4JzogbWVyZ2UgZWFjaCBpbmRleCByZWN1cnNpdmVseSAoZGVmYXVsdCBmb3IgYXJyYXlzIG9mIG9iamVjdHMpXG4gICAqIE5vdGU6IEFycmF5cyBvZiBwcmltaXRpdmVzIGFyZSByZXBsYWNlZCBieSBkZWZhdWx0IHJlZ2FyZGxlc3Mgb2YgdGhpcyBvcHRpb24uXG4gICAqL1xuICBhcnJheVN0cmF0ZWd5PzogJ3JlcGxhY2UnIHwgJ21lcmdlQnlJbmRleCc7XG4gIC8qKlxuICAgKiBJZiB0cnVlLCBhIGBudWxsYCBwYXRjaCB2YWx1ZSBkZWxldGVzIHRoZSBrZXkgZnJvbSBhbiBvYmplY3QgKFJGQyA3Mzk2LWlzaClcbiAgICovXG4gIG51bGxEZWxldGVzPzogYm9vbGVhbjtcbn07XG5cbi8vIFByZXZlbnRzIFQgZnJvbSBiZWluZyBpbmZlcnJlZCBmcm9tIHRoZSAncGF0Y2gnIHBhcmFtZXRlcjsgaXQgbXVzdCBiZSBpbmZlcnJlZCBmcm9tICdiYXNlJy5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8xNDgyOSNpc3N1ZWNvbW1lbnQtNTA0MDQyNTQ2XG50eXBlIE5vSW5mZXI8VD4gPSBbVF1bVCBleHRlbmRzIHVua25vd24gPyAwIDogbmV2ZXJdO1xuXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHg6IHVua25vd24pOiB4IGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgcmV0dXJuIChcbiAgICAhIXggJiZcbiAgICB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiZcbiAgICAhQXJyYXkuaXNBcnJheSh4KSAmJlxuICAgICEoeCBpbnN0YW5jZW9mIERhdGUpICYmXG4gICAgISh4IGluc3RhbmNlb2YgUmVnRXhwKVxuICApO1xufVxuXG5mdW5jdGlvbiBpc1JlcGxhY2UoeDogdW5rbm93bik6IHggaXMgUmVwbGFjZU9wPHVua25vd24+IHtcbiAgcmV0dXJuICEheCAmJiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgJyRyZXBsYWNlJyBpbiAoeCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG59XG5mdW5jdGlvbiBpc0RlbGV0ZSh4OiB1bmtub3duKTogeCBpcyBEZWxldGVPcCB7XG4gIHJldHVybiAhIXggJiYgdHlwZW9mIHggPT09ICdvYmplY3QnICYmICh4IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS4kZGVsZXRlID09PSB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZVZhbHVlKHg6IHVua25vd24pOiBib29sZWFuIHtcbiAgY29uc3QgdCA9IHR5cGVvZiB4O1xuICByZXR1cm4gKFxuICAgIHggPT09IG51bGwgfHxcbiAgICB0ID09PSAnc3RyaW5nJyB8fFxuICAgIHQgPT09ICdudW1iZXInIHx8XG4gICAgdCA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgdCA9PT0gJ2JpZ2ludCcgfHxcbiAgICB0ID09PSAnc3ltYm9sJyB8fFxuICAgIHQgPT09ICd1bmRlZmluZWQnXG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlPZlByaW1pdGl2ZXMoYXJyOiB1bmtub3duW10pOiBib29sZWFuIHtcbiAgaWYgKGFyci5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTsgLy8gYW1iaWd1b3VzLCBkZWZhdWx0IHRvIG1lcmdlLWJ5LWluZGV4IG9uIGVtcHR5XG4gIC8vIElmIGV2ZXJ5IGRlZmluZWQgZWxlbWVudCBpcyBwcmltaXRpdmUsIHRyZWF0IGFzIHByaW1pdGl2ZXNcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCB2ID0gYXJyW2ldO1xuICAgIGlmICh2ICE9PSB1bmRlZmluZWQgJiYgIWlzUHJpbWl0aXZlVmFsdWUodikpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VBbnkoYmFzZUFueTogdW5rbm93biwgcGF0Y2hBbnk6IHVua25vd24sIG9wdHM6IE1lcmdlT3B0aW9ucyk6IHVua25vd24ge1xuICBpZiAoaXNSZXBsYWNlKHBhdGNoQW55KSkgcmV0dXJuIHBhdGNoQW55LiRyZXBsYWNlIGFzIHVua25vd247XG4gIGlmIChpc0RlbGV0ZShwYXRjaEFueSkpIHJldHVybiB1bmRlZmluZWQ7IC8vIGNhbGxlciBkZWxldGVzIHRoZSBrZXlcblxuICBpZiAoQXJyYXkuaXNBcnJheShiYXNlQW55KSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHBhdGNoQW55KSkge1xuICAgICAgY29uc3QgYmFzZUFyciA9IGJhc2VBbnkgYXMgdW5rbm93bltdO1xuICAgICAgY29uc3QgcGF0Y2hBcnIgPSBwYXRjaEFueSBhcyB1bmtub3duW107XG4gICAgICBjb25zdCBzaG91bGRSZXBsYWNlID1cbiAgICAgICAgb3B0cy5hcnJheVN0cmF0ZWd5ID09PSAncmVwbGFjZScgfHxcbiAgICAgICAgaXNBcnJheU9mUHJpbWl0aXZlcyhiYXNlQXJyKSB8fFxuICAgICAgICBpc0FycmF5T2ZQcmltaXRpdmVzKHBhdGNoQXJyKTtcbiAgICAgIGlmIChzaG91bGRSZXBsYWNlKSByZXR1cm4gcGF0Y2hBbnkgYXMgdW5rbm93bjtcbiAgICAgIGNvbnN0IG91dCA9IGJhc2VBcnIuc2xpY2UoKTtcbiAgICAgIGNvbnN0IG1heCA9IE1hdGgubWF4KG91dC5sZW5ndGgsIHBhdGNoQXJyLmxlbmd0aCk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1heDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IHBWYWwgPSBwYXRjaEFycltpXTtcbiAgICAgICAgaWYgKHBWYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG91dFtpXSA9IG1lcmdlQW55KG91dFtpXSwgcFZhbCwgb3B0cyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXQgYXMgdW5rbm93bjtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VBbnkgYXMgdW5rbm93bjtcbiAgfVxuXG4gIGlmIChpc1BsYWluT2JqZWN0KGJhc2VBbnkpICYmIGlzUGxhaW5PYmplY3QocGF0Y2hBbnkpKSB7XG4gICAgY29uc3QgYmFzZU9iaiA9IGJhc2VBbnkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgY29uc3QgcGF0Y2hPYmogPSBwYXRjaEFueSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBjb25zdCBvdXQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyAuLi5iYXNlT2JqIH07XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocGF0Y2hPYmopKSB7XG4gICAgICBjb25zdCBwVmFsID0gcGF0Y2hPYmpba2V5XTtcbiAgICAgIGlmIChwVmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gbGVhdmUgYXMtaXNcbiAgICAgIH0gZWxzZSBpZiAob3B0cy5udWxsRGVsZXRlcyAmJiBwVmFsID09PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZSBvdXRba2V5XTtcbiAgICAgIH0gZWxzZSBpZiAoaXNSZXBsYWNlKHBWYWwpKSB7XG4gICAgICAgIG91dFtrZXldID0gcFZhbC4kcmVwbGFjZTtcbiAgICAgIH0gZWxzZSBpZiAoaXNEZWxldGUocFZhbCkpIHtcbiAgICAgICAgZGVsZXRlIG91dFtrZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0W2tleV0gPSBtZXJnZUFueShiYXNlT2JqPy5ba2V5XSwgcFZhbCwgb3B0cyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXQgYXMgdW5rbm93bjtcbiAgfVxuXG4gIHJldHVybiAocGF0Y2hBbnkgYXMgdW5rbm93bikgPz8gYmFzZUFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5T3ZlcnJpZGVzPFQ+KFxuICBiYXNlOiBULFxuICBwYXRjaDogT3ZlcnJpZGU8Tm9JbmZlcjxUPj4sXG4gIG9wdHM6IE1lcmdlT3B0aW9ucyA9IHt9LFxuKTogVCB7XG4gIGNvbnN0IHsgYXJyYXlTdHJhdGVneSA9ICdtZXJnZUJ5SW5kZXgnLCBudWxsRGVsZXRlcyA9IGZhbHNlIH0gPSBvcHRzO1xuXG4gIC8vIEhhbmRsZSB3aG9sZS1ub2RlIGNvbnRyb2wgb3BlcmF0b3JzIG9uIHBhdGNoIGl0c2VsZlxuICBpZiAoaXNSZXBsYWNlKHBhdGNoKSkgcmV0dXJuIHBhdGNoLiRyZXBsYWNlIGFzIFQ7XG4gIGlmIChpc0RlbGV0ZShwYXRjaCkpIHJldHVybiB1bmRlZmluZWQgYXMgdW5rbm93biBhcyBUO1xuXG4gIC8vIEFycmF5c1xuICBpZiAoQXJyYXkuaXNBcnJheShiYXNlKSkge1xuICAgIGlmIChpc1JlcGxhY2UocGF0Y2gpKSByZXR1cm4gcGF0Y2guJHJlcGxhY2UgYXMgVDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwYXRjaCkpIHtcbiAgICAgIGlmIChhcnJheVN0cmF0ZWd5ID09PSAncmVwbGFjZScpIHJldHVybiBwYXRjaCBhcyB1bmtub3duIGFzIFQ7XG4gICAgICAvLyBtZXJnZSBieSBpbmRleFxuICAgICAgY29uc3Qgb3V0ID0gKGJhc2UgYXMgdW5rbm93bltdKS5zbGljZSgpO1xuICAgICAgY29uc3QgbWF4ID0gTWF0aC5tYXgob3V0Lmxlbmd0aCwgcGF0Y2gubGVuZ3RoKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4OyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgcFZhbCA9IChwYXRjaCBhcyB1bmtub3duW10pW2ldO1xuICAgICAgICBpZiAocFZhbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgb3V0W2ldID0gbWVyZ2VBbnkob3V0W2ldLCBwVmFsLCBvcHRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG91dCBhcyB1bmtub3duIGFzIFQ7XG4gICAgfVxuICAgIC8vIGludmFsaWQgcGF0Y2ggdHlwZSBmb3IgYW4gYXJyYXkg4oaSIGlnbm9yZSBhbmQgcmV0dXJuIGJhc2VcbiAgICByZXR1cm4gYmFzZSBhcyBUO1xuICB9XG5cbiAgLy8gUGxhaW4gb2JqZWN0c1xuICBpZiAoaXNQbGFpbk9iamVjdChiYXNlKSAmJiBpc1BsYWluT2JqZWN0KHBhdGNoKSkge1xuICAgIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7IC4uLihiYXNlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB9O1xuICAgIGNvbnN0IHBhdGNoT2JqID0gcGF0Y2ggYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocGF0Y2hPYmopKSB7XG4gICAgICBjb25zdCBwVmFsID0gcGF0Y2hPYmpba2V5XTtcbiAgICAgIGlmIChwVmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gbGVhdmUgZXhpc3RpbmcgdmFsdWVcbiAgICAgIH0gZWxzZSBpZiAobnVsbERlbGV0ZXMgJiYgcFZhbCA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgb3V0W2tleV07XG4gICAgICB9IGVsc2UgaWYgKGlzUmVwbGFjZShwVmFsKSkge1xuICAgICAgICBvdXRba2V5XSA9IHBWYWwuJHJlcGxhY2U7XG4gICAgICB9IGVsc2UgaWYgKGlzRGVsZXRlKHBWYWwpKSB7XG4gICAgICAgIGRlbGV0ZSBvdXRba2V5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGJWYWwgPSAoYmFzZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilba2V5XTtcbiAgICAgICAgb3V0W2tleV0gPSBtZXJnZUFueShiVmFsLCBwVmFsLCBvcHRzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG91dCBhcyB1bmtub3duIGFzIFQ7XG4gIH1cblxuICAvLyBGb3IgcHJpbWl0aXZlcyBvciB3aGVuIHBhdGNoIGlzIHByaW1pdGl2ZSwgcGF0Y2ggd2lucyBpZiBkZWZpbmVkXG4gIHJldHVybiAoKHBhdGNoIGFzIHVua25vd24pID8/IGJhc2UpIGFzIFQ7XG59XG4iLCJcbmNsYXNzIFN0cmluZ1V0aWxzIHtcbiAgc3RhdGljIGlzTnVsbE9yRW1wdHkodmFsdWU6IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHZhbHVlVHJpbW1lZCA9IHZhbHVlPy50cmltKCk7XG4gICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWVUcmltbWVkID09PSAnJztcbiAgfVxuXG4gIHN0YXRpYyB0cmltVG9OdWxsKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHZhbHVlVHJpbW1lZCA9IHZhbHVlPy50cmltKCk7XG4gICAgcmV0dXJuIFN0cmluZ1V0aWxzLmlzTnVsbE9yRW1wdHkodmFsdWVUcmltbWVkKSA/IHVuZGVmaW5lZCA6IHZhbHVlVHJpbW1lZDtcbiAgfVxuXG4gIHN0YXRpYyBjYXBpdGFsaXplKHR5cGU6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICAgIGlmICh0eXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHR5cGUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB0eXBlLnN1YnN0cmluZygxKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgZmlyc3QgcGF0dGVybiBpbiBhbiBhcnJheSB0aGF0IG1hdGNoZXMgYSBnaXZlbiBVUkwuXG4gICAqIFBhdHRlcm5zIGNhbiBpbmNsdWRlIGEgc2luZ2xlIHdpbGRjYXJkICcqJyB3aGljaCBtYXRjaGVzIGFueSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gcGF0dGVybnNcbiAgICogQHBhcmFtIHVybFRvVGVzdFxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgc3RhdGljIGZpbmRNYXRjaGluZ1BhdHRlcm4ocGF0dGVybnM6IHN0cmluZ1tdLCB1cmxUb1Rlc3Q6IExvY2F0aW9uKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXVybFRvVGVzdCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHBhdHRlcm4gb2YgcGF0dGVybnMpIHtcbiAgICAgIC8vIFRlc3Qgb25seSBpZiBhIHBhdGhuYW1lIGlzIHByZXNlbnQuXG4gICAgICBpZiAodXJsVG9UZXN0LnBhdGhuYW1lICE9PSAnLycpIHtcbiAgICAgICAgLy8gRXNjYXBlIHNwZWNpYWwgcmVnZXggY2hhcmFjdGVycyBpbiB0aGUgcGF0dGVyblxuICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCBjaGFyYWN0ZXJzIGxpa2UgJy4nLCAnKycsICc/JywgJygnLCBldGMuLCBpbiB0aGUgcGF0dGVybiBhcmUgdHJlYXRlZCBsaXRlcmFsbHkuXG4gICAgICAgIGNvbnN0IGVzY2FwZWRQYXR0ZXJuID0gcGF0dGVybi5yZXBsYWNlKC9bLis/XiR7fSgpfFtcXF1cXFxcXS9nLCAnXFxcXCQmJyk7XG5cbiAgICAgICAgLy8gUmVwbGFjZSB0aGUgd2lsZGNhcmQgJyonIHdpdGggaXRzIHJlZ2V4IGVxdWl2YWxlbnQgJy4qJyAobWF0Y2hlcyBhbnkgY2hhcmFjdGVyIHplcm8gb3IgbW9yZSB0aW1lcylcbiAgICAgICAgY29uc3QgcmVnZXhQYXR0ZXJuID0gZXNjYXBlZFBhdHRlcm4ucmVwbGFjZSgvXFwqL2csICcuKicpO1xuXG4gICAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7cmVnZXhQYXR0ZXJufSRgKTtcbiAgICAgICAgaWYgKHJlZ2V4LnRlc3QodXJsVG9UZXN0LnBhdGhuYW1lKSkge1xuICAgICAgICAgIHJldHVybiBwYXR0ZXJuO1xuICAgICAgICB9XG5cbiAgICAgIH0gZWxzZSBpZiAocGF0dGVybi5zdGFydHNXaXRoKHVybFRvVGVzdC5ob3N0bmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHBhdHRlcm47XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB7IFN0cmluZ1V0aWxzIH07XG4iLCIvLyBUaGlzIGVtYWlsIHZhbGlkYXRlcyB0aGF0IHRoZXJlIGFyZSBvbmUgb3IgbW9yZSBjaGFyYWN0ZXJzIGJlZm9yZSB0aGUgYEBgIHN5bWJvbCxcbi8vIG9uZSBvciBtb3JlIGNoYXJhY3RlcnMgYmV0d2VlbiB0aGUgYEBgIHN5bWJvbCBhbmQgdGhlIGAuYCBzeW1ib2wsXG4vLyBhbmQgb25lIG9yIG1vcmUgY2hhcmFjdGVycyBhZnRlciB0aGUgYC5gIHN5bWJvbFxuLy8gSXQgZG9lcyBOT1QgdmFsaWRhdGUgYWxsIHBvc3NpYmxlIGVtYWlsIGZvcm1hdHMsIGJ1dCBpdCBpcyBhIGRlY2VudCBwbGFjZSB0byBzdGFydC5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUVtYWlsID0gKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuID0+IC9eW15cXHNAXStAW15cXHNAXStcXC5bXlxcc0BdKyQvLnRlc3QodmFsdWUpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRQSxNQUFhLCtCQUErQixTQUFzQztBQUNoRixLQUNFLEtBQUssYUFBYSxrQkFBa0IsWUFDcEMsS0FBSyxhQUFhLGtCQUFrQixVQUVwQyxRQUFPO0VBQ0wsVUFBVSxLQUFLO0VBQ2YsWUFBWSxLQUFLO0VBQ2pCLFVBQVUsS0FBSztFQUNmLFlBQVk7R0FDVixZQUFZLEtBQUssV0FBVztHQUM1QixtQkFBbUIsS0FBSyxXQUFXO0dBQ25DLEtBQUssS0FBSyxXQUFXO0dBQ3RCO0VBQ0Y7QUFHSCxLQUFJLEtBQUssYUFBYSxrQkFBa0IsU0FDdEMsUUFBTztFQUNMLFVBQVUsS0FBSztFQUNmLFlBQVksS0FBSztFQUNqQixVQUFVLEtBQUs7RUFDZixZQUFZO0dBQ1YsVUFBVSxxQkFBcUI7R0FDL0IsWUFBWSxFQUVWLElBQUssS0FBSyxXQUFXLFdBQStCLElBQ3JEO0dBQ0Y7RUFDRjtBQUdILEtB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