@envive-ai/react-hooks 0.2.6 → 0.2.7-arthur-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/dist/{NewOrgConfig-BxSuoP9C.cjs → NewOrgConfig-Bo1seKr6.cjs} +2 -2
  2. package/dist/{NewOrgConfig-BfrGpiGk.js → NewOrgConfig-yptI2imS.js} +2 -2
  3. package/dist/{SystemSettingsContext-B8X_Dvw2.js → SystemSettingsContext-BY1BFgAQ.js} +2 -2
  4. package/dist/{SystemSettingsContext-Bkoiobdv.cjs → SystemSettingsContext-EDpRMMt2.cjs} +2 -2
  5. package/dist/{TrackComponentVisibleEvent-DwfGqNTx.js → TrackComponentVisibleEvent-CXhKOwKQ.js} +2 -2
  6. package/dist/{TrackComponentVisibleEvent-DMuX-byo.cjs → TrackComponentVisibleEvent-CgxCqrIt.cjs} +2 -2
  7. package/dist/amplitudeContext-BItT9HmT.js +1 -0
  8. package/dist/{amplitudeContext-ZTQMvVTV.cjs → amplitudeContext-C8tT74Mi.cjs} +9 -9
  9. package/dist/{amplitudeContext-B73xamNe.d.cts → amplitudeContext-CCVyp5RU.d.cts} +1 -1
  10. package/dist/{amplitudeContext-DOqL2Vn8.js → amplitudeContext-DCk6Va-j.js} +9 -9
  11. package/dist/amplitudeContext-DPtyVv3Q.cjs +0 -0
  12. package/dist/{amplitudeContext-CiO9T9c-.d.ts → amplitudeContext-DcRur97Z.d.ts} +1 -1
  13. package/dist/{api-bHEYmSiT.js → api-BWSsazAG.js} +3 -3
  14. package/dist/{api-BvygKEiX.cjs → api-DeW6rHj3.cjs} +3 -3
  15. package/dist/{app-BQw_-JGl.cjs → app-BbPSHefQ.cjs} +2 -2
  16. package/dist/{app-Aqkm_SlS.js → app-CflxT_xI.js} +2 -2
  17. package/dist/application/models/graphql/index.cjs +4 -3
  18. package/dist/application/models/graphql/index.d.cts +2 -2
  19. package/dist/application/models/graphql/index.d.ts +2 -2
  20. package/dist/application/models/graphql/index.js +3 -3
  21. package/dist/application/models/guards/api/index.cjs +3 -3
  22. package/dist/application/models/guards/api/index.d.cts +2 -1
  23. package/dist/application/models/guards/api/index.d.ts +2 -1
  24. package/dist/application/models/guards/api/index.js +3 -3
  25. package/dist/application/models/guards/utils.cjs +1 -1
  26. package/dist/application/models/guards/utils.d.cts +1 -1
  27. package/dist/application/models/guards/utils.d.ts +1 -1
  28. package/dist/application/models/guards/utils.js +1 -1
  29. package/dist/application/models/index.cjs +9 -9
  30. package/dist/application/models/index.d.cts +11 -10
  31. package/dist/application/models/index.d.ts +11 -10
  32. package/dist/application/models/index.js +8 -8
  33. package/dist/application/models/variantInfo/index.d.cts +1 -1
  34. package/dist/application/models/variantInfo/index.d.ts +1 -1
  35. package/dist/application/utils/index.cjs +15 -15
  36. package/dist/application/utils/index.d.cts +14 -13
  37. package/dist/application/utils/index.d.ts +14 -13
  38. package/dist/application/utils/index.js +15 -15
  39. package/dist/atoms/app/index.cjs +11 -11
  40. package/dist/atoms/app/index.d.cts +19 -18
  41. package/dist/atoms/app/index.d.ts +19 -18
  42. package/dist/atoms/app/index.js +11 -11
  43. package/dist/atoms/chat/index.cjs +16 -16
  44. package/dist/atoms/chat/index.d.cts +39 -38
  45. package/dist/atoms/chat/index.d.ts +39 -38
  46. package/dist/atoms/chat/index.js +16 -16
  47. package/dist/atoms/globalSearch/index.d.cts +5 -5
  48. package/dist/atoms/globalSearch/index.d.ts +6 -6
  49. package/dist/atoms/org/index.d.cts +30 -29
  50. package/dist/atoms/org/index.d.ts +30 -29
  51. package/dist/atoms/search/index.cjs +18 -18
  52. package/dist/atoms/search/index.d.cts +13 -12
  53. package/dist/atoms/search/index.d.ts +13 -12
  54. package/dist/atoms/search/index.js +18 -18
  55. package/dist/atoms/search/types.d.cts +4 -2
  56. package/dist/atoms/search/types.d.ts +4 -2
  57. package/dist/atoms/search/utils.d.ts +1 -1
  58. package/dist/{cdnContext-Cd0Kvt6g.cjs → cdnContext-CaDyQ_5p.cjs} +2 -2
  59. package/dist/{cdnContext-D8pHA9gh.js → cdnContext-CtrIlAqX.js} +2 -2
  60. package/dist/{chat-U1IgKNij.js → chat-BjhQCyW_.js} +8 -8
  61. package/dist/{chat-DwNALtox.cjs → chat-BkPax29G.cjs} +13 -7
  62. package/dist/{chat-EJbfGWRr.js → chat-ClvJ9xEj.js} +1 -1
  63. package/dist/{chat-CJ9D8n7g.cjs → chat-DCGriB7h.cjs} +1 -1
  64. package/dist/{chatElementDisplayLocation-DWmfNX_u.d.cts → chatElementDisplayLocation-B7vr33eG.d.cts} +1 -1
  65. package/dist/{chatElementDisplayLocation-DbmdwAff.d.ts → chatElementDisplayLocation-D4XF0UfI.d.ts} +1 -1
  66. package/dist/{chatSearch-Bb2SMr9X.js → chatSearch-BsYlFvpv.js} +4 -4
  67. package/dist/{chatSearch-DtE2cUQw.cjs → chatSearch-C3N3iIxu.cjs} +4 -4
  68. package/dist/{chatState-B3Dyrd9M.cjs → chatState-CJ52Ag_7.cjs} +3 -3
  69. package/dist/{chatState-BXBN-12W.js → chatState-CXA1vF16.js} +3 -3
  70. package/dist/{commerce-api-Dx02FCQ7.cjs → commerce-api-DA1QGGMK.cjs} +8 -7
  71. package/dist/{commerce-api-DXbnMNT8.js → commerce-api-rgj30eEp.js} +8 -7
  72. package/dist/{common-CuwWqIJ1.cjs → common-DQPvV_S_.cjs} +1 -1
  73. package/dist/{common-Df2bwzd2.js → common-c_4eX0qn.js} +1 -1
  74. package/dist/{components-QGCWJ26c.js → components-CDpaMUjK.js} +1 -1
  75. package/dist/{components-BCfFLf9X.cjs → components-DKwVHIjq.cjs} +1 -1
  76. package/dist/config/index.cjs +4 -4
  77. package/dist/config/index.d.cts +4 -4
  78. package/dist/config/index.d.ts +4 -4
  79. package/dist/config/index.js +4 -4
  80. package/dist/config/locators/components/chat/index.cjs +1 -1
  81. package/dist/config/locators/components/chat/index.d.cts +1 -1
  82. package/dist/config/locators/components/chat/index.d.ts +1 -1
  83. package/dist/config/locators/components/chat/index.js +1 -1
  84. package/dist/config/locators/components/common/index.cjs +1 -1
  85. package/dist/config/locators/components/common/index.d.cts +1 -1
  86. package/dist/config/locators/components/common/index.d.ts +1 -1
  87. package/dist/config/locators/components/common/index.js +1 -1
  88. package/dist/config/locators/components/index.cjs +1 -1
  89. package/dist/config/locators/components/index.d.cts +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/index.cjs +4 -4
  93. package/dist/config/locators/index.d.cts +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 +15 -14
  97. package/dist/contexts/amplitudeContext/index.d.cts +1 -1
  98. package/dist/contexts/amplitudeContext/index.d.ts +1 -1
  99. package/dist/contexts/amplitudeContext/index.js +15 -14
  100. package/dist/contexts/cdnContext/index.cjs +4 -4
  101. package/dist/contexts/cdnContext/index.js +4 -4
  102. package/dist/contexts/chatContext/index.cjs +23 -23
  103. package/dist/contexts/chatContext/index.d.cts +4 -4
  104. package/dist/contexts/chatContext/index.d.ts +4 -4
  105. package/dist/contexts/chatContext/index.js +23 -23
  106. package/dist/contexts/enviveConfigContext/index.cjs +4 -4
  107. package/dist/contexts/enviveConfigContext/index.d.cts +3 -3
  108. package/dist/contexts/enviveConfigContext/index.d.ts +3 -3
  109. package/dist/contexts/enviveConfigContext/index.js +4 -4
  110. package/dist/contexts/enviveCssContext/index.cjs +15 -15
  111. package/dist/contexts/enviveCssContext/index.js +15 -15
  112. package/dist/contexts/featureFlagContext/index.cjs +6 -6
  113. package/dist/contexts/featureFlagContext/index.d.cts +3 -3
  114. package/dist/contexts/featureFlagContext/index.d.ts +3 -3
  115. package/dist/contexts/featureFlagContext/index.js +6 -6
  116. package/dist/contexts/featureFlagServiceContext/index.cjs +3 -3
  117. package/dist/contexts/featureFlagServiceContext/index.d.cts +4 -4
  118. package/dist/contexts/featureFlagServiceContext/index.d.ts +4 -4
  119. package/dist/contexts/featureFlagServiceContext/index.js +3 -3
  120. package/dist/contexts/graphqlContext/index.cjs +11 -11
  121. package/dist/contexts/graphqlContext/index.d.cts +13 -12
  122. package/dist/contexts/graphqlContext/index.d.ts +13 -12
  123. package/dist/contexts/graphqlContext/index.js +11 -11
  124. package/dist/contexts/localStorageContext/index.cjs +2 -2
  125. package/dist/contexts/localStorageContext/index.js +2 -2
  126. package/dist/contexts/newOrgConfigContext/index.cjs +14 -14
  127. package/dist/contexts/newOrgConfigContext/index.d.cts +14 -13
  128. package/dist/contexts/newOrgConfigContext/index.d.ts +14 -13
  129. package/dist/contexts/newOrgConfigContext/index.js +14 -14
  130. package/dist/contexts/searchContext/index.cjs +17 -17
  131. package/dist/contexts/searchContext/index.d.cts +1 -1
  132. package/dist/contexts/searchContext/index.d.ts +1 -1
  133. package/dist/contexts/searchContext/index.js +17 -17
  134. package/dist/contexts/sessionStorageContext/index.cjs +2 -2
  135. package/dist/contexts/sessionStorageContext/index.js +2 -2
  136. package/dist/contexts/shopifyUrlContext/index.cjs +2 -2
  137. package/dist/contexts/shopifyUrlContext/index.d.cts +3 -3
  138. package/dist/contexts/shopifyUrlContext/index.d.ts +3 -3
  139. package/dist/contexts/shopifyUrlContext/index.js +2 -2
  140. package/dist/contexts/systemSettingsContext/index.cjs +4 -4
  141. package/dist/contexts/systemSettingsContext/index.d.cts +16 -15
  142. package/dist/contexts/systemSettingsContext/index.d.ts +16 -15
  143. package/dist/contexts/systemSettingsContext/index.js +4 -4
  144. package/dist/contexts/types.cjs +1 -1
  145. package/dist/contexts/types.d.cts +3 -3
  146. package/dist/contexts/types.d.ts +3 -3
  147. package/dist/contexts/types.js +1 -1
  148. package/dist/contexts/userIdentityContext/index.cjs +18 -18
  149. package/dist/contexts/userIdentityContext/index.d.cts +1 -1
  150. package/dist/contexts/userIdentityContext/index.d.ts +1 -1
  151. package/dist/contexts/userIdentityContext/index.js +18 -18
  152. package/dist/{enviveConfig-BlIkxiAF.js → enviveConfig-DZBohDpc.js} +3 -3
  153. package/dist/{enviveConfig-B42OJ8bK.cjs → enviveConfig-Dv9-esGV.cjs} +3 -3
  154. package/dist/{enviveConfigContext-Y1ahEAMe.cjs → enviveConfigContext-D2OELZDR.cjs} +3 -3
  155. package/dist/{enviveConfigContext-1_EivtCa.js → enviveConfigContext-DrDjCems.js} +3 -3
  156. package/dist/{featureFlagServiceContext-D3Ge8GH5.cjs → featureFlagServiceContext-CJyYItqu.cjs} +3 -3
  157. package/dist/{featureFlagServiceContext-C5U0bshi.d.ts → featureFlagServiceContext-CpxlOkI9.d.ts} +2 -2
  158. package/dist/{featureFlagServiceContext-CAPrb4e_.js → featureFlagServiceContext-FBM6DdMJ.js} +3 -3
  159. package/dist/{featureFlagServiceContext-CiKWV306.d.cts → featureFlagServiceContext-p5UBwPM3.d.cts} +2 -2
  160. package/dist/{featureGates-D4Me_IZH.js → featureGates-KEwAL8p_.js} +1 -1
  161. package/dist/{featureGates-Bt_Y3kZ7.cjs → featureGates-qU_ulhpC.cjs} +1 -1
  162. package/dist/{frontendConfig-BiD1-j48.d.ts → frontendConfig-Cawh5iqv.d.ts} +6 -3
  163. package/dist/{frontendConfig-tVg0hsWZ.d.cts → frontendConfig-iZipB5FG.d.cts} +6 -3
  164. package/dist/graphql-CkxgqsXP.js +48 -0
  165. package/dist/graphql-i3dtpVTl.cjs +71 -0
  166. package/dist/{graphqlContext-Bf3E-V2T.d.cts → graphqlContext-BeyKU1Dr.d.cts} +2 -2
  167. package/dist/{graphqlContext-CDeKzb46.d.ts → graphqlContext-CXQl0hq2.d.ts} +2 -2
  168. package/dist/{graphqlContext-CpwAvnro.cjs → graphqlContext-DP8T3-Kd.cjs} +6 -6
  169. package/dist/{graphqlContext-dyWNSWNv.js → graphqlContext-czH0kIZg.js} +5 -5
  170. package/dist/hooks/AmplitudeOperations/index.cjs +15 -15
  171. package/dist/hooks/AmplitudeOperations/index.d.cts +1 -1
  172. package/dist/hooks/AmplitudeOperations/index.d.ts +1 -1
  173. package/dist/hooks/AmplitudeOperations/index.js +15 -15
  174. package/dist/hooks/AppDetails/index.cjs +14 -14
  175. package/dist/hooks/AppDetails/index.d.cts +12 -11
  176. package/dist/hooks/AppDetails/index.d.ts +12 -11
  177. package/dist/hooks/AppDetails/index.js +14 -14
  178. package/dist/hooks/CdnOperations/index.cjs +4 -4
  179. package/dist/hooks/CdnOperations/index.js +4 -4
  180. package/dist/hooks/ChatToggle/index.cjs +16 -16
  181. package/dist/hooks/ChatToggle/index.d.cts +1 -1
  182. package/dist/hooks/ChatToggle/index.d.ts +1 -1
  183. package/dist/hooks/ChatToggle/index.js +16 -16
  184. package/dist/hooks/ChatToggleAnalytics/index.cjs +16 -16
  185. package/dist/hooks/ChatToggleAnalytics/index.d.cts +1 -1
  186. package/dist/hooks/ChatToggleAnalytics/index.d.ts +1 -1
  187. package/dist/hooks/ChatToggleAnalytics/index.js +16 -16
  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 +20 -2
  191. package/dist/hooks/Debounce/index.js +18 -2
  192. package/dist/hooks/ElementObserver/index.d.cts +1 -1
  193. package/dist/hooks/ElementObserver/index.d.ts +1 -1
  194. package/dist/hooks/GrabAndScroll/index.d.cts +2 -2
  195. package/dist/hooks/GraphQLConfig/index.cjs +12 -12
  196. package/dist/hooks/GraphQLConfig/index.d.cts +13 -12
  197. package/dist/hooks/GraphQLConfig/index.d.ts +13 -12
  198. package/dist/hooks/GraphQLConfig/index.js +12 -12
  199. package/dist/hooks/IdentifyUser/index.cjs +18 -18
  200. package/dist/hooks/IdentifyUser/index.js +18 -18
  201. package/dist/hooks/ImageResolver/index.cjs +10 -10
  202. package/dist/hooks/ImageResolver/index.js +10 -10
  203. package/dist/hooks/LocalStorageOperations/index.cjs +2 -2
  204. package/dist/hooks/LocalStorageOperations/index.js +2 -2
  205. package/dist/hooks/MessageFilter/index.cjs +8 -8
  206. package/dist/hooks/MessageFilter/index.d.cts +12 -11
  207. package/dist/hooks/MessageFilter/index.d.ts +12 -11
  208. package/dist/hooks/MessageFilter/index.js +8 -8
  209. package/dist/hooks/NewOrgConfig/index.cjs +15 -15
  210. package/dist/hooks/NewOrgConfig/index.d.cts +14 -13
  211. package/dist/hooks/NewOrgConfig/index.d.ts +14 -13
  212. package/dist/hooks/NewOrgConfig/index.js +15 -15
  213. package/dist/hooks/Search/index.cjs +1459 -150
  214. package/dist/hooks/Search/index.d.cts +21 -17
  215. package/dist/hooks/Search/index.d.ts +21 -17
  216. package/dist/hooks/Search/index.js +1460 -151
  217. package/dist/hooks/SearchOperations/index.cjs +17 -17
  218. package/dist/hooks/SearchOperations/index.d.cts +1 -1
  219. package/dist/hooks/SearchOperations/index.d.ts +1 -1
  220. package/dist/hooks/SearchOperations/index.js +17 -17
  221. package/dist/hooks/SessionStorageOperations/index.cjs +2 -2
  222. package/dist/hooks/SessionStorageOperations/index.js +2 -2
  223. package/dist/hooks/ShopifyUrlOperations/index.cjs +2 -2
  224. package/dist/hooks/ShopifyUrlOperations/index.d.cts +5 -5
  225. package/dist/hooks/ShopifyUrlOperations/index.d.ts +5 -5
  226. package/dist/hooks/ShopifyUrlOperations/index.js +2 -2
  227. package/dist/hooks/SystemSettingsContext/index.cjs +5 -5
  228. package/dist/hooks/SystemSettingsContext/index.d.cts +14 -13
  229. package/dist/hooks/SystemSettingsContext/index.d.ts +14 -13
  230. package/dist/hooks/SystemSettingsContext/index.js +5 -5
  231. package/dist/hooks/TrackComponentVisibleEvent/index.cjs +15 -15
  232. package/dist/hooks/TrackComponentVisibleEvent/index.d.cts +2 -2
  233. package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +2 -2
  234. package/dist/hooks/TrackComponentVisibleEvent/index.js +15 -15
  235. package/dist/hooks/UpdateAnalyticsProps/index.cjs +14 -14
  236. package/dist/hooks/UpdateAnalyticsProps/index.js +14 -14
  237. package/dist/hooks/utils.d.cts +12 -11
  238. package/dist/hooks/utils.d.ts +12 -11
  239. package/dist/{index-B6xpW8RG.d.ts → index--9_c4tze.d.ts} +1 -1
  240. package/dist/index-BEpDGqnz.d.cts +41 -0
  241. package/dist/{index-D31m6bPU.d.ts → index-BKvFVPUX.d.ts} +1 -1
  242. package/dist/{index-VwfWqyR_.d.ts → index-BNHIIgYk.d.ts} +1 -1
  243. package/dist/{index-Bq39XSmY.d.cts → index-BSd8767K.d.cts} +34 -34
  244. package/dist/index-BUDrAxnl.d.ts +673 -0
  245. package/dist/{index-DzbkQtaK.d.cts → index-CCboEuTO.d.cts} +1 -1
  246. package/dist/{index-FQjyuD3D.d.cts → index-COXkY78t.d.cts} +1 -1
  247. package/dist/{index-wFHfdr6p.d.ts → index-CUO68KG3.d.ts} +34 -34
  248. package/dist/{index--uHjE7L8.d.ts → index-D7htGSQC.d.ts} +1 -1
  249. package/dist/index-DM_5fh8c.d.ts +101 -0
  250. package/dist/index-DU7uw0ba.d.cts +101 -0
  251. package/dist/{index-Da1s8h5C.d.cts → index-DZtnHhlr.d.cts} +1 -1
  252. package/dist/{index-DSRs6N6J.d.ts → index-Dtw-hJdt.d.ts} +1 -1
  253. package/dist/index-Dy3TTIOm.d.cts +673 -0
  254. package/dist/index-ErVcwUnR.d.ts +41 -0
  255. package/dist/{index-Cyq5HiC0.d.cts → index-OkKEOL6H.d.cts} +1 -1
  256. package/dist/{index-9NE86em3.d.cts → index-hAqp0oYb.d.cts} +1 -1
  257. package/dist/interceptors/index.d.cts +13 -12
  258. package/dist/interceptors/index.d.ts +13 -12
  259. package/dist/interceptors/types.d.cts +12 -11
  260. package/dist/interceptors/types.d.ts +12 -11
  261. package/dist/{localStorageContext-DAOJ4be4.js → localStorageContext-BPZ82q-G.js} +2 -2
  262. package/dist/{localStorageContext-C5giszHn.cjs → localStorageContext-NRP-CdmF.cjs} +2 -2
  263. package/dist/{locators-C2fWd-74.js → locators-BMQGmGLq.js} +1 -1
  264. package/dist/{locators-Cx3q6Z_h.cjs → locators-DxYdak1F.cjs} +1 -1
  265. package/dist/{logger-0D_8Ip2L.cjs → logger-TBIl4uIH.cjs} +1 -1
  266. package/dist/{logger-Co0IA3k5.js → logger-W3lqg-4b.js} +1 -1
  267. package/dist/models-CWOgrLCm.js +1284 -0
  268. package/dist/models-DqdLOi2I.cjs +1519 -0
  269. package/dist/{newOrgConfigContext-BMvcqPzD.cjs → newOrgConfigContext-Bet9CgKP.cjs} +4 -4
  270. package/dist/{newOrgConfigContext-6mlrvr1w.js → newOrgConfigContext-Bi_dBNe5.js} +4 -4
  271. package/dist/{newOrgConfigContext-DOdUxlOE.d.cts → newOrgConfigContext-CJI3tsVV.d.cts} +2 -2
  272. package/dist/{newOrgConfigContext-BVyJExeW.d.ts → newOrgConfigContext-I2qceBB4.d.ts} +2 -2
  273. package/dist/{nodeSelector-DYhDUi7v.d.ts → nodeSelector-B5NfnUHv.d.ts} +1 -1
  274. package/dist/{nodeSelector-B3bPtEjX.d.cts → nodeSelector-vKB44CDB.d.cts} +1 -1
  275. package/dist/responseGenerics-D9bS-Dd6.d.ts +148 -0
  276. package/dist/{index-Cx9e-fRi.d.ts → responseGenerics-DWLV09cQ.d.cts} +4 -40
  277. package/dist/{search-y-ioX5Mz.d.cts → search-6RrxBXD6.d.cts} +1 -1
  278. package/dist/{search-D-UfTjB7.cjs → search-Csh2n66W.cjs} +2 -2
  279. package/dist/{search-yawhMv22.js → search-DkiqkogN.js} +2 -2
  280. package/dist/{search-B1OtJe8Z.d.ts → search-DrJiCT7d.d.ts} +1 -1
  281. package/dist/{search-filter-types-BxaNSLs_.d.cts → search-filter-types-BItKtezf.d.cts} +1 -1
  282. package/dist/{search-filter-types-OI9zH3E_.d.ts → search-filter-types-CGFhksO3.d.ts} +1 -1
  283. package/dist/{searchContext-CiqOqTJL.js → searchContext-BmgoAFMF.js} +6 -6
  284. package/dist/{searchContext-CFuwIIW-.cjs → searchContext-DksJfC1s.cjs} +6 -6
  285. package/dist/{sessionStorageContext-BmCW091C.cjs → sessionStorageContext-B6FsNKjj.cjs} +2 -2
  286. package/dist/{sessionStorageContext-CNxkqJi1.js → sessionStorageContext-CLYCm83p.js} +2 -2
  287. package/dist/{shopifyUrlContext-BXbI0PIG.js → shopifyUrlContext-C-PkSgNC.js} +2 -2
  288. package/dist/{shopifyUrlContext-aZMwCfbJ.cjs → shopifyUrlContext-ZOcARiMR.cjs} +2 -2
  289. package/dist/{spiffyWidgets-CvEJIuJx.d.ts → spiffyWidgets-CR6F7FRE.d.ts} +1 -1
  290. package/dist/{spiffyWidgets-BuS00VaQ.d.cts → spiffyWidgets-eNbU1gMc.d.cts} +1 -1
  291. package/dist/{systemSettingsContext-kz6yyiFF.js → systemSettingsContext-DF0jSq9m.js} +2 -2
  292. package/dist/{systemSettingsContext-SozpUezn.cjs → systemSettingsContext-dmE1v6w8.cjs} +2 -2
  293. package/dist/{test-types-DRhqHXw-.d.ts → test-types-BEml_bm3.d.ts} +1 -1
  294. package/dist/{test-types-ThQiO_cc.d.cts → test-types-Dsu8RJZu.d.cts} +1 -1
  295. package/dist/types/index.d.cts +2 -2
  296. package/dist/types/index.d.ts +2 -2
  297. package/dist/{types-r0Z6CwyF.d.ts → types-4LQ7LUCk.d.ts} +2 -2
  298. package/dist/types-BegmH0S1.d.ts +60 -0
  299. package/dist/types-BuvXXGxE.cjs +1 -1
  300. package/dist/types-CtUb63bt.js +76 -0
  301. package/dist/{types-zQGBI-Yo.d.cts → types-DFsSqmWx.d.cts} +2 -2
  302. package/dist/types-DWorwfS-.d.cts +60 -0
  303. package/dist/types-DXnG1tV0.js +1 -1
  304. package/dist/types-UUvB6h05.cjs +106 -0
  305. package/dist/types.d.cts +3 -3
  306. package/dist/types.d.ts +3 -3
  307. package/dist/{unsupportedProductExceptions-B4f9aLjr.cjs → unsupportedProductExceptions-DGENUnEA.cjs} +1 -1
  308. package/dist/{unsupportedProductExceptions-DlmraJm8.js → unsupportedProductExceptions-uQuuelOs.js} +1 -1
  309. package/dist/{urlsParser-DhcEZLc_.cjs → urlsParser-COzMdJaX.cjs} +1 -1
  310. package/dist/{urlsParser-DLCzibqU.js → urlsParser-DxjoLj98.js} +1 -1
  311. package/dist/{useAmplitudeOperations-D0nvIYlt.cjs → useAmplitudeOperations-Bo6YNbTV.cjs} +2 -2
  312. package/dist/{useAmplitudeOperations-Dhks3PgF.js → useAmplitudeOperations-zIRSqmMW.js} +2 -2
  313. package/dist/{useAppDetails-qyaQIbWE.js → useAppDetails-B584gkCs.js} +4 -4
  314. package/dist/{useAppDetails-B9sGmpJ3.cjs → useAppDetails-DczgqeLG.cjs} +4 -4
  315. package/dist/{useGraphQLConfig-BccQUaeW.js → useGraphQLConfig-7UxACM4n.js} +2 -2
  316. package/dist/{useGraphQLConfig-CgKEfVYc.cjs → useGraphQLConfig-D_rF2Sun.cjs} +2 -2
  317. package/dist/{userIdentityContext-Cb6lLv6t.cjs → userIdentityContext-BqbNu7xu.cjs} +5 -5
  318. package/dist/{userIdentityContext-O_DHHPTN.js → userIdentityContext-BxFH9FNQ.js} +5 -5
  319. package/dist/{userIdentityContext-BKLedN4R.d.ts → userIdentityContext-C6kApbuk.d.ts} +1 -1
  320. package/dist/{userIdentityContext-D2oFVFzo.d.cts → userIdentityContext-kU1PIo8K.d.cts} +1 -1
  321. package/dist/{utils-BhyZiDrE.d.ts → utils-BRkGP1eb.d.ts} +1 -1
  322. package/dist/{utils-DFPt3FSw.js → utils-C1ErYSoW.js} +4 -4
  323. package/dist/{utils-B7PAzB_M.d.cts → utils-CBD4g2Nc.d.cts} +4 -4
  324. package/dist/{utils-C6imnLBo.cjs → utils-CDw74BCO.cjs} +1 -1
  325. package/dist/{utils-B3x_9JTY.d.cts → utils-DCrwX6FT.d.cts} +1 -1
  326. package/dist/{utils-C4ci_t0-.js → utils-DIvMgPe8.js} +1 -1
  327. package/dist/{utils-B1v0iXs3.d.ts → utils-QKFAbPT6.d.ts} +4 -4
  328. package/dist/{utils-Cazq8Q3q.cjs → utils-mqfncrhI.cjs} +4 -4
  329. package/package.json +5 -1
  330. package/src/application/commerce-api.ts +2 -0
  331. package/src/application/models/graphql/index.ts +1 -0
  332. package/src/atoms/search/productRetrievalAPI.ts +70 -0
  333. package/src/atoms/search/productRetrievalAdapter.ts +25 -0
  334. package/src/atoms/search/types.ts +13 -0
  335. package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +790 -0
  336. package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +775 -0
  337. package/src/contexts/newOrgConfigContext/__tests__/newOrgConfigContext.test.tsx +495 -0
  338. package/src/contexts/searchContext/__tests__/searchContext.test.tsx +806 -0
  339. package/src/contexts/systemSettingsContext/__tests__/systemSettingsContext.test.tsx +506 -0
  340. package/src/contexts/types.ts +3 -0
  341. package/src/hooks/Search/useRecommendedProducts.ts +48 -0
  342. package/src/hooks/Search/useSearch.tsx +89 -182
  343. package/src/hooks/Search/useSearchInput.ts +263 -0
  344. package/src/types/FilterAttribute.ts +35 -0
  345. package/dist/graphql-OkhsP4ir.js +0 -36
  346. package/dist/graphql-l4dQrsA6.cjs +0 -53
  347. package/dist/index-Bmub8e38.d.cts +0 -98
  348. package/dist/index-CG3P8xE1.d.cts +0 -676
  349. package/dist/index-CiWEYzXl.d.cts +0 -184
  350. package/dist/index-D2VaMPA3.d.ts +0 -98
  351. package/dist/index-fUsw_Mea.d.ts +0 -676
  352. package/dist/models-CkJ-wg9Q.cjs +0 -1537
  353. package/dist/models-UHOY0ak5.js +0 -1296
  354. package/dist/types-BwNrLPSZ.cjs +0 -106
  355. package/dist/types-CKMMb_gX.d.cts +0 -51
  356. package/dist/types-D3uOF0Oy.js +0 -76
  357. package/dist/types-DZPuBnHe.d.ts +0 -51
  358. package/dist/useDebounce-BZDtUAQ8.cjs +0 -26
  359. package/dist/useDebounce-ueblXZI-.js +0 -19
  360. /package/dist/{index-RcVcRKH7.d.cts → index-A0HvA68Y.d.cts} +0 -0
  361. /package/dist/{index-mHc9_XC3.d.ts → index-DNVvRcKu.d.ts} +0 -0
@@ -1,44 +1,1428 @@
1
- import "../../types-D3uOF0Oy.js";
1
+ import "../../types-CtUb63bt.js";
2
2
  import "../../events-DyUix-Bn.js";
3
3
  import { SearchResultsState, getSearchResultsState } from "../../utils-D_kATUj6.js";
4
- import { logger_default } from "../../logger-Co0IA3k5.js";
5
- import { SpiffyWidgets } from "../../models-UHOY0ak5.js";
6
- import "../../featureGates-D4Me_IZH.js";
7
- import "../../urlsParser-DLCzibqU.js";
8
- import "../../graphql-OkhsP4ir.js";
9
- import "../../utils-C4ci_t0-.js";
10
- import "../../api-bHEYmSiT.js";
4
+ import { SpiffyWidgets } from "../../models-CWOgrLCm.js";
5
+ import { FeatureGates } from "../../featureGates-KEwAL8p_.js";
6
+ import "../../urlsParser-DxjoLj98.js";
7
+ import "../../graphql-CkxgqsXP.js";
8
+ import "../../utils-DIvMgPe8.js";
9
+ import "../../api-BWSsazAG.js";
10
+ import "../../logger-W3lqg-4b.js";
11
11
  import "../../utilityTypes-B2KuRn37.js";
12
12
  import "../../variantInfo-BfKlkaWU.js";
13
- import "../../localStorageContext-DAOJ4be4.js";
14
- import { orgShortNameAtom } from "../../enviveConfig-BlIkxiAF.js";
13
+ import "../../localStorageContext-BPZ82q-G.js";
14
+ import { orgShortNameAtom } from "../../enviveConfig-DZBohDpc.js";
15
15
  import "../../orgAnalyticsConfig-CpBmga08.js";
16
16
  import "../../atomStore-DEcDhiLp.js";
17
- import "../../app-Aqkm_SlS.js";
18
- import "../../enviveConfigContext-1_EivtCa.js";
19
- import "../../featureFlagServiceContext-CAPrb4e_.js";
20
- import { SpiffyMetricsEventName, useAmplitude } from "../../amplitudeContext-DOqL2Vn8.js";
21
- import "../../chatState-BXBN-12W.js";
17
+ import "../../app-CflxT_xI.js";
18
+ import "../../enviveConfigContext-DrDjCems.js";
19
+ import { useFeatureFlagService } from "../../featureFlagServiceContext-FBM6DdMJ.js";
20
+ import { SpiffyMetricsEventName, useAmplitude } from "../../amplitudeContext-DCk6Va-j.js";
21
+ import "../../chatState-CXA1vF16.js";
22
22
  import "../../graphqlConfig-CZGjJ8hP.js";
23
- import "../../chat-U1IgKNij.js";
23
+ import { amplitudeTrackEventAtom } from "../../chat-BjhQCyW_.js";
24
24
  import { autocompleteStateAtom, isFilterOpenAtom } from "../../globalSearch-BQEX-2Ml.js";
25
25
  import "../../org-h32_LSEb.js";
26
26
  import "../../newOrgConfigAtom-DEUj6H-p.js";
27
27
  import { formatFilterDisplayName } from "../../utils-D82gfbgU.js";
28
- import "../../chatSearch-Bb2SMr9X.js";
28
+ import "../../chatSearch-BsYlFvpv.js";
29
29
  import { ProductSorting } from "../../types-DXnG1tV0.js";
30
30
  import "../../searchServiceAdapter-Db6jEcJs.js";
31
- import { addSearchFilterAtom, clearSearchFiltersAtom, createFilterOption, filteredSearchProductsAtom, performSearchAtom, removeSearchFilterAtom, searchAtom, searchFiltersAtom, searchParamsAtom, searchProductSortingAtom, searchSelectedFiltersAtom } from "../../search-yawhMv22.js";
32
- import "../../graphqlContext-dyWNSWNv.js";
33
- import "../../useGraphQLConfig-BccQUaeW.js";
34
- import "../../newOrgConfigContext-6mlrvr1w.js";
35
- import { useNewOrgConfig } from "../../NewOrgConfig-BfrGpiGk.js";
36
- import { useDebounce } from "../../useDebounce-ueblXZI-.js";
31
+ import { addSearchFilterAtom, clearSearchFiltersAtom, createFilterOption, filteredSearchProductsAtom, performSearchAtom, removeSearchFilterAtom, searchAtom, searchFiltersAtom, searchParamsAtom, searchProductSortingAtom, searchSelectedFiltersAtom } from "../../search-DkiqkogN.js";
32
+ import "../../amplitudeContext-BItT9HmT.js";
33
+ import "../../graphqlContext-czH0kIZg.js";
34
+ import "../../useGraphQLConfig-7UxACM4n.js";
35
+ import "../../newOrgConfigContext-Bi_dBNe5.js";
36
+ import { useNewOrgConfig } from "../../NewOrgConfig-yptI2imS.js";
37
37
  import "../../useIntersection-CZSEBUbv.js";
38
- import { useTrackComponentVisibleEvent } from "../../TrackComponentVisibleEvent-DwfGqNTx.js";
38
+ import { useTrackComponentVisibleEvent } from "../../TrackComponentVisibleEvent-CXhKOwKQ.js";
39
39
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
40
- import { useAtom, useAtomValue, useSetAtom } from "jotai";
40
+ import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
41
41
 
42
+ //#region node_modules/fuse.js/dist/fuse.mjs
43
+ /**
44
+ * Fuse.js v7.1.0 - Lightweight fuzzy-search (http://fusejs.io)
45
+ *
46
+ * Copyright (c) 2025 Kiro Risk (http://kiro.me)
47
+ * All Rights Reserved. Apache Software License 2.0
48
+ *
49
+ * http://www.apache.org/licenses/LICENSE-2.0
50
+ */
51
+ function isArray(value) {
52
+ return !Array.isArray ? getTag(value) === "[object Array]" : Array.isArray(value);
53
+ }
54
+ const INFINITY = Infinity;
55
+ function baseToString(value) {
56
+ if (typeof value == "string") return value;
57
+ let result = value + "";
58
+ return result == "0" && 1 / value == -INFINITY ? "-0" : result;
59
+ }
60
+ function toString(value) {
61
+ return value == null ? "" : baseToString(value);
62
+ }
63
+ function isString(value) {
64
+ return typeof value === "string";
65
+ }
66
+ function isNumber(value) {
67
+ return typeof value === "number";
68
+ }
69
+ function isBoolean(value) {
70
+ return value === true || value === false || isObjectLike(value) && getTag(value) == "[object Boolean]";
71
+ }
72
+ function isObject(value) {
73
+ return typeof value === "object";
74
+ }
75
+ function isObjectLike(value) {
76
+ return isObject(value) && value !== null;
77
+ }
78
+ function isDefined(value) {
79
+ return value !== void 0 && value !== null;
80
+ }
81
+ function isBlank(value) {
82
+ return !value.trim().length;
83
+ }
84
+ function getTag(value) {
85
+ return value == null ? value === void 0 ? "[object Undefined]" : "[object Null]" : Object.prototype.toString.call(value);
86
+ }
87
+ const INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
88
+ const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => `Invalid value for key ${key}`;
89
+ const PATTERN_LENGTH_TOO_LARGE = (max) => `Pattern length exceeds max of ${max}.`;
90
+ const MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;
91
+ const INVALID_KEY_WEIGHT_VALUE = (key) => `Property 'weight' in key '${key}' must be a positive integer`;
92
+ const hasOwn = Object.prototype.hasOwnProperty;
93
+ var KeyStore = class {
94
+ constructor(keys) {
95
+ this._keys = [];
96
+ this._keyMap = {};
97
+ let totalWeight = 0;
98
+ keys.forEach((key) => {
99
+ let obj = createKey(key);
100
+ this._keys.push(obj);
101
+ this._keyMap[obj.id] = obj;
102
+ totalWeight += obj.weight;
103
+ });
104
+ this._keys.forEach((key) => {
105
+ key.weight /= totalWeight;
106
+ });
107
+ }
108
+ get(keyId) {
109
+ return this._keyMap[keyId];
110
+ }
111
+ keys() {
112
+ return this._keys;
113
+ }
114
+ toJSON() {
115
+ return JSON.stringify(this._keys);
116
+ }
117
+ };
118
+ function createKey(key) {
119
+ let path = null;
120
+ let id = null;
121
+ let src = null;
122
+ let weight = 1;
123
+ let getFn = null;
124
+ if (isString(key) || isArray(key)) {
125
+ src = key;
126
+ path = createKeyPath(key);
127
+ id = createKeyId(key);
128
+ } else {
129
+ if (!hasOwn.call(key, "name")) throw new Error(MISSING_KEY_PROPERTY("name"));
130
+ const name = key.name;
131
+ src = name;
132
+ if (hasOwn.call(key, "weight")) {
133
+ weight = key.weight;
134
+ if (weight <= 0) throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
135
+ }
136
+ path = createKeyPath(name);
137
+ id = createKeyId(name);
138
+ getFn = key.getFn;
139
+ }
140
+ return {
141
+ path,
142
+ id,
143
+ weight,
144
+ src,
145
+ getFn
146
+ };
147
+ }
148
+ function createKeyPath(key) {
149
+ return isArray(key) ? key : key.split(".");
150
+ }
151
+ function createKeyId(key) {
152
+ return isArray(key) ? key.join(".") : key;
153
+ }
154
+ function get(obj, path) {
155
+ let list = [];
156
+ let arr = false;
157
+ const deepGet = (obj$1, path$1, index) => {
158
+ if (!isDefined(obj$1)) return;
159
+ if (!path$1[index]) list.push(obj$1);
160
+ else {
161
+ let key = path$1[index];
162
+ const value = obj$1[key];
163
+ if (!isDefined(value)) return;
164
+ if (index === path$1.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) list.push(toString(value));
165
+ else if (isArray(value)) {
166
+ arr = true;
167
+ for (let i = 0, len = value.length; i < len; i += 1) deepGet(value[i], path$1, index + 1);
168
+ } else if (path$1.length) deepGet(value, path$1, index + 1);
169
+ }
170
+ };
171
+ deepGet(obj, isString(path) ? path.split(".") : path, 0);
172
+ return arr ? list : list[0];
173
+ }
174
+ const MatchOptions = {
175
+ includeMatches: false,
176
+ findAllMatches: false,
177
+ minMatchCharLength: 1
178
+ };
179
+ const BasicOptions = {
180
+ isCaseSensitive: false,
181
+ ignoreDiacritics: false,
182
+ includeScore: false,
183
+ keys: [],
184
+ shouldSort: true,
185
+ sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1
186
+ };
187
+ const FuzzyOptions = {
188
+ location: 0,
189
+ threshold: .6,
190
+ distance: 100
191
+ };
192
+ const AdvancedOptions = {
193
+ useExtendedSearch: false,
194
+ getFn: get,
195
+ ignoreLocation: false,
196
+ ignoreFieldNorm: false,
197
+ fieldNormWeight: 1
198
+ };
199
+ var Config = {
200
+ ...BasicOptions,
201
+ ...MatchOptions,
202
+ ...FuzzyOptions,
203
+ ...AdvancedOptions
204
+ };
205
+ const SPACE = /[^ ]+/g;
206
+ function norm(weight = 1, mantissa = 3) {
207
+ const cache = /* @__PURE__ */ new Map();
208
+ const m = Math.pow(10, mantissa);
209
+ return {
210
+ get(value) {
211
+ const numTokens = value.match(SPACE).length;
212
+ if (cache.has(numTokens)) return cache.get(numTokens);
213
+ const norm$1 = 1 / Math.pow(numTokens, .5 * weight);
214
+ const n = parseFloat(Math.round(norm$1 * m) / m);
215
+ cache.set(numTokens, n);
216
+ return n;
217
+ },
218
+ clear() {
219
+ cache.clear();
220
+ }
221
+ };
222
+ }
223
+ var FuseIndex = class {
224
+ constructor({ getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
225
+ this.norm = norm(fieldNormWeight, 3);
226
+ this.getFn = getFn;
227
+ this.isCreated = false;
228
+ this.setIndexRecords();
229
+ }
230
+ setSources(docs = []) {
231
+ this.docs = docs;
232
+ }
233
+ setIndexRecords(records = []) {
234
+ this.records = records;
235
+ }
236
+ setKeys(keys = []) {
237
+ this.keys = keys;
238
+ this._keysMap = {};
239
+ keys.forEach((key, idx) => {
240
+ this._keysMap[key.id] = idx;
241
+ });
242
+ }
243
+ create() {
244
+ if (this.isCreated || !this.docs.length) return;
245
+ this.isCreated = true;
246
+ if (isString(this.docs[0])) this.docs.forEach((doc, docIndex) => {
247
+ this._addString(doc, docIndex);
248
+ });
249
+ else this.docs.forEach((doc, docIndex) => {
250
+ this._addObject(doc, docIndex);
251
+ });
252
+ this.norm.clear();
253
+ }
254
+ add(doc) {
255
+ const idx = this.size();
256
+ if (isString(doc)) this._addString(doc, idx);
257
+ else this._addObject(doc, idx);
258
+ }
259
+ removeAt(idx) {
260
+ this.records.splice(idx, 1);
261
+ for (let i = idx, len = this.size(); i < len; i += 1) this.records[i].i -= 1;
262
+ }
263
+ getValueForItemAtKeyId(item, keyId) {
264
+ return item[this._keysMap[keyId]];
265
+ }
266
+ size() {
267
+ return this.records.length;
268
+ }
269
+ _addString(doc, docIndex) {
270
+ if (!isDefined(doc) || isBlank(doc)) return;
271
+ let record = {
272
+ v: doc,
273
+ i: docIndex,
274
+ n: this.norm.get(doc)
275
+ };
276
+ this.records.push(record);
277
+ }
278
+ _addObject(doc, docIndex) {
279
+ let record = {
280
+ i: docIndex,
281
+ $: {}
282
+ };
283
+ this.keys.forEach((key, keyIndex) => {
284
+ let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
285
+ if (!isDefined(value)) return;
286
+ if (isArray(value)) {
287
+ let subRecords = [];
288
+ const stack = [{
289
+ nestedArrIndex: -1,
290
+ value
291
+ }];
292
+ while (stack.length) {
293
+ const { nestedArrIndex, value: value$1 } = stack.pop();
294
+ if (!isDefined(value$1)) continue;
295
+ if (isString(value$1) && !isBlank(value$1)) {
296
+ let subRecord = {
297
+ v: value$1,
298
+ i: nestedArrIndex,
299
+ n: this.norm.get(value$1)
300
+ };
301
+ subRecords.push(subRecord);
302
+ } else if (isArray(value$1)) value$1.forEach((item, k) => {
303
+ stack.push({
304
+ nestedArrIndex: k,
305
+ value: item
306
+ });
307
+ });
308
+ }
309
+ record.$[keyIndex] = subRecords;
310
+ } else if (isString(value) && !isBlank(value)) {
311
+ let subRecord = {
312
+ v: value,
313
+ n: this.norm.get(value)
314
+ };
315
+ record.$[keyIndex] = subRecord;
316
+ }
317
+ });
318
+ this.records.push(record);
319
+ }
320
+ toJSON() {
321
+ return {
322
+ keys: this.keys,
323
+ records: this.records
324
+ };
325
+ }
326
+ };
327
+ function createIndex(keys, docs, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
328
+ const myIndex = new FuseIndex({
329
+ getFn,
330
+ fieldNormWeight
331
+ });
332
+ myIndex.setKeys(keys.map(createKey));
333
+ myIndex.setSources(docs);
334
+ myIndex.create();
335
+ return myIndex;
336
+ }
337
+ function parseIndex(data, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
338
+ const { keys, records } = data;
339
+ const myIndex = new FuseIndex({
340
+ getFn,
341
+ fieldNormWeight
342
+ });
343
+ myIndex.setKeys(keys);
344
+ myIndex.setIndexRecords(records);
345
+ return myIndex;
346
+ }
347
+ function computeScore$1(pattern, { errors = 0, currentLocation = 0, expectedLocation = 0, distance = Config.distance, ignoreLocation = Config.ignoreLocation } = {}) {
348
+ const accuracy = errors / pattern.length;
349
+ if (ignoreLocation) return accuracy;
350
+ const proximity = Math.abs(expectedLocation - currentLocation);
351
+ if (!distance) return proximity ? 1 : accuracy;
352
+ return accuracy + proximity / distance;
353
+ }
354
+ function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
355
+ let indices = [];
356
+ let start = -1;
357
+ let end = -1;
358
+ let i = 0;
359
+ for (let len = matchmask.length; i < len; i += 1) {
360
+ let match = matchmask[i];
361
+ if (match && start === -1) start = i;
362
+ else if (!match && start !== -1) {
363
+ end = i - 1;
364
+ if (end - start + 1 >= minMatchCharLength) indices.push([start, end]);
365
+ start = -1;
366
+ }
367
+ }
368
+ if (matchmask[i - 1] && i - start >= minMatchCharLength) indices.push([start, i - 1]);
369
+ return indices;
370
+ }
371
+ const MAX_BITS = 32;
372
+ function search(text, pattern, patternAlphabet, { location = Config.location, distance = Config.distance, threshold = Config.threshold, findAllMatches = Config.findAllMatches, minMatchCharLength = Config.minMatchCharLength, includeMatches = Config.includeMatches, ignoreLocation = Config.ignoreLocation } = {}) {
373
+ if (pattern.length > MAX_BITS) throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
374
+ const patternLen = pattern.length;
375
+ const textLen = text.length;
376
+ const expectedLocation = Math.max(0, Math.min(location, textLen));
377
+ let currentThreshold = threshold;
378
+ let bestLocation = expectedLocation;
379
+ const computeMatches = minMatchCharLength > 1 || includeMatches;
380
+ const matchMask = computeMatches ? Array(textLen) : [];
381
+ let index;
382
+ while ((index = text.indexOf(pattern, bestLocation)) > -1) {
383
+ let score = computeScore$1(pattern, {
384
+ currentLocation: index,
385
+ expectedLocation,
386
+ distance,
387
+ ignoreLocation
388
+ });
389
+ currentThreshold = Math.min(score, currentThreshold);
390
+ bestLocation = index + patternLen;
391
+ if (computeMatches) {
392
+ let i = 0;
393
+ while (i < patternLen) {
394
+ matchMask[index + i] = 1;
395
+ i += 1;
396
+ }
397
+ }
398
+ }
399
+ bestLocation = -1;
400
+ let lastBitArr = [];
401
+ let finalScore = 1;
402
+ let binMax = patternLen + textLen;
403
+ const mask = 1 << patternLen - 1;
404
+ for (let i = 0; i < patternLen; i += 1) {
405
+ let binMin = 0;
406
+ let binMid = binMax;
407
+ while (binMin < binMid) {
408
+ if (computeScore$1(pattern, {
409
+ errors: i,
410
+ currentLocation: expectedLocation + binMid,
411
+ expectedLocation,
412
+ distance,
413
+ ignoreLocation
414
+ }) <= currentThreshold) binMin = binMid;
415
+ else binMax = binMid;
416
+ binMid = Math.floor((binMax - binMin) / 2 + binMin);
417
+ }
418
+ binMax = binMid;
419
+ let start = Math.max(1, expectedLocation - binMid + 1);
420
+ let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
421
+ let bitArr = Array(finish + 2);
422
+ bitArr[finish + 1] = (1 << i) - 1;
423
+ for (let j = finish; j >= start; j -= 1) {
424
+ let currentLocation = j - 1;
425
+ let charMatch = patternAlphabet[text.charAt(currentLocation)];
426
+ if (computeMatches) matchMask[currentLocation] = +!!charMatch;
427
+ bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;
428
+ if (i) bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
429
+ if (bitArr[j] & mask) {
430
+ finalScore = computeScore$1(pattern, {
431
+ errors: i,
432
+ currentLocation,
433
+ expectedLocation,
434
+ distance,
435
+ ignoreLocation
436
+ });
437
+ if (finalScore <= currentThreshold) {
438
+ currentThreshold = finalScore;
439
+ bestLocation = currentLocation;
440
+ if (bestLocation <= expectedLocation) break;
441
+ start = Math.max(1, 2 * expectedLocation - bestLocation);
442
+ }
443
+ }
444
+ }
445
+ if (computeScore$1(pattern, {
446
+ errors: i + 1,
447
+ currentLocation: expectedLocation,
448
+ expectedLocation,
449
+ distance,
450
+ ignoreLocation
451
+ }) > currentThreshold) break;
452
+ lastBitArr = bitArr;
453
+ }
454
+ const result = {
455
+ isMatch: bestLocation >= 0,
456
+ score: Math.max(.001, finalScore)
457
+ };
458
+ if (computeMatches) {
459
+ const indices = convertMaskToIndices(matchMask, minMatchCharLength);
460
+ if (!indices.length) result.isMatch = false;
461
+ else if (includeMatches) result.indices = indices;
462
+ }
463
+ return result;
464
+ }
465
+ function createPatternAlphabet(pattern) {
466
+ let mask = {};
467
+ for (let i = 0, len = pattern.length; i < len; i += 1) {
468
+ const char = pattern.charAt(i);
469
+ mask[char] = (mask[char] || 0) | 1 << len - i - 1;
470
+ }
471
+ return mask;
472
+ }
473
+ const stripDiacritics = String.prototype.normalize ? ((str) => str.normalize("NFD").replace(/[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/g, "")) : ((str) => str);
474
+ var BitapSearch = class {
475
+ constructor(pattern, { location = Config.location, threshold = Config.threshold, distance = Config.distance, includeMatches = Config.includeMatches, findAllMatches = Config.findAllMatches, minMatchCharLength = Config.minMatchCharLength, isCaseSensitive = Config.isCaseSensitive, ignoreDiacritics = Config.ignoreDiacritics, ignoreLocation = Config.ignoreLocation } = {}) {
476
+ this.options = {
477
+ location,
478
+ threshold,
479
+ distance,
480
+ includeMatches,
481
+ findAllMatches,
482
+ minMatchCharLength,
483
+ isCaseSensitive,
484
+ ignoreDiacritics,
485
+ ignoreLocation
486
+ };
487
+ pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
488
+ pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
489
+ this.pattern = pattern;
490
+ this.chunks = [];
491
+ if (!this.pattern.length) return;
492
+ const addChunk = (pattern$1, startIndex) => {
493
+ this.chunks.push({
494
+ pattern: pattern$1,
495
+ alphabet: createPatternAlphabet(pattern$1),
496
+ startIndex
497
+ });
498
+ };
499
+ const len = this.pattern.length;
500
+ if (len > MAX_BITS) {
501
+ let i = 0;
502
+ const remainder = len % MAX_BITS;
503
+ const end = len - remainder;
504
+ while (i < end) {
505
+ addChunk(this.pattern.substr(i, MAX_BITS), i);
506
+ i += MAX_BITS;
507
+ }
508
+ if (remainder) {
509
+ const startIndex = len - MAX_BITS;
510
+ addChunk(this.pattern.substr(startIndex), startIndex);
511
+ }
512
+ } else addChunk(this.pattern, 0);
513
+ }
514
+ searchIn(text) {
515
+ const { isCaseSensitive, ignoreDiacritics, includeMatches } = this.options;
516
+ text = isCaseSensitive ? text : text.toLowerCase();
517
+ text = ignoreDiacritics ? stripDiacritics(text) : text;
518
+ if (this.pattern === text) {
519
+ let result$1 = {
520
+ isMatch: true,
521
+ score: 0
522
+ };
523
+ if (includeMatches) result$1.indices = [[0, text.length - 1]];
524
+ return result$1;
525
+ }
526
+ const { location, distance, threshold, findAllMatches, minMatchCharLength, ignoreLocation } = this.options;
527
+ let allIndices = [];
528
+ let totalScore = 0;
529
+ let hasMatches = false;
530
+ this.chunks.forEach(({ pattern, alphabet, startIndex }) => {
531
+ const { isMatch, score, indices } = search(text, pattern, alphabet, {
532
+ location: location + startIndex,
533
+ distance,
534
+ threshold,
535
+ findAllMatches,
536
+ minMatchCharLength,
537
+ includeMatches,
538
+ ignoreLocation
539
+ });
540
+ if (isMatch) hasMatches = true;
541
+ totalScore += score;
542
+ if (isMatch && indices) allIndices = [...allIndices, ...indices];
543
+ });
544
+ let result = {
545
+ isMatch: hasMatches,
546
+ score: hasMatches ? totalScore / this.chunks.length : 1
547
+ };
548
+ if (hasMatches && includeMatches) result.indices = allIndices;
549
+ return result;
550
+ }
551
+ };
552
+ var BaseMatch = class {
553
+ constructor(pattern) {
554
+ this.pattern = pattern;
555
+ }
556
+ static isMultiMatch(pattern) {
557
+ return getMatch(pattern, this.multiRegex);
558
+ }
559
+ static isSingleMatch(pattern) {
560
+ return getMatch(pattern, this.singleRegex);
561
+ }
562
+ search() {}
563
+ };
564
+ function getMatch(pattern, exp) {
565
+ const matches = pattern.match(exp);
566
+ return matches ? matches[1] : null;
567
+ }
568
+ var ExactMatch = class extends BaseMatch {
569
+ constructor(pattern) {
570
+ super(pattern);
571
+ }
572
+ static get type() {
573
+ return "exact";
574
+ }
575
+ static get multiRegex() {
576
+ return /^="(.*)"$/;
577
+ }
578
+ static get singleRegex() {
579
+ return /^=(.*)$/;
580
+ }
581
+ search(text) {
582
+ const isMatch = text === this.pattern;
583
+ return {
584
+ isMatch,
585
+ score: isMatch ? 0 : 1,
586
+ indices: [0, this.pattern.length - 1]
587
+ };
588
+ }
589
+ };
590
+ var InverseExactMatch = class extends BaseMatch {
591
+ constructor(pattern) {
592
+ super(pattern);
593
+ }
594
+ static get type() {
595
+ return "inverse-exact";
596
+ }
597
+ static get multiRegex() {
598
+ return /^!"(.*)"$/;
599
+ }
600
+ static get singleRegex() {
601
+ return /^!(.*)$/;
602
+ }
603
+ search(text) {
604
+ const isMatch = text.indexOf(this.pattern) === -1;
605
+ return {
606
+ isMatch,
607
+ score: isMatch ? 0 : 1,
608
+ indices: [0, text.length - 1]
609
+ };
610
+ }
611
+ };
612
+ var PrefixExactMatch = class extends BaseMatch {
613
+ constructor(pattern) {
614
+ super(pattern);
615
+ }
616
+ static get type() {
617
+ return "prefix-exact";
618
+ }
619
+ static get multiRegex() {
620
+ return /^\^"(.*)"$/;
621
+ }
622
+ static get singleRegex() {
623
+ return /^\^(.*)$/;
624
+ }
625
+ search(text) {
626
+ const isMatch = text.startsWith(this.pattern);
627
+ return {
628
+ isMatch,
629
+ score: isMatch ? 0 : 1,
630
+ indices: [0, this.pattern.length - 1]
631
+ };
632
+ }
633
+ };
634
+ var InversePrefixExactMatch = class extends BaseMatch {
635
+ constructor(pattern) {
636
+ super(pattern);
637
+ }
638
+ static get type() {
639
+ return "inverse-prefix-exact";
640
+ }
641
+ static get multiRegex() {
642
+ return /^!\^"(.*)"$/;
643
+ }
644
+ static get singleRegex() {
645
+ return /^!\^(.*)$/;
646
+ }
647
+ search(text) {
648
+ const isMatch = !text.startsWith(this.pattern);
649
+ return {
650
+ isMatch,
651
+ score: isMatch ? 0 : 1,
652
+ indices: [0, text.length - 1]
653
+ };
654
+ }
655
+ };
656
+ var SuffixExactMatch = class extends BaseMatch {
657
+ constructor(pattern) {
658
+ super(pattern);
659
+ }
660
+ static get type() {
661
+ return "suffix-exact";
662
+ }
663
+ static get multiRegex() {
664
+ return /^"(.*)"\$$/;
665
+ }
666
+ static get singleRegex() {
667
+ return /^(.*)\$$/;
668
+ }
669
+ search(text) {
670
+ const isMatch = text.endsWith(this.pattern);
671
+ return {
672
+ isMatch,
673
+ score: isMatch ? 0 : 1,
674
+ indices: [text.length - this.pattern.length, text.length - 1]
675
+ };
676
+ }
677
+ };
678
+ var InverseSuffixExactMatch = class extends BaseMatch {
679
+ constructor(pattern) {
680
+ super(pattern);
681
+ }
682
+ static get type() {
683
+ return "inverse-suffix-exact";
684
+ }
685
+ static get multiRegex() {
686
+ return /^!"(.*)"\$$/;
687
+ }
688
+ static get singleRegex() {
689
+ return /^!(.*)\$$/;
690
+ }
691
+ search(text) {
692
+ const isMatch = !text.endsWith(this.pattern);
693
+ return {
694
+ isMatch,
695
+ score: isMatch ? 0 : 1,
696
+ indices: [0, text.length - 1]
697
+ };
698
+ }
699
+ };
700
+ var FuzzyMatch = class extends BaseMatch {
701
+ constructor(pattern, { location = Config.location, threshold = Config.threshold, distance = Config.distance, includeMatches = Config.includeMatches, findAllMatches = Config.findAllMatches, minMatchCharLength = Config.minMatchCharLength, isCaseSensitive = Config.isCaseSensitive, ignoreDiacritics = Config.ignoreDiacritics, ignoreLocation = Config.ignoreLocation } = {}) {
702
+ super(pattern);
703
+ this._bitapSearch = new BitapSearch(pattern, {
704
+ location,
705
+ threshold,
706
+ distance,
707
+ includeMatches,
708
+ findAllMatches,
709
+ minMatchCharLength,
710
+ isCaseSensitive,
711
+ ignoreDiacritics,
712
+ ignoreLocation
713
+ });
714
+ }
715
+ static get type() {
716
+ return "fuzzy";
717
+ }
718
+ static get multiRegex() {
719
+ return /^"(.*)"$/;
720
+ }
721
+ static get singleRegex() {
722
+ return /^(.*)$/;
723
+ }
724
+ search(text) {
725
+ return this._bitapSearch.searchIn(text);
726
+ }
727
+ };
728
+ var IncludeMatch = class extends BaseMatch {
729
+ constructor(pattern) {
730
+ super(pattern);
731
+ }
732
+ static get type() {
733
+ return "include";
734
+ }
735
+ static get multiRegex() {
736
+ return /^'"(.*)"$/;
737
+ }
738
+ static get singleRegex() {
739
+ return /^'(.*)$/;
740
+ }
741
+ search(text) {
742
+ let location = 0;
743
+ let index;
744
+ const indices = [];
745
+ const patternLen = this.pattern.length;
746
+ while ((index = text.indexOf(this.pattern, location)) > -1) {
747
+ location = index + patternLen;
748
+ indices.push([index, location - 1]);
749
+ }
750
+ const isMatch = !!indices.length;
751
+ return {
752
+ isMatch,
753
+ score: isMatch ? 0 : 1,
754
+ indices
755
+ };
756
+ }
757
+ };
758
+ const searchers = [
759
+ ExactMatch,
760
+ IncludeMatch,
761
+ PrefixExactMatch,
762
+ InversePrefixExactMatch,
763
+ InverseSuffixExactMatch,
764
+ SuffixExactMatch,
765
+ InverseExactMatch,
766
+ FuzzyMatch
767
+ ];
768
+ const searchersLen = searchers.length;
769
+ const SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
770
+ const OR_TOKEN = "|";
771
+ function parseQuery(pattern, options = {}) {
772
+ return pattern.split(OR_TOKEN).map((item) => {
773
+ let query = item.trim().split(SPACE_RE).filter((item$1) => item$1 && !!item$1.trim());
774
+ let results = [];
775
+ for (let i = 0, len = query.length; i < len; i += 1) {
776
+ const queryItem = query[i];
777
+ let found = false;
778
+ let idx = -1;
779
+ while (!found && ++idx < searchersLen) {
780
+ const searcher = searchers[idx];
781
+ let token = searcher.isMultiMatch(queryItem);
782
+ if (token) {
783
+ results.push(new searcher(token, options));
784
+ found = true;
785
+ }
786
+ }
787
+ if (found) continue;
788
+ idx = -1;
789
+ while (++idx < searchersLen) {
790
+ const searcher = searchers[idx];
791
+ let token = searcher.isSingleMatch(queryItem);
792
+ if (token) {
793
+ results.push(new searcher(token, options));
794
+ break;
795
+ }
796
+ }
797
+ }
798
+ return results;
799
+ });
800
+ }
801
+ const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]);
802
+ /**
803
+ * Command-like searching
804
+ * ======================
805
+ *
806
+ * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`,
807
+ * search in a given text.
808
+ *
809
+ * Search syntax:
810
+ *
811
+ * | Token | Match type | Description |
812
+ * | ----------- | -------------------------- | -------------------------------------- |
813
+ * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` |
814
+ * | `=scheme` | exact-match | Items that are `scheme` |
815
+ * | `'python` | include-match | Items that include `python` |
816
+ * | `!ruby` | inverse-exact-match | Items that do not include `ruby` |
817
+ * | `^java` | prefix-exact-match | Items that start with `java` |
818
+ * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` |
819
+ * | `.js$` | suffix-exact-match | Items that end with `.js` |
820
+ * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` |
821
+ *
822
+ * A single pipe character acts as an OR operator. For example, the following
823
+ * query matches entries that start with `core` and end with either`go`, `rb`,
824
+ * or`py`.
825
+ *
826
+ * ```
827
+ * ^core go$ | rb$ | py$
828
+ * ```
829
+ */
830
+ var ExtendedSearch = class {
831
+ constructor(pattern, { isCaseSensitive = Config.isCaseSensitive, ignoreDiacritics = Config.ignoreDiacritics, includeMatches = Config.includeMatches, minMatchCharLength = Config.minMatchCharLength, ignoreLocation = Config.ignoreLocation, findAllMatches = Config.findAllMatches, location = Config.location, threshold = Config.threshold, distance = Config.distance } = {}) {
832
+ this.query = null;
833
+ this.options = {
834
+ isCaseSensitive,
835
+ ignoreDiacritics,
836
+ includeMatches,
837
+ minMatchCharLength,
838
+ findAllMatches,
839
+ ignoreLocation,
840
+ location,
841
+ threshold,
842
+ distance
843
+ };
844
+ pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
845
+ pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
846
+ this.pattern = pattern;
847
+ this.query = parseQuery(this.pattern, this.options);
848
+ }
849
+ static condition(_, options) {
850
+ return options.useExtendedSearch;
851
+ }
852
+ searchIn(text) {
853
+ const query = this.query;
854
+ if (!query) return {
855
+ isMatch: false,
856
+ score: 1
857
+ };
858
+ const { includeMatches, isCaseSensitive, ignoreDiacritics } = this.options;
859
+ text = isCaseSensitive ? text : text.toLowerCase();
860
+ text = ignoreDiacritics ? stripDiacritics(text) : text;
861
+ let numMatches = 0;
862
+ let allIndices = [];
863
+ let totalScore = 0;
864
+ for (let i = 0, qLen = query.length; i < qLen; i += 1) {
865
+ const searchers$1 = query[i];
866
+ allIndices.length = 0;
867
+ numMatches = 0;
868
+ for (let j = 0, pLen = searchers$1.length; j < pLen; j += 1) {
869
+ const searcher = searchers$1[j];
870
+ const { isMatch, indices, score } = searcher.search(text);
871
+ if (isMatch) {
872
+ numMatches += 1;
873
+ totalScore += score;
874
+ if (includeMatches) {
875
+ const type = searcher.constructor.type;
876
+ if (MultiMatchSet.has(type)) allIndices = [...allIndices, ...indices];
877
+ else allIndices.push(indices);
878
+ }
879
+ } else {
880
+ totalScore = 0;
881
+ numMatches = 0;
882
+ allIndices.length = 0;
883
+ break;
884
+ }
885
+ }
886
+ if (numMatches) {
887
+ let result = {
888
+ isMatch: true,
889
+ score: totalScore / numMatches
890
+ };
891
+ if (includeMatches) result.indices = allIndices;
892
+ return result;
893
+ }
894
+ }
895
+ return {
896
+ isMatch: false,
897
+ score: 1
898
+ };
899
+ }
900
+ };
901
+ const registeredSearchers = [];
902
+ function register(...args) {
903
+ registeredSearchers.push(...args);
904
+ }
905
+ function createSearcher(pattern, options) {
906
+ for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {
907
+ let searcherClass = registeredSearchers[i];
908
+ if (searcherClass.condition(pattern, options)) return new searcherClass(pattern, options);
909
+ }
910
+ return new BitapSearch(pattern, options);
911
+ }
912
+ const LogicalOperator = {
913
+ AND: "$and",
914
+ OR: "$or"
915
+ };
916
+ const KeyType = {
917
+ PATH: "$path",
918
+ PATTERN: "$val"
919
+ };
920
+ const isExpression = (query) => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);
921
+ const isPath = (query) => !!query[KeyType.PATH];
922
+ const isLeaf = (query) => !isArray(query) && isObject(query) && !isExpression(query);
923
+ const convertToExplicit = (query) => ({ [LogicalOperator.AND]: Object.keys(query).map((key) => ({ [key]: query[key] })) });
924
+ function parse(query, options, { auto = true } = {}) {
925
+ const next = (query$1) => {
926
+ let keys = Object.keys(query$1);
927
+ const isQueryPath = isPath(query$1);
928
+ if (!isQueryPath && keys.length > 1 && !isExpression(query$1)) return next(convertToExplicit(query$1));
929
+ if (isLeaf(query$1)) {
930
+ const key = isQueryPath ? query$1[KeyType.PATH] : keys[0];
931
+ const pattern = isQueryPath ? query$1[KeyType.PATTERN] : query$1[key];
932
+ if (!isString(pattern)) throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
933
+ const obj = {
934
+ keyId: createKeyId(key),
935
+ pattern
936
+ };
937
+ if (auto) obj.searcher = createSearcher(pattern, options);
938
+ return obj;
939
+ }
940
+ let node = {
941
+ children: [],
942
+ operator: keys[0]
943
+ };
944
+ keys.forEach((key) => {
945
+ const value = query$1[key];
946
+ if (isArray(value)) value.forEach((item) => {
947
+ node.children.push(next(item));
948
+ });
949
+ });
950
+ return node;
951
+ };
952
+ if (!isExpression(query)) query = convertToExplicit(query);
953
+ return next(query);
954
+ }
955
+ function computeScore(results, { ignoreFieldNorm = Config.ignoreFieldNorm }) {
956
+ results.forEach((result) => {
957
+ let totalScore = 1;
958
+ result.matches.forEach(({ key, norm: norm$1, score }) => {
959
+ const weight = key ? key.weight : null;
960
+ totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm$1));
961
+ });
962
+ result.score = totalScore;
963
+ });
964
+ }
965
+ function transformMatches(result, data) {
966
+ const matches = result.matches;
967
+ data.matches = [];
968
+ if (!isDefined(matches)) return;
969
+ matches.forEach((match) => {
970
+ if (!isDefined(match.indices) || !match.indices.length) return;
971
+ const { indices, value } = match;
972
+ let obj = {
973
+ indices,
974
+ value
975
+ };
976
+ if (match.key) obj.key = match.key.src;
977
+ if (match.idx > -1) obj.refIndex = match.idx;
978
+ data.matches.push(obj);
979
+ });
980
+ }
981
+ function transformScore(result, data) {
982
+ data.score = result.score;
983
+ }
984
+ function format(results, docs, { includeMatches = Config.includeMatches, includeScore = Config.includeScore } = {}) {
985
+ const transformers = [];
986
+ if (includeMatches) transformers.push(transformMatches);
987
+ if (includeScore) transformers.push(transformScore);
988
+ return results.map((result) => {
989
+ const { idx } = result;
990
+ const data = {
991
+ item: docs[idx],
992
+ refIndex: idx
993
+ };
994
+ if (transformers.length) transformers.forEach((transformer) => {
995
+ transformer(result, data);
996
+ });
997
+ return data;
998
+ });
999
+ }
1000
+ var Fuse = class {
1001
+ constructor(docs, options = {}, index) {
1002
+ this.options = {
1003
+ ...Config,
1004
+ ...options
1005
+ };
1006
+ if (this.options.useExtendedSearch && false);
1007
+ this._keyStore = new KeyStore(this.options.keys);
1008
+ this.setCollection(docs, index);
1009
+ }
1010
+ setCollection(docs, index) {
1011
+ this._docs = docs;
1012
+ if (index && !(index instanceof FuseIndex)) throw new Error(INCORRECT_INDEX_TYPE);
1013
+ this._myIndex = index || createIndex(this.options.keys, this._docs, {
1014
+ getFn: this.options.getFn,
1015
+ fieldNormWeight: this.options.fieldNormWeight
1016
+ });
1017
+ }
1018
+ add(doc) {
1019
+ if (!isDefined(doc)) return;
1020
+ this._docs.push(doc);
1021
+ this._myIndex.add(doc);
1022
+ }
1023
+ remove(predicate = () => false) {
1024
+ const results = [];
1025
+ for (let i = 0, len = this._docs.length; i < len; i += 1) {
1026
+ const doc = this._docs[i];
1027
+ if (predicate(doc, i)) {
1028
+ this.removeAt(i);
1029
+ i -= 1;
1030
+ len -= 1;
1031
+ results.push(doc);
1032
+ }
1033
+ }
1034
+ return results;
1035
+ }
1036
+ removeAt(idx) {
1037
+ this._docs.splice(idx, 1);
1038
+ this._myIndex.removeAt(idx);
1039
+ }
1040
+ getIndex() {
1041
+ return this._myIndex;
1042
+ }
1043
+ search(query, { limit = -1 } = {}) {
1044
+ const { includeMatches, includeScore, shouldSort, sortFn, ignoreFieldNorm } = this.options;
1045
+ let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query);
1046
+ computeScore(results, { ignoreFieldNorm });
1047
+ if (shouldSort) results.sort(sortFn);
1048
+ if (isNumber(limit) && limit > -1) results = results.slice(0, limit);
1049
+ return format(results, this._docs, {
1050
+ includeMatches,
1051
+ includeScore
1052
+ });
1053
+ }
1054
+ _searchStringList(query) {
1055
+ const searcher = createSearcher(query, this.options);
1056
+ const { records } = this._myIndex;
1057
+ const results = [];
1058
+ records.forEach(({ v: text, i: idx, n: norm$1 }) => {
1059
+ if (!isDefined(text)) return;
1060
+ const { isMatch, score, indices } = searcher.searchIn(text);
1061
+ if (isMatch) results.push({
1062
+ item: text,
1063
+ idx,
1064
+ matches: [{
1065
+ score,
1066
+ value: text,
1067
+ norm: norm$1,
1068
+ indices
1069
+ }]
1070
+ });
1071
+ });
1072
+ return results;
1073
+ }
1074
+ _searchLogical(query) {
1075
+ const expression = parse(query, this.options);
1076
+ const evaluate = (node, item, idx) => {
1077
+ if (!node.children) {
1078
+ const { keyId, searcher } = node;
1079
+ const matches = this._findMatches({
1080
+ key: this._keyStore.get(keyId),
1081
+ value: this._myIndex.getValueForItemAtKeyId(item, keyId),
1082
+ searcher
1083
+ });
1084
+ if (matches && matches.length) return [{
1085
+ idx,
1086
+ item,
1087
+ matches
1088
+ }];
1089
+ return [];
1090
+ }
1091
+ const res = [];
1092
+ for (let i = 0, len = node.children.length; i < len; i += 1) {
1093
+ const child = node.children[i];
1094
+ const result = evaluate(child, item, idx);
1095
+ if (result.length) res.push(...result);
1096
+ else if (node.operator === LogicalOperator.AND) return [];
1097
+ }
1098
+ return res;
1099
+ };
1100
+ const records = this._myIndex.records;
1101
+ const resultMap = {};
1102
+ const results = [];
1103
+ records.forEach(({ $: item, i: idx }) => {
1104
+ if (isDefined(item)) {
1105
+ let expResults = evaluate(expression, item, idx);
1106
+ if (expResults.length) {
1107
+ if (!resultMap[idx]) {
1108
+ resultMap[idx] = {
1109
+ idx,
1110
+ item,
1111
+ matches: []
1112
+ };
1113
+ results.push(resultMap[idx]);
1114
+ }
1115
+ expResults.forEach(({ matches }) => {
1116
+ resultMap[idx].matches.push(...matches);
1117
+ });
1118
+ }
1119
+ }
1120
+ });
1121
+ return results;
1122
+ }
1123
+ _searchObjectList(query) {
1124
+ const searcher = createSearcher(query, this.options);
1125
+ const { keys, records } = this._myIndex;
1126
+ const results = [];
1127
+ records.forEach(({ $: item, i: idx }) => {
1128
+ if (!isDefined(item)) return;
1129
+ let matches = [];
1130
+ keys.forEach((key, keyIndex) => {
1131
+ matches.push(...this._findMatches({
1132
+ key,
1133
+ value: item[keyIndex],
1134
+ searcher
1135
+ }));
1136
+ });
1137
+ if (matches.length) results.push({
1138
+ idx,
1139
+ item,
1140
+ matches
1141
+ });
1142
+ });
1143
+ return results;
1144
+ }
1145
+ _findMatches({ key, value, searcher }) {
1146
+ if (!isDefined(value)) return [];
1147
+ let matches = [];
1148
+ if (isArray(value)) value.forEach(({ v: text, i: idx, n: norm$1 }) => {
1149
+ if (!isDefined(text)) return;
1150
+ const { isMatch, score, indices } = searcher.searchIn(text);
1151
+ if (isMatch) matches.push({
1152
+ score,
1153
+ key,
1154
+ value: text,
1155
+ idx,
1156
+ norm: norm$1,
1157
+ indices
1158
+ });
1159
+ });
1160
+ else {
1161
+ const { v: text, n: norm$1 } = value;
1162
+ const { isMatch, score, indices } = searcher.searchIn(text);
1163
+ if (isMatch) matches.push({
1164
+ score,
1165
+ key,
1166
+ value: text,
1167
+ norm: norm$1,
1168
+ indices
1169
+ });
1170
+ }
1171
+ return matches;
1172
+ }
1173
+ };
1174
+ Fuse.version = "7.1.0";
1175
+ Fuse.createIndex = createIndex;
1176
+ Fuse.parseIndex = parseIndex;
1177
+ Fuse.config = Config;
1178
+ Fuse.parseQuery = parse;
1179
+ register(ExtendedSearch);
1180
+
1181
+ //#endregion
1182
+ //#region src/hooks/Search/useSearchInput.ts
1183
+ const useSearchInput = ({ initialSearchText = "", searchOrigin, onSearchSubmit }) => {
1184
+ const track = useAtomValue(amplitudeTrackEventAtom);
1185
+ const [searchText, setSearchText] = useState(initialSearchText);
1186
+ const [hasText, setHasText] = useState(initialSearchText.trim().length > 0);
1187
+ const [isFocused, setIsFocused] = useState(false);
1188
+ const [focusedIndex, setFocusedIndex] = useState(-1);
1189
+ const [focusedOptionId, setFocusedOptionId] = useState(void 0);
1190
+ const globalAutocompleteResults = useAtomValue(autocompleteStateAtom).results;
1191
+ const isAutocompleteEnabled = globalAutocompleteResults.length > 0;
1192
+ const isSelectingAutocomplete = useRef(false);
1193
+ const shouldShowAutocomplete = hasText && isFocused && isAutocompleteEnabled;
1194
+ const autocompleteResultsLimit = 5;
1195
+ const fuseOptions = useMemo(() => ({
1196
+ includeScore: true,
1197
+ includeMatches: true,
1198
+ threshold: .3,
1199
+ location: 0,
1200
+ distance: 4,
1201
+ minMatchCharLength: 1,
1202
+ keys: [],
1203
+ useExtendedSearch: false,
1204
+ ignoreLocation: false
1205
+ }), []);
1206
+ const fuse = useMemo(() => {
1207
+ if (!globalAutocompleteResults.length) return null;
1208
+ return new Fuse(globalAutocompleteResults, fuseOptions);
1209
+ }, [globalAutocompleteResults, fuseOptions]);
1210
+ const autocompleteResults = useMemo(() => {
1211
+ if (!isAutocompleteEnabled || !fuse) return [];
1212
+ if (!searchText.trim()) return [];
1213
+ return fuse.search(searchText).slice(0, autocompleteResultsLimit).map((result) => result.item);
1214
+ }, [
1215
+ isAutocompleteEnabled,
1216
+ fuse,
1217
+ searchText,
1218
+ autocompleteResultsLimit
1219
+ ]);
1220
+ const handleSearchInputChange = useCallback((newValue) => {
1221
+ if (newValue !== searchText) setIsFocused(true);
1222
+ if (newValue.length === 1) track?.({
1223
+ eventName: SpiffyMetricsEventName.SearchInputStarted,
1224
+ eventProps: { searchOrigin }
1225
+ });
1226
+ setSearchText(newValue);
1227
+ setHasText(newValue.trim().length > 0);
1228
+ setFocusedIndex(-1);
1229
+ setFocusedOptionId(void 0);
1230
+ }, [
1231
+ searchOrigin,
1232
+ searchText,
1233
+ track
1234
+ ]);
1235
+ const handleSearchInputFocus = useCallback(() => {
1236
+ setIsFocused(true);
1237
+ }, []);
1238
+ const handleSearchInputBlur = useCallback(() => {
1239
+ setTimeout(() => {
1240
+ if (!isSelectingAutocomplete.current) {
1241
+ setIsFocused(false);
1242
+ setFocusedIndex(-1);
1243
+ setFocusedOptionId(void 0);
1244
+ }
1245
+ }, 150);
1246
+ }, []);
1247
+ const handleSubmitSearch = useCallback(() => {
1248
+ setIsFocused(false);
1249
+ if (searchText.trim() && onSearchSubmit) {
1250
+ track?.({
1251
+ eventName: SpiffyMetricsEventName.SearchQuerySubmitted,
1252
+ eventProps: {
1253
+ searchOrigin,
1254
+ queryText: searchText.trim()
1255
+ },
1256
+ alsoSendToGoogleAnalytics: true
1257
+ });
1258
+ onSearchSubmit(searchText.trim());
1259
+ }
1260
+ }, [
1261
+ searchText,
1262
+ onSearchSubmit,
1263
+ searchOrigin,
1264
+ track
1265
+ ]);
1266
+ const handleAutocompleteSelect = useCallback((suggestion, rankPosition) => {
1267
+ isSelectingAutocomplete.current = true;
1268
+ setSearchText(suggestion);
1269
+ setHasText(suggestion.trim().length > 0);
1270
+ setIsFocused(false);
1271
+ track?.({
1272
+ eventName: SpiffyMetricsEventName.SearchInputStarted,
1273
+ eventProps: { searchOrigin }
1274
+ });
1275
+ if (onSearchSubmit) onSearchSubmit(suggestion.trim());
1276
+ setTimeout(() => {
1277
+ isSelectingAutocomplete.current = false;
1278
+ }, 100);
1279
+ }, [
1280
+ onSearchSubmit,
1281
+ searchOrigin,
1282
+ track
1283
+ ]);
1284
+ const handleKeyDown = useCallback((event) => {
1285
+ if (event.key === "ArrowDown") {
1286
+ event.preventDefault();
1287
+ const newIndex = (focusedIndex + 1) % autocompleteResults.length;
1288
+ setFocusedIndex(newIndex);
1289
+ setFocusedOptionId(`option-${newIndex}`);
1290
+ } else if (event.key === "ArrowUp") {
1291
+ event.preventDefault();
1292
+ const newIndex = (focusedIndex - 1 + autocompleteResults.length) % autocompleteResults.length;
1293
+ setFocusedIndex(newIndex);
1294
+ setFocusedOptionId(`option-${newIndex}`);
1295
+ } else if (event.key === "Enter") if (focusedIndex === -1) {
1296
+ event.preventDefault();
1297
+ handleSubmitSearch();
1298
+ } else {
1299
+ event.preventDefault();
1300
+ const suggestionText = autocompleteResults[focusedIndex];
1301
+ handleAutocompleteSelect(suggestionText, focusedIndex);
1302
+ }
1303
+ else if (event.key === "Escape") {
1304
+ event.preventDefault();
1305
+ setFocusedIndex(-1);
1306
+ setFocusedOptionId(void 0);
1307
+ }
1308
+ }, [
1309
+ autocompleteResults,
1310
+ focusedIndex,
1311
+ handleAutocompleteSelect,
1312
+ handleSubmitSearch
1313
+ ]);
1314
+ const setSearchTextUtility = useCallback((text) => {
1315
+ setSearchText(text);
1316
+ setHasText(text.trim().length > 0);
1317
+ }, []);
1318
+ const resetSearch = useCallback(() => {
1319
+ setSearchText("");
1320
+ setHasText(false);
1321
+ setIsFocused(false);
1322
+ setFocusedIndex(-1);
1323
+ setFocusedOptionId(void 0);
1324
+ }, []);
1325
+ return {
1326
+ searchText,
1327
+ hasText,
1328
+ isFocused,
1329
+ focusedIndex,
1330
+ focusedOptionId,
1331
+ autocompleteResults,
1332
+ shouldShowAutocomplete,
1333
+ handleSearchInputChange,
1334
+ handleSearchInputFocus,
1335
+ handleSearchInputBlur,
1336
+ handleKeyDown,
1337
+ handleAutocompleteSelect,
1338
+ handleSubmitSearch,
1339
+ setSearchText: setSearchTextUtility,
1340
+ resetSearch
1341
+ };
1342
+ };
1343
+
1344
+ //#endregion
1345
+ //#region src/atoms/search/productRetrievalAdapter.ts
1346
+ let productRetrievalFunction = null;
1347
+ const getProductRetrievalFunction = () => {
1348
+ if (!productRetrievalFunction) throw new Error("Product retrieval function not initialized. Make sure ProductRetrievalProvider is mounted.");
1349
+ return productRetrievalFunction;
1350
+ };
1351
+
1352
+ //#endregion
1353
+ //#region src/atoms/search/productRetrievalAPI.ts
1354
+ const productRetrievalAtom = atom({
1355
+ data: null,
1356
+ loading: false,
1357
+ error: null,
1358
+ lastProductIds: null
1359
+ });
1360
+ const performProductRetrievalAtom = atom(null, async (get$1, set, params) => {
1361
+ if (get$1(productRetrievalAtom).loading) return;
1362
+ set(productRetrievalAtom, {
1363
+ data: null,
1364
+ loading: true,
1365
+ error: null,
1366
+ lastProductIds: params.productIds
1367
+ });
1368
+ try {
1369
+ const result = await getProductRetrievalFunction()(params);
1370
+ set(productRetrievalAtom, {
1371
+ data: result,
1372
+ loading: false,
1373
+ error: null,
1374
+ lastProductIds: params.productIds
1375
+ });
1376
+ } catch (error) {
1377
+ const errorMessage = error instanceof Error ? error.message : "An unknown error occurred";
1378
+ set(productRetrievalAtom, {
1379
+ data: null,
1380
+ loading: false,
1381
+ error: errorMessage,
1382
+ lastProductIds: params.productIds
1383
+ });
1384
+ }
1385
+ });
1386
+ const retrievedProductsAtom = atom((get$1) => {
1387
+ return get$1(productRetrievalAtom).data?.products || [];
1388
+ });
1389
+ const productRetrievalLoadingAtom = atom((get$1) => {
1390
+ return get$1(productRetrievalAtom).loading;
1391
+ });
1392
+ const productRetrievalErrorAtom = atom((get$1) => {
1393
+ return get$1(productRetrievalAtom).error;
1394
+ });
1395
+
1396
+ //#endregion
1397
+ //#region src/hooks/Search/useRecommendedProducts.ts
1398
+ /**
1399
+ * A hook to get recommended products.
1400
+ * It checks the `IsRecommendedProductsEnabled` feature gate and triggers fetching if needed.
1401
+ * If the gate is enabled, it returns the list of recommended products.
1402
+ * If the gate is disabled, it returns an empty array.
1403
+ *
1404
+ * @returns The list of recommended products or an empty array.
1405
+ */
1406
+ const useRecommendedProducts = () => {
1407
+ const { featureFlagService } = useFeatureFlagService();
1408
+ const isEnabled = featureFlagService?.isFeatureGateEnabled(FeatureGates.IsRecommendedProductsEnabled);
1409
+ const recommendedProducts = useAtomValue(retrievedProductsAtom);
1410
+ const performProductRetrieval = useSetAtom(performProductRetrievalAtom);
1411
+ const { lastProductIds } = useAtomValue(productRetrievalAtom);
1412
+ const orgUIConfig = useNewOrgConfig();
1413
+ useEffect(() => {
1414
+ const recommendedProductIds = orgUIConfig.frontendConfig?.uiConfigs?.searchConfig ? orgUIConfig.frontendConfig?.uiConfigs?.searchConfig.recommendedProducts : [];
1415
+ if (isEnabled && recommendedProductIds && recommendedProductIds.length > 0 && !lastProductIds) performProductRetrieval({ productIds: recommendedProductIds });
1416
+ }, [
1417
+ isEnabled,
1418
+ performProductRetrieval,
1419
+ lastProductIds,
1420
+ orgUIConfig
1421
+ ]);
1422
+ return isEnabled ? recommendedProducts : [];
1423
+ };
1424
+
1425
+ //#endregion
42
1426
  //#region src/hooks/Search/useSearch.tsx
43
1427
  const useSearch = () => {
44
1428
  const config = useNewOrgConfig();
@@ -46,7 +1430,6 @@ const useSearch = () => {
46
1430
  const { data: searchData, loading: isLoadingSearch } = useAtomValue(searchAtom);
47
1431
  const productList = useAtomValue(filteredSearchProductsAtom);
48
1432
  const performSearch = useSetAtom(performSearchAtom);
49
- const [{ results: autocompleteResults, isLoading: isLoadingAutocomplete }, setAutocompleteState] = useAtom(autocompleteStateAtom);
50
1433
  const [{ query }] = useAtom(searchParamsAtom);
51
1434
  const [isFilterOpen, setIsFilterOpen] = useAtom(isFilterOpenAtom);
52
1435
  const [selectedFilterOptions] = useAtom(searchSelectedFiltersAtom);
@@ -55,12 +1438,26 @@ const useSearch = () => {
55
1438
  const [productSorting, setProductSorting] = useAtom(searchProductSortingAtom);
56
1439
  const clearFilters = useSetAtom(clearSearchFiltersAtom);
57
1440
  const searchFilters = useAtomValue(searchFiltersAtom);
58
- const [isDirty, setIsDirty] = useState(true);
59
- const [focusedIndex, setFocusedIndex] = useState(-1);
60
- const [focusedOptionId, setFocusedOptionId] = useState(void 0);
61
- const [searchText, setSearchText] = useState(query || "");
1441
+ const recommendedProducts = useRecommendedProducts();
62
1442
  const searchResultsRef = useRef(null);
63
- const debouncedSearchText = useDebounce(searchText, 200);
1443
+ const scrollToTop = useCallback(() => {
1444
+ const container = searchResultsRef.current;
1445
+ if (container) container.scrollTo({
1446
+ top: 0,
1447
+ behavior: "smooth"
1448
+ });
1449
+ else window.scrollTo({
1450
+ top: 0,
1451
+ behavior: "smooth"
1452
+ });
1453
+ }, []);
1454
+ const { searchText, focusedIndex, focusedOptionId, autocompleteResults, shouldShowAutocomplete, handleSearchInputChange, handleSearchInputFocus, handleSearchInputBlur, handleKeyDown, handleAutocompleteSelect, handleSubmitSearch, setSearchText } = useSearchInput({
1455
+ initialSearchText: query || "",
1456
+ searchOrigin: SpiffyWidgets.SearchResults,
1457
+ onSearchSubmit: (searchQuery) => {
1458
+ performSearch({ query: searchQuery });
1459
+ }
1460
+ });
64
1461
  const searchResultsState = getSearchResultsState(isLoadingSearch, searchData);
65
1462
  const dynamicFilters = searchData?.filters || [];
66
1463
  const safeProductCardConfig = config?.frontendConfig?.uiConfigs?.productCardConfig || {
@@ -120,76 +1517,16 @@ const useSearch = () => {
120
1517
  }
121
1518
  });
122
1519
  addFilter(createFilterOption("dynamic", filter, dynamicFilterDisplayName));
1520
+ scrollToTop();
123
1521
  }, [
124
1522
  addFilter,
125
1523
  searchText,
126
- trackEvent
1524
+ scrollToTop
127
1525
  ]);
128
1526
  const handleRemoveFilter = useCallback((filter) => {
129
1527
  removeFilter(filter.id);
130
- }, [removeFilter]);
131
- const handleSubmitSearch = useCallback(async () => {
132
- if (searchText.trim()) {
133
- trackEvent({
134
- eventName: SpiffyMetricsEventName.SearchQuerySubmitted,
135
- eventProps: {
136
- searchOrigin: SpiffyWidgets.SearchResults,
137
- queryText: searchText.trim()
138
- },
139
- alsoSendToGoogleAnalytics: true
140
- });
141
- const url = new URL(window.location.href);
142
- url.searchParams.set("esq", searchText.trim());
143
- window.history.pushState({}, "", url);
144
- performSearch({ query: searchText.trim() });
145
- }
146
- }, [
147
- performSearch,
148
- searchText,
149
- trackEvent
150
- ]);
151
- const handleAutocompleteSelect = useCallback((suggestion) => {
152
- setSearchText(suggestion);
153
- handleSubmitSearch();
154
- }, [handleSubmitSearch, setSearchText]);
155
- const handleKeyDown = useCallback((event) => {
156
- if (event.key === "ArrowDown") {
157
- event.preventDefault();
158
- const newIndex = (focusedIndex + 1) % autocompleteResults.length;
159
- setFocusedIndex(newIndex);
160
- setFocusedOptionId(`option-${newIndex}`);
161
- } else if (event.key === "ArrowUp") {
162
- event.preventDefault();
163
- const newIndex = (focusedIndex - 1 + autocompleteResults.length) % autocompleteResults.length;
164
- setFocusedIndex(newIndex);
165
- setFocusedOptionId(`option-${newIndex}`);
166
- } else if (event.key === "Enter") if (focusedIndex === -1) {
167
- event.preventDefault();
168
- handleSubmitSearch();
169
- } else {
170
- event.preventDefault();
171
- const suggestionText = autocompleteResults[focusedIndex];
172
- handleAutocompleteSelect(suggestionText);
173
- }
174
- else if (event.key === "Escape") {
175
- event.preventDefault();
176
- setFocusedIndex(-1);
177
- setFocusedOptionId(void 0);
178
- }
179
- }, [
180
- autocompleteResults,
181
- focusedIndex,
182
- handleAutocompleteSelect,
183
- handleSubmitSearch
184
- ]);
185
- const handleSearchInputChange = (newValue) => {
186
- if (newValue.length === 1) trackEvent({
187
- eventName: SpiffyMetricsEventName.SearchInputStarted,
188
- eventProps: { searchOrigin: SpiffyWidgets.SearchResults }
189
- });
190
- setSearchText(newValue);
191
- setIsDirty(true);
192
- };
1528
+ scrollToTop();
1529
+ }, [removeFilter, scrollToTop]);
193
1530
  const handleSelectFilterItem = useCallback(({ filterId, filterItemId, isSelected, displayName }) => {
194
1531
  if (filterId === "sort") {
195
1532
  const newSort = filterItemId;
@@ -201,8 +1538,11 @@ const useSearch = () => {
201
1538
  }
202
1539
  });
203
1540
  setProductSorting(newSort);
204
- } else if (!isSelected) removeFilter(`${filterId}:${filterItemId}`);
205
- else {
1541
+ scrollToTop();
1542
+ } else if (!isSelected) {
1543
+ removeFilter(`${filterId}:${filterItemId}`);
1544
+ scrollToTop();
1545
+ } else {
206
1546
  trackEvent({
207
1547
  eventName: SpiffyMetricsEventName.SearchFilterClicked,
208
1548
  eventProps: {
@@ -213,78 +1553,44 @@ const useSearch = () => {
213
1553
  }
214
1554
  });
215
1555
  addFilter(createFilterOption(filterId, filterItemId, displayName));
1556
+ scrollToTop();
216
1557
  }
217
1558
  }, [
218
1559
  addFilter,
219
1560
  removeFilter,
220
1561
  setProductSorting,
221
1562
  searchText,
222
- trackEvent
1563
+ scrollToTop
223
1564
  ]);
224
1565
  const handleClearAllFilters = useCallback(() => {
225
1566
  setProductSorting(ProductSorting.FEATURED);
226
1567
  clearFilters();
227
- }, [setProductSorting, clearFilters]);
1568
+ scrollToTop();
1569
+ }, [
1570
+ setProductSorting,
1571
+ clearFilters,
1572
+ scrollToTop
1573
+ ]);
228
1574
  useTrackComponentVisibleEvent(SpiffyWidgets.SearchResults, searchResultsRef, {}, SpiffyMetricsEventName.SearchComponentVisible);
229
1575
  useEffect(() => {
230
- if (searchResultsState === SearchResultsState.NoResults || searchResultsState === SearchResultsState.Results) trackEvent({
1576
+ if (searchResultsState === SearchResultsState.Results || searchResultsState === SearchResultsState.NoResults) trackEvent({
231
1577
  eventName: SpiffyMetricsEventName.SearchResultsViewed,
232
1578
  eventProps: {
233
1579
  queryText: searchText,
234
1580
  resultsCount: productList.length
235
1581
  }
236
1582
  });
237
- }, [
238
- productList.length,
239
- searchResultsState,
240
- trackEvent
241
- ]);
242
- useEffect(() => {
243
- if (query && query !== searchText) setSearchText(query);
244
- }, [query]);
245
- useEffect(() => {
246
- const esq = new URLSearchParams(window.location.search).get("esq");
247
- if (esq) {
248
- setSearchText(esq);
249
- performSearch({ query: esq });
250
- }
251
- }, [performSearch]);
252
- const fetchAutocompleteSuggestions = (_query) => {
253
- return Promise.resolve([]);
254
- };
1583
+ }, [productList.length, searchResultsState]);
255
1584
  useEffect(() => {
256
- if (fetchAutocompleteSuggestions === void 0) return;
257
- if (!isDirty || debouncedSearchText.length <= 2) {
258
- setAutocompleteState({
259
- results: [],
260
- isLoading: false
261
- });
262
- return;
1585
+ if (query && query !== searchText) {
1586
+ const esq = new URLSearchParams(window.location.search).get("esq");
1587
+ setSearchText(query);
1588
+ performSearch({ query: esq ?? query });
263
1589
  }
264
- setAutocompleteState((prev) => ({
265
- ...prev,
266
- isLoading: true
267
- }));
268
- const fetchData = async () => {
269
- try {
270
- const results = await fetchAutocompleteSuggestions?.(debouncedSearchText);
271
- setAutocompleteState({
272
- results: results ?? [],
273
- isLoading: false
274
- });
275
- } catch (error) {
276
- logger_default.logError("Failed to fetch autocomplete suggestions:", error);
277
- setAutocompleteState({
278
- results: [],
279
- isLoading: false
280
- });
281
- }
282
- };
283
- fetchData();
284
1590
  }, [
285
- debouncedSearchText,
286
- isDirty,
287
- setAutocompleteState
1591
+ performSearch,
1592
+ query,
1593
+ setSearchText
288
1594
  ]);
289
1595
  return {
290
1596
  searchData,
@@ -292,16 +1598,17 @@ const useSearch = () => {
292
1598
  merchantShortName: safeMerchantShortName,
293
1599
  productCardConfig: safeProductCardConfig,
294
1600
  productList,
1601
+ recommendedProducts,
295
1602
  autocompleteResults,
296
1603
  searchFilters: filters,
297
1604
  availableDynamicFilters,
298
1605
  selectedFilterOptions,
299
1606
  searchText,
1607
+ query: query || "",
300
1608
  searchResultsState,
301
- isLoadingAutocomplete,
302
1609
  isLoadingSearch,
303
1610
  isFilterOpen,
304
- isDirty,
1611
+ shouldShowAutocomplete,
305
1612
  focusedIndex,
306
1613
  focusedOptionId,
307
1614
  filterButtonText,
@@ -309,6 +1616,8 @@ const useSearch = () => {
309
1616
  onSubmitSearch: handleSubmitSearch,
310
1617
  onAutocompleteSelect: handleAutocompleteSelect,
311
1618
  onKeyDown: handleKeyDown,
1619
+ onSearchInputFocus: handleSearchInputFocus,
1620
+ onSearchInputBlur: handleSearchInputBlur,
312
1621
  onToggleDynamicFilter: handleToggleDynamicFilter,
313
1622
  onSelectFilterItem: handleSelectFilterItem,
314
1623
  onRemoveFilter: handleRemoveFilter,
@@ -320,4 +1629,4 @@ const useSearch = () => {
320
1629
 
321
1630
  //#endregion
322
1631
  export { useSearch };
323
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJoYW5kbGVTZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hvb2tzL1NlYXJjaC91c2VTZWFyY2gudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZUF0b20sIHVzZUF0b21WYWx1ZSwgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlRGVib3VuY2UgfSBmcm9tIFwic3JjL2hvb2tzL0RlYm91bmNlL3VzZURlYm91bmNlXCI7XG5pbXBvcnQge1xuICBhZGRTZWFyY2hGaWx0ZXJBdG9tLFxuICBjbGVhclNlYXJjaEZpbHRlcnNBdG9tLFxuICBjcmVhdGVGaWx0ZXJPcHRpb24sXG4gIGZpbHRlcmVkU2VhcmNoUHJvZHVjdHNBdG9tLFxuICBwZXJmb3JtU2VhcmNoQXRvbSxcbiAgcmVtb3ZlU2VhcmNoRmlsdGVyQXRvbSxcbiAgc2VhcmNoQXRvbSxcbiAgc2VhcmNoRmlsdGVyc0F0b20sXG4gIHNlYXJjaFBhcmFtc0F0b20sXG4gIHNlYXJjaFByb2R1Y3RTb3J0aW5nQXRvbSxcbiAgc2VhcmNoU2VsZWN0ZWRGaWx0ZXJzQXRvbSxcbiAgU2VsZWN0ZWRGaWx0ZXJPcHRpb24sXG59IGZyb20gXCJzcmMvYXRvbXMvc2VhcmNoXCI7XG5pbXBvcnQge1xuICBhdXRvY29tcGxldGVTdGF0ZUF0b20sXG4gIGlzRmlsdGVyT3BlbkF0b20sXG59IGZyb20gXCJzcmMvYXRvbXMvZ2xvYmFsU2VhcmNoL2dsb2JhbFNlYXJjaFwiO1xuaW1wb3J0IHsgZm9ybWF0RmlsdGVyRGlzcGxheU5hbWUgfSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC91dGlsc1wiO1xuaW1wb3J0IHsgUHJvZHVjdFNvcnRpbmcgfSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC90eXBlc1wiO1xuaW1wb3J0IHtcbiAgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgdXNlQW1wbGl0dWRlLFxufSBmcm9tIFwic3JjL2NvbnRleHRzL2FtcGxpdHVkZUNvbnRleHQvYW1wbGl0dWRlQ29udGV4dFwiO1xuaW1wb3J0IHsgU3BpZmZ5V2lkZ2V0cyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3NwaWZmeVdpZGdldHNcIjtcbmltcG9ydCB7IFByb2R1Y3RDYXJkQ29uZmlnIH0gZnJvbSBcInNyYy9jb250ZXh0cy90eXBlc1wiO1xuaW1wb3J0IExvZ2dlciBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5pbXBvcnQgeyBTZWFyY2hSZXN1bHQgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9hcGkvc2VhcmNoXCI7XG5pbXBvcnQgeyBTZWFyY2hSZXNwb25zZVByb2R1Y3QgfSBmcm9tIFwiQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50XCI7XG5pbXBvcnQge1xuICBTZWFyY2hGaWx0ZXJEYXR1bSxcbiAgU2VsZWN0RmlsdGVySXRlbSxcbn0gZnJvbSBcInNyYy90eXBlcy9zZWFyY2gtZmlsdGVyLXR5cGVzXCI7XG5pbXBvcnQgeyBnZXRTZWFyY2hSZXN1bHRzU3RhdGUsIFNlYXJjaFJlc3VsdHNTdGF0ZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgb3JnU2hvcnROYW1lQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvZW52aXZlL2Vudml2ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlTmV3T3JnQ29uZmlnIH0gZnJvbSBcIi4uL05ld09yZ0NvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlVHJhY2tDb21wb25lbnRWaXNpYmxlRXZlbnQgfSBmcm9tIFwiLi4vVHJhY2tDb21wb25lbnRWaXNpYmxlRXZlbnRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSZXN1bHRzSG9jUHJvcHMge1xuICAvLyBEYXRhXG4gIHNlYXJjaERhdGE6IFNlYXJjaFJlc3VsdCB8IG51bGw7XG4gIHNlYXJjaFJlc3BvbnNlSWQ6IHN0cmluZztcbiAgbWVyY2hhbnRTaG9ydE5hbWU6IHN0cmluZztcbiAgcHJvZHVjdENhcmRDb25maWc6IFByb2R1Y3RDYXJkQ29uZmlnO1xuICBwcm9kdWN0TGlzdDogU2VhcmNoUmVzcG9uc2VQcm9kdWN0W107XG4gIGF1dG9jb21wbGV0ZVJlc3VsdHM6IHN0cmluZ1tdO1xuICBzZWFyY2hGaWx0ZXJzOiBTZWFyY2hGaWx0ZXJEYXR1bVtdO1xuICBhdmFpbGFibGVEeW5hbWljRmlsdGVyczogeyBuYW1lOiBzdHJpbmc7IGRpc3BsYXlOYW1lOiBzdHJpbmcgfVtdO1xuICBzZWxlY3RlZEZpbHRlck9wdGlvbnM6IFNlbGVjdGVkRmlsdGVyT3B0aW9uW107XG5cbiAgLy8gU3RhdGVcbiAgc2VhcmNoVGV4dDogc3RyaW5nO1xuICBzZWFyY2hSZXN1bHRzU3RhdGU6IFNlYXJjaFJlc3VsdHNTdGF0ZTtcbiAgaXNMb2FkaW5nQXV0b2NvbXBsZXRlOiBib29sZWFuO1xuICBpc0xvYWRpbmdTZWFyY2g6IGJvb2xlYW47XG4gIGlzRmlsdGVyT3BlbjogYm9vbGVhbjtcbiAgaXNEaXJ0eTogYm9vbGVhbjtcbiAgZm9jdXNlZEluZGV4OiBudW1iZXI7XG4gIGZvY3VzZWRPcHRpb25JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8vIFVJXG4gIGZpbHRlckJ1dHRvblRleHQ6IHN0cmluZztcblxuICAvLyBFdmVudCBIYW5kbGVyc1xuICBvblNlYXJjaElucHV0Q2hhbmdlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZDtcbiAgb25TdWJtaXRTZWFyY2g6ICgpID0+IHZvaWQ7XG4gIG9uQXV0b2NvbXBsZXRlU2VsZWN0OiAoc3VnZ2VzdGlvbjogc3RyaW5nKSA9PiB2b2lkO1xuICBvbktleURvd246IChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4gdm9pZDtcbiAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiAoe1xuICAgIGZpbHRlcixcbiAgICBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUsXG4gIH06IHtcbiAgICBmaWx0ZXI6IHN0cmluZztcbiAgICBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWU6IHN0cmluZztcbiAgfSkgPT4gdm9pZDtcbiAgb25TZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtO1xuICBvblJlbW92ZUZpbHRlcjogKGZpbHRlcjogU2VsZWN0ZWRGaWx0ZXJPcHRpb24pID0+IHZvaWQ7XG4gIG9uQ2xlYXJBbGxGaWx0ZXJzOiAoKSA9PiB2b2lkO1xuICBzZXRJc0ZpbHRlck9wZW46IChpc0ZpbHRlck9wZW46IGJvb2xlYW4pID0+IHZvaWQ7XG5cbiAgLy8gUmVmc1xuICBzZWFyY2hSZXN1bHRzUmVmOiBSZWFjdC5SZWZPYmplY3Q8SFRNTERpdkVsZW1lbnQ+O1xufVxuXG5leHBvcnQgY29uc3QgdXNlU2VhcmNoID0gKCk6IFNlYXJjaFJlc3VsdHNIb2NQcm9wcyA9PiB7XG4gIC8vIEF0b21zXG4gIGNvbnN0IGNvbmZpZyA9IHVzZU5ld09yZ0NvbmZpZygpO1xuICBjb25zdCBvcmdTaG9ydE5hbWUgPSB1c2VBdG9tVmFsdWUob3JnU2hvcnROYW1lQXRvbSk7XG4gIGNvbnN0IHsgZGF0YTogc2VhcmNoRGF0YSwgbG9hZGluZzogaXNMb2FkaW5nU2VhcmNoIH0gPVxuICAgIHVzZUF0b21WYWx1ZShzZWFyY2hBdG9tKTtcbiAgY29uc3QgcHJvZHVjdExpc3QgPSB1c2VBdG9tVmFsdWUoZmlsdGVyZWRTZWFyY2hQcm9kdWN0c0F0b20pO1xuICBjb25zdCBwZXJmb3JtU2VhcmNoID0gdXNlU2V0QXRvbShwZXJmb3JtU2VhcmNoQXRvbSk7XG4gIGNvbnN0IFtcbiAgICB7IHJlc3VsdHM6IGF1dG9jb21wbGV0ZVJlc3VsdHMsIGlzTG9hZGluZzogaXNMb2FkaW5nQXV0b2NvbXBsZXRlIH0sXG4gICAgc2V0QXV0b2NvbXBsZXRlU3RhdGUsXG4gIF0gPSB1c2VBdG9tKGF1dG9jb21wbGV0ZVN0YXRlQXRvbSk7XG4gIGNvbnN0IFt7IHF1ZXJ5IH1dID0gdXNlQXRvbShzZWFyY2hQYXJhbXNBdG9tKTtcbiAgY29uc3QgW2lzRmlsdGVyT3Blbiwgc2V0SXNGaWx0ZXJPcGVuXSA9IHVzZUF0b20oaXNGaWx0ZXJPcGVuQXRvbSk7XG4gIGNvbnN0IFtzZWxlY3RlZEZpbHRlck9wdGlvbnNdID0gdXNlQXRvbShzZWFyY2hTZWxlY3RlZEZpbHRlcnNBdG9tKTtcbiAgY29uc3QgYWRkRmlsdGVyID0gdXNlU2V0QXRvbShhZGRTZWFyY2hGaWx0ZXJBdG9tKTtcbiAgY29uc3QgcmVtb3ZlRmlsdGVyID0gdXNlU2V0QXRvbShyZW1vdmVTZWFyY2hGaWx0ZXJBdG9tKTtcbiAgY29uc3QgW3Byb2R1Y3RTb3J0aW5nLCBzZXRQcm9kdWN0U29ydGluZ10gPSB1c2VBdG9tKHNlYXJjaFByb2R1Y3RTb3J0aW5nQXRvbSk7XG4gIGNvbnN0IGNsZWFyRmlsdGVycyA9IHVzZVNldEF0b20oY2xlYXJTZWFyY2hGaWx0ZXJzQXRvbSk7XG4gIGNvbnN0IHNlYXJjaEZpbHRlcnMgPSB1c2VBdG9tVmFsdWUoc2VhcmNoRmlsdGVyc0F0b20pO1xuXG4gIC8vIFN0YXRlXG4gIGNvbnN0IFtpc0RpcnR5LCBzZXRJc0RpcnR5XSA9IHVzZVN0YXRlKHRydWUpO1xuICBjb25zdCBbZm9jdXNlZEluZGV4LCBzZXRGb2N1c2VkSW5kZXhdID0gdXNlU3RhdGUoLTEpO1xuICBjb25zdCBbZm9jdXNlZE9wdGlvbklkLCBzZXRGb2N1c2VkT3B0aW9uSWRdID0gdXNlU3RhdGU8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgICB1bmRlZmluZWRcbiAgKTtcbiAgY29uc3QgW3NlYXJjaFRleHQsIHNldFNlYXJjaFRleHRdID0gdXNlU3RhdGUocXVlcnkgfHwgXCJcIik7XG5cbiAgLy8gUmVmc1xuICBjb25zdCBzZWFyY2hSZXN1bHRzUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcblxuICAvLyBEZXJpdmVkIFN0YXRlXG4gIGNvbnN0IGRlYm91bmNlZFNlYXJjaFRleHQgPSB1c2VEZWJvdW5jZShzZWFyY2hUZXh0LCAyMDApO1xuICBjb25zdCBzZWFyY2hSZXN1bHRzU3RhdGUgPSBnZXRTZWFyY2hSZXN1bHRzU3RhdGUoaXNMb2FkaW5nU2VhcmNoLCBzZWFyY2hEYXRhKTtcblxuICBjb25zdCBkeW5hbWljRmlsdGVycyA9IHNlYXJjaERhdGE/LmZpbHRlcnMgfHwgW107XG5cbiAgLy8gUHJvdmlkZSBmYWxsYmFjayB2YWx1ZXMgd2hlbiBvcmdVSUNvbmZpZyBpcyBub3QgeWV0IGF2YWlsYWJsZVxuICBjb25zdCBzYWZlUHJvZHVjdENhcmRDb25maWcgPSBjb25maWc/LmZyb250ZW5kQ29uZmlnPy51aUNvbmZpZ3NcbiAgICA/LnByb2R1Y3RDYXJkQ29uZmlnIHx8IHtcbiAgICB2YXJpYW50OiBcIm1pbmltYWxcIixcbiAgICBob3ZlclZhcmlhbnQ6IFwibm9uZVwiLFxuICAgIGxheW91dFZhcmlhbnQ6IFwic3F1YXJlXCIsXG4gIH07XG4gIGNvbnN0IHNhZmVNZXJjaGFudFNob3J0TmFtZSA9IG9yZ1Nob3J0TmFtZSB8fCBcIlwiO1xuXG4gIGNvbnN0IGF2YWlsYWJsZUR5bmFtaWNGaWx0ZXJzID0gdXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIGR5bmFtaWNGaWx0ZXJzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoZHluYW1pY0ZpbHRlck5hbWUpID0+XG4gICAgICAgICAgIXNlbGVjdGVkRmlsdGVyT3B0aW9ucy5zb21lKFxuICAgICAgICAgICAgKG9wdGlvbikgPT4gb3B0aW9uLmlkID09PSBgZHluYW1pYzoke2R5bmFtaWNGaWx0ZXJOYW1lfWBcbiAgICAgICAgICApXG4gICAgICApXG4gICAgICAubWFwKChkeW5hbWljRmlsdGVyTmFtZSkgPT4gKHtcbiAgICAgICAgbmFtZTogZHluYW1pY0ZpbHRlck5hbWUsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBmb3JtYXRGaWx0ZXJEaXNwbGF5TmFtZShkeW5hbWljRmlsdGVyTmFtZSksXG4gICAgICB9KSk7XG4gIH0sIFtkeW5hbWljRmlsdGVycywgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zXSk7XG5cbiAgY29uc3QgZmlsdGVycyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHNvcnRPcHRpb25zID0gW1xuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5GRUFUVVJFRCksXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlJlbGV2YW5jZVwiLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5GRUFUVVJFRCxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGZpbHRlckl0ZW1JZDogU3RyaW5nKFByb2R1Y3RTb3J0aW5nLlBSSUNFX0FTQyksXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlByaWNlOiBMb3cgdG8gSGlnaFwiLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5QUklDRV9BU0MsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5QUklDRV9ERVNDKSxcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiUHJpY2U6IEhpZ2ggdG8gTG93XCIsXG4gICAgICAgIHByb2R1Y3RDb3VudDogMCxcbiAgICAgICAgaXNTZWxlY3RlZDogcHJvZHVjdFNvcnRpbmcgPT09IFByb2R1Y3RTb3J0aW5nLlBSSUNFX0RFU0MsXG4gICAgICB9LFxuICAgIF07XG5cbiAgICByZXR1cm4gW1xuICAgICAgeyBmaWx0ZXJJZDogXCJzb3J0XCIsIGRpc3BsYXlOYW1lOiBcIlNPUlRcIiwgaXRlbXM6IHNvcnRPcHRpb25zIH0sXG4gICAgICAuLi5zZWFyY2hGaWx0ZXJzLFxuICAgIF0gYXMgU2VhcmNoRmlsdGVyRGF0dW1bXTtcbiAgfSwgW3Byb2R1Y3RTb3J0aW5nLCBzZWFyY2hGaWx0ZXJzXSk7XG5cbiAgY29uc3QgZmlsdGVyQnV0dG9uVGV4dCA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkQ291bnQgPSBmaWx0ZXJzLnJlZHVjZSgoYWNjOiBudW1iZXIsIGZpbHRlcikgPT4ge1xuICAgICAgaWYgKGZpbHRlci5maWx0ZXJJZCA9PT0gXCJzb3J0XCIpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBmaWx0ZXIuaXRlbXMuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmlzU2VsZWN0ZWQpLmxlbmd0aDtcbiAgICB9LCAwKTtcbiAgICBpZiAoc2VsZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiRmlsdGVyICYgU29ydFwiO1xuICAgIH1cbiAgICByZXR1cm4gYEZpbHRlciAmIFNvcnQgKCR7c2VsZWN0ZWRDb3VudH0pYDtcbiAgfSwgW2ZpbHRlcnNdKTtcblxuICAvLyBDYWxsYmFja3NcbiAgY29uc3QgeyB0cmFja0V2ZW50IH0gPSB1c2VBbXBsaXR1ZGUoKTtcblxuICBjb25zdCBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIGZpbHRlcixcbiAgICAgIGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZSxcbiAgICB9OiB7XG4gICAgICBmaWx0ZXI6IHN0cmluZztcbiAgICAgIGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoRmlsdGVyQ2xpY2tlZCxcbiAgICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICAgIGZpbHRlclR5cGU6IFwiRHluYW1pY1wiLFxuICAgICAgICAgIGZpbHRlclZhbHVlOiBmaWx0ZXIsXG4gICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhZGRGaWx0ZXIoXG4gICAgICAgIGNyZWF0ZUZpbHRlck9wdGlvbihcImR5bmFtaWNcIiwgZmlsdGVyLCBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUpXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FkZEZpbHRlciwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVSZW1vdmVGaWx0ZXIgPSB1c2VDYWxsYmFjayhcbiAgICAoZmlsdGVyOiBTZWxlY3RlZEZpbHRlck9wdGlvbikgPT4ge1xuICAgICAgcmVtb3ZlRmlsdGVyKGZpbHRlci5pZCk7XG4gICAgfSxcbiAgICBbcmVtb3ZlRmlsdGVyXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZVN1Ym1pdFNlYXJjaCA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICBpZiAoc2VhcmNoVGV4dC50cmltKCkpIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoUXVlcnlTdWJtaXR0ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBzZWFyY2hPcmlnaW46IFNwaWZmeVdpZGdldHMuU2VhcmNoUmVzdWx0cyxcbiAgICAgICAgICBxdWVyeVRleHQ6IHNlYXJjaFRleHQudHJpbSgpLFxuICAgICAgICB9LFxuICAgICAgICBhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KFwiZXNxXCIsIHNlYXJjaFRleHQudHJpbSgpKTtcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSh7fSwgXCJcIiwgdXJsKTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogc2VhcmNoVGV4dC50cmltKCkgfSk7XG4gICAgfVxuICB9LCBbcGVyZm9ybVNlYXJjaCwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF0pO1xuXG4gIGNvbnN0IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCA9IHVzZUNhbGxiYWNrKFxuICAgIChzdWdnZXN0aW9uOiBzdHJpbmcpID0+IHtcbiAgICAgIHNldFNlYXJjaFRleHQoc3VnZ2VzdGlvbik7XG4gICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICB9LFxuICAgIFtoYW5kbGVTdWJtaXRTZWFyY2gsIHNldFNlYXJjaFRleHRdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlS2V5RG93biA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd0Rvd25cIikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBuZXdJbmRleCA9IChmb2N1c2VkSW5kZXggKyAxKSAlIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoO1xuICAgICAgICBzZXRGb2N1c2VkSW5kZXgobmV3SW5kZXgpO1xuICAgICAgICBzZXRGb2N1c2VkT3B0aW9uSWQoYG9wdGlvbi0ke25ld0luZGV4fWApO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dVcFwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IG5ld0luZGV4ID1cbiAgICAgICAgICAoZm9jdXNlZEluZGV4IC0gMSArIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoKSAlXG4gICAgICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cy5sZW5ndGg7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleChuZXdJbmRleCk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZChgb3B0aW9uLSR7bmV3SW5kZXh9YCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiKSB7XG4gICAgICAgIGlmIChmb2N1c2VkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25UZXh0ID0gYXV0b2NvbXBsZXRlUmVzdWx0c1tmb2N1c2VkSW5kZXhdO1xuICAgICAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdChzdWdnZXN0aW9uVGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleCgtMSk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZCh1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW1xuICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cyxcbiAgICAgIGZvY3VzZWRJbmRleCxcbiAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICAgIGhhbmRsZVN1Ym1pdFNlYXJjaCxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlU2VhcmNoSW5wdXRDaGFuZ2UgPSAobmV3VmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGlmIChuZXdWYWx1ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoSW5wdXRTdGFydGVkLFxuICAgICAgICBldmVudFByb3BzOiB7XG4gICAgICAgICAgc2VhcmNoT3JpZ2luOiBTcGlmZnlXaWRnZXRzLlNlYXJjaFJlc3VsdHMsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgc2V0U2VhcmNoVGV4dChuZXdWYWx1ZSk7XG4gICAgc2V0SXNEaXJ0eSh0cnVlKTtcbiAgfTtcblxuICBjb25zdCBoYW5kbGVTZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtID0gdXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIGZpbHRlcklkLFxuICAgICAgZmlsdGVySXRlbUlkLFxuICAgICAgaXNTZWxlY3RlZCxcbiAgICAgIGRpc3BsYXlOYW1lLFxuICAgIH06IHtcbiAgICAgIGZpbHRlcklkOiBzdHJpbmc7XG4gICAgICBmaWx0ZXJJdGVtSWQ6IHN0cmluZztcbiAgICAgIGlzU2VsZWN0ZWQ6IGJvb2xlYW47XG4gICAgICBkaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChmaWx0ZXJJZCA9PT0gXCJzb3J0XCIpIHtcbiAgICAgICAgY29uc3QgbmV3U29ydCA9IGZpbHRlckl0ZW1JZCBhcyBQcm9kdWN0U29ydGluZztcbiAgICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaFNvcnRDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIHNvcnRUeXBlOiBuZXdTb3J0LFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBzZXRQcm9kdWN0U29ydGluZyhuZXdTb3J0KTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzU2VsZWN0ZWQpIHtcbiAgICAgICAgcmVtb3ZlRmlsdGVyKGAke2ZpbHRlcklkfToke2ZpbHRlckl0ZW1JZH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hGaWx0ZXJDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIGZpbHRlclR5cGU6IFwiU3RhdGljXCIsXG4gICAgICAgICAgICBmaWx0ZXJDYXRlZ29yeTogZmlsdGVySWQsXG4gICAgICAgICAgICBmaWx0ZXJWYWx1ZTogZmlsdGVySXRlbUlkLFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBhZGRGaWx0ZXIoY3JlYXRlRmlsdGVyT3B0aW9uKGZpbHRlcklkLCBmaWx0ZXJJdGVtSWQsIGRpc3BsYXlOYW1lKSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbYWRkRmlsdGVyLCByZW1vdmVGaWx0ZXIsIHNldFByb2R1Y3RTb3J0aW5nLCBzZWFyY2hUZXh0LCB0cmFja0V2ZW50XVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZUNsZWFyQWxsRmlsdGVycyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRQcm9kdWN0U29ydGluZyhQcm9kdWN0U29ydGluZy5GRUFUVVJFRCk7XG4gICAgY2xlYXJGaWx0ZXJzKCk7XG4gIH0sIFtzZXRQcm9kdWN0U29ydGluZywgY2xlYXJGaWx0ZXJzXSk7XG5cbiAgLy8gU2lkZSBFZmZlY3RzXG4gIHVzZVRyYWNrQ29tcG9uZW50VmlzaWJsZUV2ZW50KFxuICAgIFNwaWZmeVdpZGdldHMuU2VhcmNoUmVzdWx0cyxcbiAgICBzZWFyY2hSZXN1bHRzUmVmLFxuICAgIHt9LFxuICAgIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoQ29tcG9uZW50VmlzaWJsZVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHNlYXJjaFJlc3VsdHNTdGF0ZSA9PT0gU2VhcmNoUmVzdWx0c1N0YXRlLk5vUmVzdWx0cyB8fCBzZWFyY2hSZXN1bHRzU3RhdGUgPT09IFNlYXJjaFJlc3VsdHNTdGF0ZS5SZXN1bHRzKSB7XG4gICAgICB0cmFja0V2ZW50KHtcbiAgICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaFJlc3VsdHNWaWV3ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBxdWVyeVRleHQ6IHNlYXJjaFRleHQsXG4gICAgICAgICAgcmVzdWx0c0NvdW50OiBwcm9kdWN0TGlzdC5sZW5ndGgsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIFtwcm9kdWN0TGlzdC5sZW5ndGgsIHNlYXJjaFJlc3VsdHNTdGF0ZSwgdHJhY2tFdmVudF0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5ICE9PSBzZWFyY2hUZXh0KSB7XG4gICAgICBzZXRTZWFyY2hUZXh0KHF1ZXJ5KTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbcXVlcnldKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGVzcSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCkuZ2V0KFwiZXNxXCIpO1xuICAgIGlmIChlc3EpIHtcbiAgICAgIHNldFNlYXJjaFRleHQoZXNxKTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogZXNxIH0pO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIFtwZXJmb3JtU2VhcmNoXSk7XG5cbiAgY29uc3QgZmV0Y2hBdXRvY29tcGxldGVTdWdnZXN0aW9ucyA9IChfcXVlcnk6IHN0cmluZykgPT4ge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBhdXRvY29tcGxldGUgc3VnZ2VzdGlvbnNcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChmZXRjaEF1dG9jb21wbGV0ZVN1Z2dlc3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlzRGlydHkgfHwgZGVib3VuY2VkU2VhcmNoVGV4dC5sZW5ndGggPD0gMikge1xuICAgICAgc2V0QXV0b2NvbXBsZXRlU3RhdGUoeyByZXN1bHRzOiBbXSwgaXNMb2FkaW5nOiBmYWxzZSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRBdXRvY29tcGxldGVTdGF0ZSgocHJldikgPT4gKHsgLi4ucHJldiwgaXNMb2FkaW5nOiB0cnVlIH0pKTtcblxuICAgIGNvbnN0IGZldGNoRGF0YSA9IGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBmZXRjaEF1dG9jb21wbGV0ZVN1Z2dlc3Rpb25zPy4oXG4gICAgICAgICAgZGVib3VuY2VkU2VhcmNoVGV4dFxuICAgICAgICApO1xuICAgICAgICBzZXRBdXRvY29tcGxldGVTdGF0ZSh7IHJlc3VsdHM6IHJlc3VsdHMgPz8gW10sIGlzTG9hZGluZzogZmFsc2UgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gZmV0Y2ggYXV0b2NvbXBsZXRlIHN1Z2dlc3Rpb25zOlwiLCBlcnJvcik7XG4gICAgICAgIHNldEF1dG9jb21wbGV0ZVN0YXRlKHsgcmVzdWx0czogW10sIGlzTG9hZGluZzogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZldGNoRGF0YSgpO1xuICB9LCBbZGVib3VuY2VkU2VhcmNoVGV4dCwgaXNEaXJ0eSwgc2V0QXV0b2NvbXBsZXRlU3RhdGVdKTtcblxuICByZXR1cm4ge1xuICAgIHNlYXJjaERhdGEsXG4gICAgc2VhcmNoUmVzcG9uc2VJZDogc2VhcmNoRGF0YT8uc2VhcmNoUmVzcG9uc2VJZCA/PyBcIlwiLFxuICAgIG1lcmNoYW50U2hvcnROYW1lOiBzYWZlTWVyY2hhbnRTaG9ydE5hbWUsXG4gICAgcHJvZHVjdENhcmRDb25maWc6IHNhZmVQcm9kdWN0Q2FyZENvbmZpZyxcbiAgICBwcm9kdWN0TGlzdCxcbiAgICBhdXRvY29tcGxldGVSZXN1bHRzLFxuICAgIHNlYXJjaEZpbHRlcnM6IGZpbHRlcnMsXG4gICAgYXZhaWxhYmxlRHluYW1pY0ZpbHRlcnMsXG4gICAgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zLFxuICAgIHNlYXJjaFRleHQsXG4gICAgc2VhcmNoUmVzdWx0c1N0YXRlLFxuICAgIGlzTG9hZGluZ0F1dG9jb21wbGV0ZSxcbiAgICBpc0xvYWRpbmdTZWFyY2gsXG4gICAgaXNGaWx0ZXJPcGVuLFxuICAgIGlzRGlydHksXG4gICAgZm9jdXNlZEluZGV4LFxuICAgIGZvY3VzZWRPcHRpb25JZCxcbiAgICBmaWx0ZXJCdXR0b25UZXh0LFxuICAgIG9uU2VhcmNoSW5wdXRDaGFuZ2U6IGhhbmRsZVNlYXJjaElucHV0Q2hhbmdlLFxuICAgIG9uU3VibWl0U2VhcmNoOiBoYW5kbGVTdWJtaXRTZWFyY2gsXG4gICAgb25BdXRvY29tcGxldGVTZWxlY3Q6IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICBvbktleURvd246IGhhbmRsZUtleURvd24sXG4gICAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyLFxuICAgIG9uU2VsZWN0RmlsdGVySXRlbTogaGFuZGxlU2VsZWN0RmlsdGVySXRlbSxcbiAgICBvblJlbW92ZUZpbHRlcjogaGFuZGxlUmVtb3ZlRmlsdGVyLFxuICAgIG9uQ2xlYXJBbGxGaWx0ZXJzOiBoYW5kbGVDbGVhckFsbEZpbHRlcnMsXG4gICAgc2V0SXNGaWx0ZXJPcGVuLFxuICAgIHNlYXJjaFJlc3VsdHNSZWYsXG4gIH07XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF1RkEsTUFBYSxrQkFBeUM7Q0FFcEQsTUFBTSxT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
1632
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJvYmoiLCJwYXRoIiwibm9ybSIsInZhbHVlIiwicGF0dGVybiIsInJlc3VsdCIsIml0ZW0iLCJzZWFyY2hlcnMiLCJxdWVyeSIsInByb2R1Y3RSZXRyaWV2YWxGdW5jdGlvbjpcbiAgfCAoKHBhcmFtczogUHJvZHVjdFJldHJpZXZhbFBhcmFtcykgPT4gUHJvbWlzZTxQcm9kdWN0UmV0cmlldmFsUmVzdWx0PilcbiAgfCBudWxsIiwiZ2V0IiwiZXJyb3I6IHVua25vd24iLCJoYW5kbGVTZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2Z1c2UuanMvZGlzdC9mdXNlLm1qcyIsIi4uLy4uLy4uL3NyYy9ob29rcy9TZWFyY2gvdXNlU2VhcmNoSW5wdXQudHMiLCIuLi8uLi8uLi9zcmMvYXRvbXMvc2VhcmNoL3Byb2R1Y3RSZXRyaWV2YWxBZGFwdGVyLnRzIiwiLi4vLi4vLi4vc3JjL2F0b21zL3NlYXJjaC9wcm9kdWN0UmV0cmlldmFsQVBJLnRzIiwiLi4vLi4vLi4vc3JjL2hvb2tzL1NlYXJjaC91c2VSZWNvbW1lbmRlZFByb2R1Y3RzLnRzIiwiLi4vLi4vLi4vc3JjL2hvb2tzL1NlYXJjaC91c2VTZWFyY2gudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRnVzZS5qcyB2Ny4xLjAgLSBMaWdodHdlaWdodCBmdXp6eS1zZWFyY2ggKGh0dHA6Ly9mdXNlanMuaW8pXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDI1IEtpcm8gUmlzayAoaHR0cDovL2tpcm8ubWUpXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLiBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSAyLjBcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqL1xuXG5mdW5jdGlvbiBpc0FycmF5KHZhbHVlKSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheVxuICAgID8gZ2V0VGFnKHZhbHVlKSA9PT0gJ1tvYmplY3QgQXJyYXldJ1xuICAgIDogQXJyYXkuaXNBcnJheSh2YWx1ZSlcbn1cblxuLy8gQWRhcHRlZCBmcm9tOiBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iL21hc3Rlci8uaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzXG5jb25zdCBJTkZJTklUWSA9IDEgLyAwO1xuZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7XG4gIC8vIEV4aXQgZWFybHkgZm9yIHN0cmluZ3MgdG8gYXZvaWQgYSBwZXJmb3JtYW5jZSBoaXQgaW4gc29tZSBlbnZpcm9ubWVudHMuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuICBsZXQgcmVzdWx0ID0gdmFsdWUgKyAnJztcbiAgcmV0dXJuIHJlc3VsdCA9PSAnMCcgJiYgMSAvIHZhbHVlID09IC1JTkZJTklUWSA/ICctMCcgOiByZXN1bHRcbn1cblxuZnVuY3Rpb24gdG9TdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09IG51bGwgPyAnJyA6IGJhc2VUb1N0cmluZyh2YWx1ZSlcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZydcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcidcbn1cblxuLy8gQWRhcHRlZCBmcm9tOiBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iL21hc3Rlci9pc0Jvb2xlYW4uanNcbmZ1bmN0aW9uIGlzQm9vbGVhbih2YWx1ZSkge1xuICByZXR1cm4gKFxuICAgIHZhbHVlID09PSB0cnVlIHx8XG4gICAgdmFsdWUgPT09IGZhbHNlIHx8XG4gICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSAnW29iamVjdCBCb29sZWFuXScpXG4gIClcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCdcbn1cblxuLy8gQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSAmJiB2YWx1ZSAhPT0gbnVsbFxufVxuXG5mdW5jdGlvbiBpc0RlZmluZWQodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGxcbn1cblxuZnVuY3Rpb24gaXNCbGFuayh2YWx1ZSkge1xuICByZXR1cm4gIXZhbHVlLnRyaW0oKS5sZW5ndGhcbn1cblxuLy8gR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLlxuLy8gQWRhcHRlZCBmcm9tOiBodHRwczovL2dpdGh1Yi5jb20vbG9kYXNoL2xvZGFzaC9ibG9iL21hc3Rlci8uaW50ZXJuYWwvZ2V0VGFnLmpzXG5mdW5jdGlvbiBnZXRUYWcodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICA/IHZhbHVlID09PSB1bmRlZmluZWRcbiAgICAgID8gJ1tvYmplY3QgVW5kZWZpbmVkXSdcbiAgICAgIDogJ1tvYmplY3QgTnVsbF0nXG4gICAgOiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpXG59XG5cbmNvbnN0IEVYVEVOREVEX1NFQVJDSF9VTkFWQUlMQUJMRSA9ICdFeHRlbmRlZCBzZWFyY2ggaXMgbm90IGF2YWlsYWJsZSc7XG5cbmNvbnN0IElOQ09SUkVDVF9JTkRFWF9UWVBFID0gXCJJbmNvcnJlY3QgJ2luZGV4JyB0eXBlXCI7XG5cbmNvbnN0IExPR0lDQUxfU0VBUkNIX0lOVkFMSURfUVVFUllfRk9SX0tFWSA9IChrZXkpID0+XG4gIGBJbnZhbGlkIHZhbHVlIGZvciBrZXkgJHtrZXl9YDtcblxuY29uc3QgUEFUVEVSTl9MRU5HVEhfVE9PX0xBUkdFID0gKG1heCkgPT5cbiAgYFBhdHRlcm4gbGVuZ3RoIGV4Y2VlZHMgbWF4IG9mICR7bWF4fS5gO1xuXG5jb25zdCBNSVNTSU5HX0tFWV9QUk9QRVJUWSA9IChuYW1lKSA9PiBgTWlzc2luZyAke25hbWV9IHByb3BlcnR5IGluIGtleWA7XG5cbmNvbnN0IElOVkFMSURfS0VZX1dFSUdIVF9WQUxVRSA9IChrZXkpID0+XG4gIGBQcm9wZXJ0eSAnd2VpZ2h0JyBpbiBrZXkgJyR7a2V5fScgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXJgO1xuXG5jb25zdCBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5jbGFzcyBLZXlTdG9yZSB7XG4gIGNvbnN0cnVjdG9yKGtleXMpIHtcbiAgICB0aGlzLl9rZXlzID0gW107XG4gICAgdGhpcy5fa2V5TWFwID0ge307XG5cbiAgICBsZXQgdG90YWxXZWlnaHQgPSAwO1xuXG4gICAga2V5cy5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGxldCBvYmogPSBjcmVhdGVLZXkoa2V5KTtcblxuICAgICAgdGhpcy5fa2V5cy5wdXNoKG9iaik7XG4gICAgICB0aGlzLl9rZXlNYXBbb2JqLmlkXSA9IG9iajtcblxuICAgICAgdG90YWxXZWlnaHQgKz0gb2JqLndlaWdodDtcbiAgICB9KTtcblxuICAgIC8vIE5vcm1hbGl6ZSB3ZWlnaHRzIHNvIHRoYXQgdGhlaXIgc3VtIGlzIGVxdWFsIHRvIDFcbiAgICB0aGlzLl9rZXlzLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAga2V5LndlaWdodCAvPSB0b3RhbFdlaWdodDtcbiAgICB9KTtcbiAgfVxuICBnZXQoa2V5SWQpIHtcbiAgICByZXR1cm4gdGhpcy5fa2V5TWFwW2tleUlkXVxuICB9XG4gIGtleXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2tleXNcbiAgfVxuICB0b0pTT04oKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuX2tleXMpXG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlS2V5KGtleSkge1xuICBsZXQgcGF0aCA9IG51bGw7XG4gIGxldCBpZCA9IG51bGw7XG4gIGxldCBzcmMgPSBudWxsO1xuICBsZXQgd2VpZ2h0ID0gMTtcbiAgbGV0IGdldEZuID0gbnVsbDtcblxuICBpZiAoaXNTdHJpbmcoa2V5KSB8fCBpc0FycmF5KGtleSkpIHtcbiAgICBzcmMgPSBrZXk7XG4gICAgcGF0aCA9IGNyZWF0ZUtleVBhdGgoa2V5KTtcbiAgICBpZCA9IGNyZWF0ZUtleUlkKGtleSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFoYXNPd24uY2FsbChrZXksICduYW1lJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihNSVNTSU5HX0tFWV9QUk9QRVJUWSgnbmFtZScpKVxuICAgIH1cblxuICAgIGNvbnN0IG5hbWUgPSBrZXkubmFtZTtcbiAgICBzcmMgPSBuYW1lO1xuXG4gICAgaWYgKGhhc093bi5jYWxsKGtleSwgJ3dlaWdodCcpKSB7XG4gICAgICB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuXG4gICAgICBpZiAod2VpZ2h0IDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKElOVkFMSURfS0VZX1dFSUdIVF9WQUxVRShuYW1lKSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYXRoID0gY3JlYXRlS2V5UGF0aChuYW1lKTtcbiAgICBpZCA9IGNyZWF0ZUtleUlkKG5hbWUpO1xuICAgIGdldEZuID0ga2V5LmdldEZuO1xuICB9XG5cbiAgcmV0dXJuIHsgcGF0aCwgaWQsIHdlaWdodCwgc3JjLCBnZXRGbiB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUtleVBhdGgoa2V5KSB7XG4gIHJldHVybiBpc0FycmF5KGtleSkgPyBrZXkgOiBrZXkuc3BsaXQoJy4nKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVLZXlJZChrZXkpIHtcbiAgcmV0dXJuIGlzQXJyYXkoa2V5KSA/IGtleS5qb2luKCcuJykgOiBrZXlcbn1cblxuZnVuY3Rpb24gZ2V0KG9iaiwgcGF0aCkge1xuICBsZXQgbGlzdCA9IFtdO1xuICBsZXQgYXJyID0gZmFsc2U7XG5cbiAgY29uc3QgZGVlcEdldCA9IChvYmosIHBhdGgsIGluZGV4KSA9PiB7XG4gICAgaWYgKCFpc0RlZmluZWQob2JqKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmICghcGF0aFtpbmRleF0pIHtcbiAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gcGF0aCBsZWZ0LCB3ZSd2ZSBhcnJpdmVkIGF0IHRoZSBvYmplY3Qgd2UgY2FyZSBhYm91dC5cbiAgICAgIGxpc3QucHVzaChvYmopO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQga2V5ID0gcGF0aFtpbmRleF07XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gb2JqW2tleV07XG5cbiAgICAgIGlmICghaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLy8gSWYgd2UncmUgYXQgdGhlIGxhc3QgdmFsdWUgaW4gdGhlIHBhdGgsIGFuZCBpZiBpdCdzIGEgc3RyaW5nL251bWJlci9ib29sLFxuICAgICAgLy8gYWRkIGl0IHRvIHRoZSBsaXN0XG4gICAgICBpZiAoXG4gICAgICAgIGluZGV4ID09PSBwYXRoLmxlbmd0aCAtIDEgJiZcbiAgICAgICAgKGlzU3RyaW5nKHZhbHVlKSB8fCBpc051bWJlcih2YWx1ZSkgfHwgaXNCb29sZWFuKHZhbHVlKSlcbiAgICAgICkge1xuICAgICAgICBsaXN0LnB1c2godG9TdHJpbmcodmFsdWUpKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgYXJyID0gdHJ1ZTtcbiAgICAgICAgLy8gU2VhcmNoIGVhY2ggaXRlbSBpbiB0aGUgYXJyYXkuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSB2YWx1ZS5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICAgIGRlZXBHZXQodmFsdWVbaV0sIHBhdGgsIGluZGV4ICsgMSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAocGF0aC5sZW5ndGgpIHtcbiAgICAgICAgLy8gQW4gb2JqZWN0LiBSZWN1cnNlIGZ1cnRoZXIuXG4gICAgICAgIGRlZXBHZXQodmFsdWUsIHBhdGgsIGluZGV4ICsgMSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IChzaW5jZSBwYXRoIHVzZWQgdG8gYmUgYSBzdHJpbmcpXG4gIGRlZXBHZXQob2JqLCBpc1N0cmluZyhwYXRoKSA/IHBhdGguc3BsaXQoJy4nKSA6IHBhdGgsIDApO1xuXG4gIHJldHVybiBhcnIgPyBsaXN0IDogbGlzdFswXVxufVxuXG5jb25zdCBNYXRjaE9wdGlvbnMgPSB7XG4gIC8vIFdoZXRoZXIgdGhlIG1hdGNoZXMgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSByZXN1bHQgc2V0LiBXaGVuIGB0cnVlYCwgZWFjaCByZWNvcmQgaW4gdGhlIHJlc3VsdFxuICAvLyBzZXQgd2lsbCBpbmNsdWRlIHRoZSBpbmRpY2VzIG9mIHRoZSBtYXRjaGVkIGNoYXJhY3RlcnMuXG4gIC8vIFRoZXNlIGNhbiBjb25zZXF1ZW50bHkgYmUgdXNlZCBmb3IgaGlnaGxpZ2h0aW5nIHB1cnBvc2VzLlxuICBpbmNsdWRlTWF0Y2hlczogZmFsc2UsXG4gIC8vIFdoZW4gYHRydWVgLCB0aGUgbWF0Y2hpbmcgZnVuY3Rpb24gd2lsbCBjb250aW51ZSB0byB0aGUgZW5kIG9mIGEgc2VhcmNoIHBhdHRlcm4gZXZlbiBpZlxuICAvLyBhIHBlcmZlY3QgbWF0Y2ggaGFzIGFscmVhZHkgYmVlbiBsb2NhdGVkIGluIHRoZSBzdHJpbmcuXG4gIGZpbmRBbGxNYXRjaGVzOiBmYWxzZSxcbiAgLy8gTWluaW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IG11c3QgYmUgbWF0Y2hlZCBiZWZvcmUgYSByZXN1bHQgaXMgY29uc2lkZXJlZCBhIG1hdGNoXG4gIG1pbk1hdGNoQ2hhckxlbmd0aDogMVxufTtcblxuY29uc3QgQmFzaWNPcHRpb25zID0ge1xuICAvLyBXaGVuIGB0cnVlYCwgdGhlIGFsZ29yaXRobSBjb250aW51ZXMgc2VhcmNoaW5nIHRvIHRoZSBlbmQgb2YgdGhlIGlucHV0IGV2ZW4gaWYgYSBwZXJmZWN0XG4gIC8vIG1hdGNoIGlzIGZvdW5kIGJlZm9yZSB0aGUgZW5kIG9mIHRoZSBzYW1lIGlucHV0LlxuICBpc0Nhc2VTZW5zaXRpdmU6IGZhbHNlLFxuICAvLyBXaGVuIGB0cnVlYCwgdGhlIGFsZ29yaXRobSB3aWxsIGlnbm9yZSBkaWFjcml0aWNzIChhY2NlbnRzKSBpbiBjb21wYXJpc29uc1xuICBpZ25vcmVEaWFjcml0aWNzOiBmYWxzZSxcbiAgLy8gV2hlbiB0cnVlLCB0aGUgbWF0Y2hpbmcgZnVuY3Rpb24gd2lsbCBjb250aW51ZSB0byB0aGUgZW5kIG9mIGEgc2VhcmNoIHBhdHRlcm4gZXZlbiBpZlxuICBpbmNsdWRlU2NvcmU6IGZhbHNlLFxuICAvLyBMaXN0IG9mIHByb3BlcnRpZXMgdGhhdCB3aWxsIGJlIHNlYXJjaGVkLiBUaGlzIGFsc28gc3VwcG9ydHMgbmVzdGVkIHByb3BlcnRpZXMuXG4gIGtleXM6IFtdLFxuICAvLyBXaGV0aGVyIHRvIHNvcnQgdGhlIHJlc3VsdCBsaXN0LCBieSBzY29yZVxuICBzaG91bGRTb3J0OiB0cnVlLFxuICAvLyBEZWZhdWx0IHNvcnQgZnVuY3Rpb246IHNvcnQgYnkgYXNjZW5kaW5nIHNjb3JlLCBhc2NlbmRpbmcgaW5kZXhcbiAgc29ydEZuOiAoYSwgYikgPT5cbiAgICBhLnNjb3JlID09PSBiLnNjb3JlID8gKGEuaWR4IDwgYi5pZHggPyAtMSA6IDEpIDogYS5zY29yZSA8IGIuc2NvcmUgPyAtMSA6IDFcbn07XG5cbmNvbnN0IEZ1enp5T3B0aW9ucyA9IHtcbiAgLy8gQXBwcm94aW1hdGVseSB3aGVyZSBpbiB0aGUgdGV4dCBpcyB0aGUgcGF0dGVybiBleHBlY3RlZCB0byBiZSBmb3VuZD9cbiAgbG9jYXRpb246IDAsXG4gIC8vIEF0IHdoYXQgcG9pbnQgZG9lcyB0aGUgbWF0Y2ggYWxnb3JpdGhtIGdpdmUgdXAuIEEgdGhyZXNob2xkIG9mICcwLjAnIHJlcXVpcmVzIGEgcGVyZmVjdCBtYXRjaFxuICAvLyAob2YgYm90aCBsZXR0ZXJzIGFuZCBsb2NhdGlvbiksIGEgdGhyZXNob2xkIG9mICcxLjAnIHdvdWxkIG1hdGNoIGFueXRoaW5nLlxuICB0aHJlc2hvbGQ6IDAuNixcbiAgLy8gRGV0ZXJtaW5lcyBob3cgY2xvc2UgdGhlIG1hdGNoIG11c3QgYmUgdG8gdGhlIGZ1enp5IGxvY2F0aW9uIChzcGVjaWZpZWQgYWJvdmUpLlxuICAvLyBBbiBleGFjdCBsZXR0ZXIgbWF0Y2ggd2hpY2ggaXMgJ2Rpc3RhbmNlJyBjaGFyYWN0ZXJzIGF3YXkgZnJvbSB0aGUgZnV6enkgbG9jYXRpb25cbiAgLy8gd291bGQgc2NvcmUgYXMgYSBjb21wbGV0ZSBtaXNtYXRjaC4gQSBkaXN0YW5jZSBvZiAnMCcgcmVxdWlyZXMgdGhlIG1hdGNoIGJlIGF0XG4gIC8vIHRoZSBleGFjdCBsb2NhdGlvbiBzcGVjaWZpZWQsIGEgdGhyZXNob2xkIG9mICcxMDAwJyB3b3VsZCByZXF1aXJlIGEgcGVyZmVjdCBtYXRjaFxuICAvLyB0byBiZSB3aXRoaW4gODAwIGNoYXJhY3RlcnMgb2YgdGhlIGZ1enp5IGxvY2F0aW9uIHRvIGJlIGZvdW5kIHVzaW5nIGEgMC44IHRocmVzaG9sZC5cbiAgZGlzdGFuY2U6IDEwMFxufTtcblxuY29uc3QgQWR2YW5jZWRPcHRpb25zID0ge1xuICAvLyBXaGVuIGB0cnVlYCwgaXQgZW5hYmxlcyB0aGUgdXNlIG9mIHVuaXgtbGlrZSBzZWFyY2ggY29tbWFuZHNcbiAgdXNlRXh0ZW5kZWRTZWFyY2g6IGZhbHNlLFxuICAvLyBUaGUgZ2V0IGZ1bmN0aW9uIHRvIHVzZSB3aGVuIGZldGNoaW5nIGFuIG9iamVjdCdzIHByb3BlcnRpZXMuXG4gIC8vIFRoZSBkZWZhdWx0IHdpbGwgc2VhcmNoIG5lc3RlZCBwYXRocyAqaWUgZm9vLmJhci5iYXoqXG4gIGdldEZuOiBnZXQsXG4gIC8vIFdoZW4gYHRydWVgLCBzZWFyY2ggd2lsbCBpZ25vcmUgYGxvY2F0aW9uYCBhbmQgYGRpc3RhbmNlYCwgc28gaXQgd29uJ3QgbWF0dGVyXG4gIC8vIHdoZXJlIGluIHRoZSBzdHJpbmcgdGhlIHBhdHRlcm4gYXBwZWFycy5cbiAgLy8gTW9yZSBpbmZvOiBodHRwczovL2Z1c2Vqcy5pby9jb25jZXB0cy9zY29yaW5nLXRoZW9yeS5odG1sI2Z1enppbmVzcy1zY29yZVxuICBpZ25vcmVMb2NhdGlvbjogZmFsc2UsXG4gIC8vIFdoZW4gYHRydWVgLCB0aGUgY2FsY3VsYXRpb24gZm9yIHRoZSByZWxldmFuY2Ugc2NvcmUgKHVzZWQgZm9yIHNvcnRpbmcpIHdpbGxcbiAgLy8gaWdub3JlIHRoZSBmaWVsZC1sZW5ndGggbm9ybS5cbiAgLy8gTW9yZSBpbmZvOiBodHRwczovL2Z1c2Vqcy5pby9jb25jZXB0cy9zY29yaW5nLXRoZW9yeS5odG1sI2ZpZWxkLWxlbmd0aC1ub3JtXG4gIGlnbm9yZUZpZWxkTm9ybTogZmFsc2UsXG4gIC8vIFRoZSB3ZWlnaHQgdG8gZGV0ZXJtaW5lIGhvdyBtdWNoIGZpZWxkIGxlbmd0aCBub3JtIGVmZmVjdHMgc2NvcmluZy5cbiAgZmllbGROb3JtV2VpZ2h0OiAxXG59O1xuXG52YXIgQ29uZmlnID0ge1xuICAuLi5CYXNpY09wdGlvbnMsXG4gIC4uLk1hdGNoT3B0aW9ucyxcbiAgLi4uRnV6enlPcHRpb25zLFxuICAuLi5BZHZhbmNlZE9wdGlvbnNcbn07XG5cbmNvbnN0IFNQQUNFID0gL1teIF0rL2c7XG5cbi8vIEZpZWxkLWxlbmd0aCBub3JtOiB0aGUgc2hvcnRlciB0aGUgZmllbGQsIHRoZSBoaWdoZXIgdGhlIHdlaWdodC5cbi8vIFNldCB0byAzIGRlY2ltYWxzIHRvIHJlZHVjZSBpbmRleCBzaXplLlxuZnVuY3Rpb24gbm9ybSh3ZWlnaHQgPSAxLCBtYW50aXNzYSA9IDMpIHtcbiAgY29uc3QgY2FjaGUgPSBuZXcgTWFwKCk7XG4gIGNvbnN0IG0gPSBNYXRoLnBvdygxMCwgbWFudGlzc2EpO1xuXG4gIHJldHVybiB7XG4gICAgZ2V0KHZhbHVlKSB7XG4gICAgICBjb25zdCBudW1Ub2tlbnMgPSB2YWx1ZS5tYXRjaChTUEFDRSkubGVuZ3RoO1xuXG4gICAgICBpZiAoY2FjaGUuaGFzKG51bVRva2VucykpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlLmdldChudW1Ub2tlbnMpXG4gICAgICB9XG5cbiAgICAgIC8vIERlZmF1bHQgZnVuY3Rpb24gaXMgMS9zcXJ0KHgpLCB3ZWlnaHQgbWFrZXMgdGhhdCB2YXJpYWJsZVxuICAgICAgY29uc3Qgbm9ybSA9IDEgLyBNYXRoLnBvdyhudW1Ub2tlbnMsIDAuNSAqIHdlaWdodCk7XG5cbiAgICAgIC8vIEluIHBsYWNlIG9mIGB0b0ZpeGVkKG1hbnRpc3NhKWAsIGZvciBmYXN0ZXIgY29tcHV0YXRpb25cbiAgICAgIGNvbnN0IG4gPSBwYXJzZUZsb2F0KE1hdGgucm91bmQobm9ybSAqIG0pIC8gbSk7XG5cbiAgICAgIGNhY2hlLnNldChudW1Ub2tlbnMsIG4pO1xuXG4gICAgICByZXR1cm4gblxuICAgIH0sXG4gICAgY2xlYXIoKSB7XG4gICAgICBjYWNoZS5jbGVhcigpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBGdXNlSW5kZXgge1xuICBjb25zdHJ1Y3Rvcih7XG4gICAgZ2V0Rm4gPSBDb25maWcuZ2V0Rm4sXG4gICAgZmllbGROb3JtV2VpZ2h0ID0gQ29uZmlnLmZpZWxkTm9ybVdlaWdodFxuICB9ID0ge30pIHtcbiAgICB0aGlzLm5vcm0gPSBub3JtKGZpZWxkTm9ybVdlaWdodCwgMyk7XG4gICAgdGhpcy5nZXRGbiA9IGdldEZuO1xuICAgIHRoaXMuaXNDcmVhdGVkID0gZmFsc2U7XG5cbiAgICB0aGlzLnNldEluZGV4UmVjb3JkcygpO1xuICB9XG4gIHNldFNvdXJjZXMoZG9jcyA9IFtdKSB7XG4gICAgdGhpcy5kb2NzID0gZG9jcztcbiAgfVxuICBzZXRJbmRleFJlY29yZHMocmVjb3JkcyA9IFtdKSB7XG4gICAgdGhpcy5yZWNvcmRzID0gcmVjb3JkcztcbiAgfVxuICBzZXRLZXlzKGtleXMgPSBbXSkge1xuICAgIHRoaXMua2V5cyA9IGtleXM7XG4gICAgdGhpcy5fa2V5c01hcCA9IHt9O1xuICAgIGtleXMuZm9yRWFjaCgoa2V5LCBpZHgpID0+IHtcbiAgICAgIHRoaXMuX2tleXNNYXBba2V5LmlkXSA9IGlkeDtcbiAgICB9KTtcbiAgfVxuICBjcmVhdGUoKSB7XG4gICAgaWYgKHRoaXMuaXNDcmVhdGVkIHx8ICF0aGlzLmRvY3MubGVuZ3RoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmlzQ3JlYXRlZCA9IHRydWU7XG5cbiAgICAvLyBMaXN0IGlzIEFycmF5PFN0cmluZz5cbiAgICBpZiAoaXNTdHJpbmcodGhpcy5kb2NzWzBdKSkge1xuICAgICAgdGhpcy5kb2NzLmZvckVhY2goKGRvYywgZG9jSW5kZXgpID0+IHtcbiAgICAgICAgdGhpcy5fYWRkU3RyaW5nKGRvYywgZG9jSW5kZXgpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIExpc3QgaXMgQXJyYXk8T2JqZWN0PlxuICAgICAgdGhpcy5kb2NzLmZvckVhY2goKGRvYywgZG9jSW5kZXgpID0+IHtcbiAgICAgICAgdGhpcy5fYWRkT2JqZWN0KGRvYywgZG9jSW5kZXgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5ub3JtLmNsZWFyKCk7XG4gIH1cbiAgLy8gQWRkcyBhIGRvYyB0byB0aGUgZW5kIG9mIHRoZSBpbmRleFxuICBhZGQoZG9jKSB7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5zaXplKCk7XG5cbiAgICBpZiAoaXNTdHJpbmcoZG9jKSkge1xuICAgICAgdGhpcy5fYWRkU3RyaW5nKGRvYywgaWR4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYWRkT2JqZWN0KGRvYywgaWR4KTtcbiAgICB9XG4gIH1cbiAgLy8gUmVtb3ZlcyB0aGUgZG9jIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXggb2YgdGhlIGluZGV4XG4gIHJlbW92ZUF0KGlkeCkge1xuICAgIHRoaXMucmVjb3Jkcy5zcGxpY2UoaWR4LCAxKTtcblxuICAgIC8vIENoYW5nZSByZWYgaW5kZXggb2YgZXZlcnkgc3Vic3F1ZW50IGRvY1xuICAgIGZvciAobGV0IGkgPSBpZHgsIGxlbiA9IHRoaXMuc2l6ZSgpOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIHRoaXMucmVjb3Jkc1tpXS5pIC09IDE7XG4gICAgfVxuICB9XG4gIGdldFZhbHVlRm9ySXRlbUF0S2V5SWQoaXRlbSwga2V5SWQpIHtcbiAgICByZXR1cm4gaXRlbVt0aGlzLl9rZXlzTWFwW2tleUlkXV1cbiAgfVxuICBzaXplKCkge1xuICAgIHJldHVybiB0aGlzLnJlY29yZHMubGVuZ3RoXG4gIH1cbiAgX2FkZFN0cmluZyhkb2MsIGRvY0luZGV4KSB7XG4gICAgaWYgKCFpc0RlZmluZWQoZG9jKSB8fCBpc0JsYW5rKGRvYykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGxldCByZWNvcmQgPSB7XG4gICAgICB2OiBkb2MsXG4gICAgICBpOiBkb2NJbmRleCxcbiAgICAgIG46IHRoaXMubm9ybS5nZXQoZG9jKVxuICAgIH07XG5cbiAgICB0aGlzLnJlY29yZHMucHVzaChyZWNvcmQpO1xuICB9XG4gIF9hZGRPYmplY3QoZG9jLCBkb2NJbmRleCkge1xuICAgIGxldCByZWNvcmQgPSB7IGk6IGRvY0luZGV4LCAkOiB7fSB9O1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIGV2ZXJ5IGtleSAoaS5lLCBwYXRoKSwgYW5kIGZldGNoIHRoZSB2YWx1ZSBhdCB0aGF0IGtleVxuICAgIHRoaXMua2V5cy5mb3JFYWNoKChrZXksIGtleUluZGV4KSA9PiB7XG4gICAgICBsZXQgdmFsdWUgPSBrZXkuZ2V0Rm4gPyBrZXkuZ2V0Rm4oZG9jKSA6IHRoaXMuZ2V0Rm4oZG9jLCBrZXkucGF0aCk7XG5cbiAgICAgIGlmICghaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGxldCBzdWJSZWNvcmRzID0gW107XG4gICAgICAgIGNvbnN0IHN0YWNrID0gW3sgbmVzdGVkQXJySW5kZXg6IC0xLCB2YWx1ZSB9XTtcblxuICAgICAgICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgY29uc3QgeyBuZXN0ZWRBcnJJbmRleCwgdmFsdWUgfSA9IHN0YWNrLnBvcCgpO1xuXG4gICAgICAgICAgaWYgKCFpc0RlZmluZWQodmFsdWUpKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpc1N0cmluZyh2YWx1ZSkgJiYgIWlzQmxhbmsodmFsdWUpKSB7XG4gICAgICAgICAgICBsZXQgc3ViUmVjb3JkID0ge1xuICAgICAgICAgICAgICB2OiB2YWx1ZSxcbiAgICAgICAgICAgICAgaTogbmVzdGVkQXJySW5kZXgsXG4gICAgICAgICAgICAgIG46IHRoaXMubm9ybS5nZXQodmFsdWUpXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBzdWJSZWNvcmRzLnB1c2goc3ViUmVjb3JkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICB2YWx1ZS5mb3JFYWNoKChpdGVtLCBrKSA9PiB7XG4gICAgICAgICAgICAgIHN0YWNrLnB1c2goe1xuICAgICAgICAgICAgICAgIG5lc3RlZEFyckluZGV4OiBrLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBpdGVtXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIDtcbiAgICAgICAgfVxuICAgICAgICByZWNvcmQuJFtrZXlJbmRleF0gPSBzdWJSZWNvcmRzO1xuICAgICAgfSBlbHNlIGlmIChpc1N0cmluZyh2YWx1ZSkgJiYgIWlzQmxhbmsodmFsdWUpKSB7XG4gICAgICAgIGxldCBzdWJSZWNvcmQgPSB7XG4gICAgICAgICAgdjogdmFsdWUsXG4gICAgICAgICAgbjogdGhpcy5ub3JtLmdldCh2YWx1ZSlcbiAgICAgICAgfTtcblxuICAgICAgICByZWNvcmQuJFtrZXlJbmRleF0gPSBzdWJSZWNvcmQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnJlY29yZHMucHVzaChyZWNvcmQpO1xuICB9XG4gIHRvSlNPTigpIHtcbiAgICByZXR1cm4ge1xuICAgICAga2V5czogdGhpcy5rZXlzLFxuICAgICAgcmVjb3JkczogdGhpcy5yZWNvcmRzXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUluZGV4KFxuICBrZXlzLFxuICBkb2NzLFxuICB7IGdldEZuID0gQ29uZmlnLmdldEZuLCBmaWVsZE5vcm1XZWlnaHQgPSBDb25maWcuZmllbGROb3JtV2VpZ2h0IH0gPSB7fVxuKSB7XG4gIGNvbnN0IG15SW5kZXggPSBuZXcgRnVzZUluZGV4KHsgZ2V0Rm4sIGZpZWxkTm9ybVdlaWdodCB9KTtcbiAgbXlJbmRleC5zZXRLZXlzKGtleXMubWFwKGNyZWF0ZUtleSkpO1xuICBteUluZGV4LnNldFNvdXJjZXMoZG9jcyk7XG4gIG15SW5kZXguY3JlYXRlKCk7XG4gIHJldHVybiBteUluZGV4XG59XG5cbmZ1bmN0aW9uIHBhcnNlSW5kZXgoXG4gIGRhdGEsXG4gIHsgZ2V0Rm4gPSBDb25maWcuZ2V0Rm4sIGZpZWxkTm9ybVdlaWdodCA9IENvbmZpZy5maWVsZE5vcm1XZWlnaHQgfSA9IHt9XG4pIHtcbiAgY29uc3QgeyBrZXlzLCByZWNvcmRzIH0gPSBkYXRhO1xuICBjb25zdCBteUluZGV4ID0gbmV3IEZ1c2VJbmRleCh7IGdldEZuLCBmaWVsZE5vcm1XZWlnaHQgfSk7XG4gIG15SW5kZXguc2V0S2V5cyhrZXlzKTtcbiAgbXlJbmRleC5zZXRJbmRleFJlY29yZHMocmVjb3Jkcyk7XG4gIHJldHVybiBteUluZGV4XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVTY29yZSQxKFxuICBwYXR0ZXJuLFxuICB7XG4gICAgZXJyb3JzID0gMCxcbiAgICBjdXJyZW50TG9jYXRpb24gPSAwLFxuICAgIGV4cGVjdGVkTG9jYXRpb24gPSAwLFxuICAgIGRpc3RhbmNlID0gQ29uZmlnLmRpc3RhbmNlLFxuICAgIGlnbm9yZUxvY2F0aW9uID0gQ29uZmlnLmlnbm9yZUxvY2F0aW9uXG4gIH0gPSB7fVxuKSB7XG4gIGNvbnN0IGFjY3VyYWN5ID0gZXJyb3JzIC8gcGF0dGVybi5sZW5ndGg7XG5cbiAgaWYgKGlnbm9yZUxvY2F0aW9uKSB7XG4gICAgcmV0dXJuIGFjY3VyYWN5XG4gIH1cblxuICBjb25zdCBwcm94aW1pdHkgPSBNYXRoLmFicyhleHBlY3RlZExvY2F0aW9uIC0gY3VycmVudExvY2F0aW9uKTtcblxuICBpZiAoIWRpc3RhbmNlKSB7XG4gICAgLy8gRG9kZ2UgZGl2aWRlIGJ5IHplcm8gZXJyb3IuXG4gICAgcmV0dXJuIHByb3hpbWl0eSA/IDEuMCA6IGFjY3VyYWN5XG4gIH1cblxuICByZXR1cm4gYWNjdXJhY3kgKyBwcm94aW1pdHkgLyBkaXN0YW5jZVxufVxuXG5mdW5jdGlvbiBjb252ZXJ0TWFza1RvSW5kaWNlcyhcbiAgbWF0Y2htYXNrID0gW10sXG4gIG1pbk1hdGNoQ2hhckxlbmd0aCA9IENvbmZpZy5taW5NYXRjaENoYXJMZW5ndGhcbikge1xuICBsZXQgaW5kaWNlcyA9IFtdO1xuICBsZXQgc3RhcnQgPSAtMTtcbiAgbGV0IGVuZCA9IC0xO1xuICBsZXQgaSA9IDA7XG5cbiAgZm9yIChsZXQgbGVuID0gbWF0Y2htYXNrLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgbGV0IG1hdGNoID0gbWF0Y2htYXNrW2ldO1xuICAgIGlmIChtYXRjaCAmJiBzdGFydCA9PT0gLTEpIHtcbiAgICAgIHN0YXJ0ID0gaTtcbiAgICB9IGVsc2UgaWYgKCFtYXRjaCAmJiBzdGFydCAhPT0gLTEpIHtcbiAgICAgIGVuZCA9IGkgLSAxO1xuICAgICAgaWYgKGVuZCAtIHN0YXJ0ICsgMSA+PSBtaW5NYXRjaENoYXJMZW5ndGgpIHtcbiAgICAgICAgaW5kaWNlcy5wdXNoKFtzdGFydCwgZW5kXSk7XG4gICAgICB9XG4gICAgICBzdGFydCA9IC0xO1xuICAgIH1cbiAgfVxuXG4gIC8vIChpLTEgLSBzdGFydCkgKyAxID0+IGkgLSBzdGFydFxuICBpZiAobWF0Y2htYXNrW2kgLSAxXSAmJiBpIC0gc3RhcnQgPj0gbWluTWF0Y2hDaGFyTGVuZ3RoKSB7XG4gICAgaW5kaWNlcy5wdXNoKFtzdGFydCwgaSAtIDFdKTtcbiAgfVxuXG4gIHJldHVybiBpbmRpY2VzXG59XG5cbi8vIE1hY2hpbmUgd29yZCBzaXplXG5jb25zdCBNQVhfQklUUyA9IDMyO1xuXG5mdW5jdGlvbiBzZWFyY2goXG4gIHRleHQsXG4gIHBhdHRlcm4sXG4gIHBhdHRlcm5BbHBoYWJldCxcbiAge1xuICAgIGxvY2F0aW9uID0gQ29uZmlnLmxvY2F0aW9uLFxuICAgIGRpc3RhbmNlID0gQ29uZmlnLmRpc3RhbmNlLFxuICAgIHRocmVzaG9sZCA9IENvbmZpZy50aHJlc2hvbGQsXG4gICAgZmluZEFsbE1hdGNoZXMgPSBDb25maWcuZmluZEFsbE1hdGNoZXMsXG4gICAgbWluTWF0Y2hDaGFyTGVuZ3RoID0gQ29uZmlnLm1pbk1hdGNoQ2hhckxlbmd0aCxcbiAgICBpbmNsdWRlTWF0Y2hlcyA9IENvbmZpZy5pbmNsdWRlTWF0Y2hlcyxcbiAgICBpZ25vcmVMb2NhdGlvbiA9IENvbmZpZy5pZ25vcmVMb2NhdGlvblxuICB9ID0ge31cbikge1xuICBpZiAocGF0dGVybi5sZW5ndGggPiBNQVhfQklUUykge1xuICAgIHRocm93IG5ldyBFcnJvcihQQVRURVJOX0xFTkdUSF9UT09fTEFSR0UoTUFYX0JJVFMpKVxuICB9XG5cbiAgY29uc3QgcGF0dGVybkxlbiA9IHBhdHRlcm4ubGVuZ3RoO1xuICAvLyBTZXQgc3RhcnRpbmcgbG9jYXRpb24gYXQgYmVnaW5uaW5nIHRleHQgYW5kIGluaXRpYWxpemUgdGhlIGFscGhhYmV0LlxuICBjb25zdCB0ZXh0TGVuID0gdGV4dC5sZW5ndGg7XG4gIC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVuIGxvY2F0aW9uID4gdGV4dC5sZW5ndGhcbiAgY29uc3QgZXhwZWN0ZWRMb2NhdGlvbiA9IE1hdGgubWF4KDAsIE1hdGgubWluKGxvY2F0aW9uLCB0ZXh0TGVuKSk7XG4gIC8vIEhpZ2hlc3Qgc2NvcmUgYmV5b25kIHdoaWNoIHdlIGdpdmUgdXAuXG4gIGxldCBjdXJyZW50VGhyZXNob2xkID0gdGhyZXNob2xkO1xuICAvLyBJcyB0aGVyZSBhIG5lYXJieSBleGFjdCBtYXRjaD8gKHNwZWVkdXApXG4gIGxldCBiZXN0TG9jYXRpb24gPSBleHBlY3RlZExvY2F0aW9uO1xuXG4gIC8vIFBlcmZvcm1hbmNlOiBvbmx5IGNvbXB1dGVyIG1hdGNoZXMgd2hlbiB0aGUgbWluTWF0Y2hDaGFyTGVuZ3RoID4gMVxuICAvLyBPUiBpZiBgaW5jbHVkZU1hdGNoZXNgIGlzIHRydWUuXG4gIGNvbnN0IGNvbXB1dGVNYXRjaGVzID0gbWluTWF0Y2hDaGFyTGVuZ3RoID4gMSB8fCBpbmNsdWRlTWF0Y2hlcztcbiAgLy8gQSBtYXNrIG9mIHRoZSBtYXRjaGVzLCB1c2VkIGZvciBidWlsZGluZyB0aGUgaW5kaWNlc1xuICBjb25zdCBtYXRjaE1hc2sgPSBjb21wdXRlTWF0Y2hlcyA/IEFycmF5KHRleHRMZW4pIDogW107XG5cbiAgbGV0IGluZGV4O1xuXG4gIC8vIEdldCBhbGwgZXhhY3QgbWF0Y2hlcywgaGVyZSBmb3Igc3BlZWQgdXBcbiAgd2hpbGUgKChpbmRleCA9IHRleHQuaW5kZXhPZihwYXR0ZXJuLCBiZXN0TG9jYXRpb24pKSA+IC0xKSB7XG4gICAgbGV0IHNjb3JlID0gY29tcHV0ZVNjb3JlJDEocGF0dGVybiwge1xuICAgICAgY3VycmVudExvY2F0aW9uOiBpbmRleCxcbiAgICAgIGV4cGVjdGVkTG9jYXRpb24sXG4gICAgICBkaXN0YW5jZSxcbiAgICAgIGlnbm9yZUxvY2F0aW9uXG4gICAgfSk7XG5cbiAgICBjdXJyZW50VGhyZXNob2xkID0gTWF0aC5taW4oc2NvcmUsIGN1cnJlbnRUaHJlc2hvbGQpO1xuICAgIGJlc3RMb2NhdGlvbiA9IGluZGV4ICsgcGF0dGVybkxlbjtcblxuICAgIGlmIChjb21wdXRlTWF0Y2hlcykge1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgd2hpbGUgKGkgPCBwYXR0ZXJuTGVuKSB7XG4gICAgICAgIG1hdGNoTWFza1tpbmRleCArIGldID0gMTtcbiAgICAgICAgaSArPSAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFJlc2V0IHRoZSBiZXN0IGxvY2F0aW9uXG4gIGJlc3RMb2NhdGlvbiA9IC0xO1xuXG4gIGxldCBsYXN0Qml0QXJyID0gW107XG4gIGxldCBmaW5hbFNjb3JlID0gMTtcbiAgbGV0IGJpbk1heCA9IHBhdHRlcm5MZW4gKyB0ZXh0TGVuO1xuXG4gIGNvbnN0IG1hc2sgPSAxIDw8IChwYXR0ZXJuTGVuIC0gMSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXR0ZXJuTGVuOyBpICs9IDEpIHtcbiAgICAvLyBTY2FuIGZvciB0aGUgYmVzdCBtYXRjaDsgZWFjaCBpdGVyYXRpb24gYWxsb3dzIGZvciBvbmUgbW9yZSBlcnJvci5cbiAgICAvLyBSdW4gYSBiaW5hcnkgc2VhcmNoIHRvIGRldGVybWluZSBob3cgZmFyIGZyb20gdGhlIG1hdGNoIGxvY2F0aW9uIHdlIGNhbiBzdHJheVxuICAgIC8vIGF0IHRoaXMgZXJyb3IgbGV2ZWwuXG4gICAgbGV0IGJpbk1pbiA9IDA7XG4gICAgbGV0IGJpbk1pZCA9IGJpbk1heDtcblxuICAgIHdoaWxlIChiaW5NaW4gPCBiaW5NaWQpIHtcbiAgICAgIGNvbnN0IHNjb3JlID0gY29tcHV0ZVNjb3JlJDEocGF0dGVybiwge1xuICAgICAgICBlcnJvcnM6IGksXG4gICAgICAgIGN1cnJlbnRMb2NhdGlvbjogZXhwZWN0ZWRMb2NhdGlvbiArIGJpbk1pZCxcbiAgICAgICAgZXhwZWN0ZWRMb2NhdGlvbixcbiAgICAgICAgZGlzdGFuY2UsXG4gICAgICAgIGlnbm9yZUxvY2F0aW9uXG4gICAgICB9KTtcblxuICAgICAgaWYgKHNjb3JlIDw9IGN1cnJlbnRUaHJlc2hvbGQpIHtcbiAgICAgICAgYmluTWluID0gYmluTWlkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmluTWF4ID0gYmluTWlkO1xuICAgICAgfVxuXG4gICAgICBiaW5NaWQgPSBNYXRoLmZsb29yKChiaW5NYXggLSBiaW5NaW4pIC8gMiArIGJpbk1pbik7XG4gICAgfVxuXG4gICAgLy8gVXNlIHRoZSByZXN1bHQgZnJvbSB0aGlzIGl0ZXJhdGlvbiBhcyB0aGUgbWF4aW11bSBmb3IgdGhlIG5leHQuXG4gICAgYmluTWF4ID0gYmluTWlkO1xuXG4gICAgbGV0IHN0YXJ0ID0gTWF0aC5tYXgoMSwgZXhwZWN0ZWRMb2NhdGlvbiAtIGJpbk1pZCArIDEpO1xuICAgIGxldCBmaW5pc2ggPSBmaW5kQWxsTWF0Y2hlc1xuICAgICAgPyB0ZXh0TGVuXG4gICAgICA6IE1hdGgubWluKGV4cGVjdGVkTG9jYXRpb24gKyBiaW5NaWQsIHRleHRMZW4pICsgcGF0dGVybkxlbjtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIGJpdCBhcnJheVxuICAgIGxldCBiaXRBcnIgPSBBcnJheShmaW5pc2ggKyAyKTtcblxuICAgIGJpdEFycltmaW5pc2ggKyAxXSA9ICgxIDw8IGkpIC0gMTtcblxuICAgIGZvciAobGV0IGogPSBmaW5pc2g7IGogPj0gc3RhcnQ7IGogLT0gMSkge1xuICAgICAgbGV0IGN1cnJlbnRMb2NhdGlvbiA9IGogLSAxO1xuICAgICAgbGV0IGNoYXJNYXRjaCA9IHBhdHRlcm5BbHBoYWJldFt0ZXh0LmNoYXJBdChjdXJyZW50TG9jYXRpb24pXTtcblxuICAgICAgaWYgKGNvbXB1dGVNYXRjaGVzKSB7XG4gICAgICAgIC8vIFNwZWVkIHVwOiBxdWljayBib29sIHRvIGludCBjb252ZXJzaW9uIChpLmUsIGBjaGFyTWF0Y2ggPyAxIDogMGApXG4gICAgICAgIG1hdGNoTWFza1tjdXJyZW50TG9jYXRpb25dID0gKyEhY2hhck1hdGNoO1xuICAgICAgfVxuXG4gICAgICAvLyBGaXJzdCBwYXNzOiBleGFjdCBtYXRjaFxuICAgICAgYml0QXJyW2pdID0gKChiaXRBcnJbaiArIDFdIDw8IDEpIHwgMSkgJiBjaGFyTWF0Y2g7XG5cbiAgICAgIC8vIFN1YnNlcXVlbnQgcGFzc2VzOiBmdXp6eSBtYXRjaFxuICAgICAgaWYgKGkpIHtcbiAgICAgICAgYml0QXJyW2pdIHw9XG4gICAgICAgICAgKChsYXN0Qml0QXJyW2ogKyAxXSB8IGxhc3RCaXRBcnJbal0pIDw8IDEpIHwgMSB8IGxhc3RCaXRBcnJbaiArIDFdO1xuICAgICAgfVxuXG4gICAgICBpZiAoYml0QXJyW2pdICYgbWFzaykge1xuICAgICAgICBmaW5hbFNjb3JlID0gY29tcHV0ZVNjb3JlJDEocGF0dGVybiwge1xuICAgICAgICAgIGVycm9yczogaSxcbiAgICAgICAgICBjdXJyZW50TG9jYXRpb24sXG4gICAgICAgICAgZXhwZWN0ZWRMb2NhdGlvbixcbiAgICAgICAgICBkaXN0YW5jZSxcbiAgICAgICAgICBpZ25vcmVMb2NhdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBUaGlzIG1hdGNoIHdpbGwgYWxtb3N0IGNlcnRhaW5seSBiZSBiZXR0ZXIgdGhhbiBhbnkgZXhpc3RpbmcgbWF0Y2guXG4gICAgICAgIC8vIEJ1dCBjaGVjayBhbnl3YXkuXG4gICAgICAgIGlmIChmaW5hbFNjb3JlIDw9IGN1cnJlbnRUaHJlc2hvbGQpIHtcbiAgICAgICAgICAvLyBJbmRlZWQgaXQgaXNcbiAgICAgICAgICBjdXJyZW50VGhyZXNob2xkID0gZmluYWxTY29yZTtcbiAgICAgICAgICBiZXN0TG9jYXRpb24gPSBjdXJyZW50TG9jYXRpb247XG5cbiAgICAgICAgICAvLyBBbHJlYWR5IHBhc3NlZCBgbG9jYCwgZG93bmhpbGwgZnJvbSBoZXJlIG9uIGluLlxuICAgICAgICAgIGlmIChiZXN0TG9jYXRpb24gPD0gZXhwZWN0ZWRMb2NhdGlvbikge1xuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBXaGVuIHBhc3NpbmcgYGJlc3RMb2NhdGlvbmAsIGRvbid0IGV4Y2VlZCBvdXIgY3VycmVudCBkaXN0YW5jZSBmcm9tIGBleHBlY3RlZExvY2F0aW9uYC5cbiAgICAgICAgICBzdGFydCA9IE1hdGgubWF4KDEsIDIgKiBleHBlY3RlZExvY2F0aW9uIC0gYmVzdExvY2F0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE5vIGhvcGUgZm9yIGEgKGJldHRlcikgbWF0Y2ggYXQgZ3JlYXRlciBlcnJvciBsZXZlbHMuXG4gICAgY29uc3Qgc2NvcmUgPSBjb21wdXRlU2NvcmUkMShwYXR0ZXJuLCB7XG4gICAgICBlcnJvcnM6IGkgKyAxLFxuICAgICAgY3VycmVudExvY2F0aW9uOiBleHBlY3RlZExvY2F0aW9uLFxuICAgICAgZXhwZWN0ZWRMb2NhdGlvbixcbiAgICAgIGRpc3RhbmNlLFxuICAgICAgaWdub3JlTG9jYXRpb25cbiAgICB9KTtcblxuICAgIGlmIChzY29yZSA+IGN1cnJlbnRUaHJlc2hvbGQpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuXG4gICAgbGFzdEJpdEFyciA9IGJpdEFycjtcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBpc01hdGNoOiBiZXN0TG9jYXRpb24gPj0gMCxcbiAgICAvLyBDb3VudCBleGFjdCBtYXRjaGVzICh0aG9zZSB3aXRoIGEgc2NvcmUgb2YgMCkgdG8gYmUgXCJhbG1vc3RcIiBleGFjdFxuICAgIHNjb3JlOiBNYXRoLm1heCgwLjAwMSwgZmluYWxTY29yZSlcbiAgfTtcblxuICBpZiAoY29tcHV0ZU1hdGNoZXMpIHtcbiAgICBjb25zdCBpbmRpY2VzID0gY29udmVydE1hc2tUb0luZGljZXMobWF0Y2hNYXNrLCBtaW5NYXRjaENoYXJMZW5ndGgpO1xuICAgIGlmICghaW5kaWNlcy5sZW5ndGgpIHtcbiAgICAgIHJlc3VsdC5pc01hdGNoID0gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChpbmNsdWRlTWF0Y2hlcykge1xuICAgICAgcmVzdWx0LmluZGljZXMgPSBpbmRpY2VzO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuZnVuY3Rpb24gY3JlYXRlUGF0dGVybkFscGhhYmV0KHBhdHRlcm4pIHtcbiAgbGV0IG1hc2sgPSB7fTtcblxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gcGF0dGVybi5sZW5ndGg7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgIGNvbnN0IGNoYXIgPSBwYXR0ZXJuLmNoYXJBdChpKTtcbiAgICBtYXNrW2NoYXJdID0gKG1hc2tbY2hhcl0gfHwgMCkgfCAoMSA8PCAobGVuIC0gaSAtIDEpKTtcbiAgfVxuXG4gIHJldHVybiBtYXNrXG59XG5cbmNvbnN0IHN0cmlwRGlhY3JpdGljcyA9IFN0cmluZy5wcm90b3R5cGUubm9ybWFsaXplXG4gICAgPyAoKHN0cikgPT4gc3RyLm5vcm1hbGl6ZSgnTkZEJykucmVwbGFjZSgvW1xcdTAzMDAtXFx1MDM2RlxcdTA0ODMtXFx1MDQ4OVxcdTA1OTEtXFx1MDVCRFxcdTA1QkZcXHUwNUMxXFx1MDVDMlxcdTA1QzRcXHUwNUM1XFx1MDVDN1xcdTA2MTAtXFx1MDYxQVxcdTA2NEItXFx1MDY1RlxcdTA2NzBcXHUwNkQ2LVxcdTA2RENcXHUwNkRGLVxcdTA2RTRcXHUwNkU3XFx1MDZFOFxcdTA2RUEtXFx1MDZFRFxcdTA3MTFcXHUwNzMwLVxcdTA3NEFcXHUwN0E2LVxcdTA3QjBcXHUwN0VCLVxcdTA3RjNcXHUwN0ZEXFx1MDgxNi1cXHUwODE5XFx1MDgxQi1cXHUwODIzXFx1MDgyNS1cXHUwODI3XFx1MDgyOS1cXHUwODJEXFx1MDg1OS1cXHUwODVCXFx1MDhEMy1cXHUwOEUxXFx1MDhFMy1cXHUwOTAzXFx1MDkzQS1cXHUwOTNDXFx1MDkzRS1cXHUwOTRGXFx1MDk1MS1cXHUwOTU3XFx1MDk2MlxcdTA5NjNcXHUwOTgxLVxcdTA5ODNcXHUwOUJDXFx1MDlCRS1cXHUwOUM0XFx1MDlDN1xcdTA5QzhcXHUwOUNCLVxcdTA5Q0RcXHUwOUQ3XFx1MDlFMlxcdTA5RTNcXHUwOUZFXFx1MEEwMS1cXHUwQTAzXFx1MEEzQ1xcdTBBM0UtXFx1MEE0MlxcdTBBNDdcXHUwQTQ4XFx1MEE0Qi1cXHUwQTREXFx1MEE1MVxcdTBBNzBcXHUwQTcxXFx1MEE3NVxcdTBBODEtXFx1MEE4M1xcdTBBQkNcXHUwQUJFLVxcdTBBQzVcXHUwQUM3LVxcdTBBQzlcXHUwQUNCLVxcdTBBQ0RcXHUwQUUyXFx1MEFFM1xcdTBBRkEtXFx1MEFGRlxcdTBCMDEtXFx1MEIwM1xcdTBCM0NcXHUwQjNFLVxcdTBCNDRcXHUwQjQ3XFx1MEI0OFxcdTBCNEItXFx1MEI0RFxcdTBCNTZcXHUwQjU3XFx1MEI2MlxcdTBCNjNcXHUwQjgyXFx1MEJCRS1cXHUwQkMyXFx1MEJDNi1cXHUwQkM4XFx1MEJDQS1cXHUwQkNEXFx1MEJEN1xcdTBDMDAtXFx1MEMwNFxcdTBDM0UtXFx1MEM0NFxcdTBDNDYtXFx1MEM0OFxcdTBDNEEtXFx1MEM0RFxcdTBDNTVcXHUwQzU2XFx1MEM2MlxcdTBDNjNcXHUwQzgxLVxcdTBDODNcXHUwQ0JDXFx1MENCRS1cXHUwQ0M0XFx1MENDNi1cXHUwQ0M4XFx1MENDQS1cXHUwQ0NEXFx1MENENVxcdTBDRDZcXHUwQ0UyXFx1MENFM1xcdTBEMDAtXFx1MEQwM1xcdTBEM0JcXHUwRDNDXFx1MEQzRS1cXHUwRDQ0XFx1MEQ0Ni1cXHUwRDQ4XFx1MEQ0QS1cXHUwRDREXFx1MEQ1N1xcdTBENjJcXHUwRDYzXFx1MEQ4MlxcdTBEODNcXHUwRENBXFx1MERDRi1cXHUwREQ0XFx1MERENlxcdTBERDgtXFx1MERERlxcdTBERjJcXHUwREYzXFx1MEUzMVxcdTBFMzQtXFx1MEUzQVxcdTBFNDctXFx1MEU0RVxcdTBFQjFcXHUwRUI0LVxcdTBFQjlcXHUwRUJCXFx1MEVCQ1xcdTBFQzgtXFx1MEVDRFxcdTBGMThcXHUwRjE5XFx1MEYzNVxcdTBGMzdcXHUwRjM5XFx1MEYzRVxcdTBGM0ZcXHUwRjcxLVxcdTBGODRcXHUwRjg2XFx1MEY4N1xcdTBGOEQtXFx1MEY5N1xcdTBGOTktXFx1MEZCQ1xcdTBGQzZcXHUxMDJCLVxcdTEwM0VcXHUxMDU2LVxcdTEwNTlcXHUxMDVFLVxcdTEwNjBcXHUxMDYyLVxcdTEwNjRcXHUxMDY3LVxcdTEwNkRcXHUxMDcxLVxcdTEwNzRcXHUxMDgyLVxcdTEwOERcXHUxMDhGXFx1MTA5QS1cXHUxMDlEXFx1MTM1RC1cXHUxMzVGXFx1MTcxMi1cXHUxNzE0XFx1MTczMi1cXHUxNzM0XFx1MTc1MlxcdTE3NTNcXHUxNzcyXFx1MTc3M1xcdTE3QjQtXFx1MTdEM1xcdTE3RERcXHUxODBCLVxcdTE4MERcXHUxODg1XFx1MTg4NlxcdTE4QTlcXHUxOTIwLVxcdTE5MkJcXHUxOTMwLVxcdTE5M0JcXHUxQTE3LVxcdTFBMUJcXHUxQTU1LVxcdTFBNUVcXHUxQTYwLVxcdTFBN0NcXHUxQTdGXFx1MUFCMC1cXHUxQUJFXFx1MUIwMC1cXHUxQjA0XFx1MUIzNC1cXHUxQjQ0XFx1MUI2Qi1cXHUxQjczXFx1MUI4MC1cXHUxQjgyXFx1MUJBMS1cXHUxQkFEXFx1MUJFNi1cXHUxQkYzXFx1MUMyNC1cXHUxQzM3XFx1MUNEMC1cXHUxQ0QyXFx1MUNENC1cXHUxQ0U4XFx1MUNFRFxcdTFDRjItXFx1MUNGNFxcdTFDRjctXFx1MUNGOVxcdTFEQzAtXFx1MURGOVxcdTFERkItXFx1MURGRlxcdTIwRDAtXFx1MjBGMFxcdTJDRUYtXFx1MkNGMVxcdTJEN0ZcXHUyREUwLVxcdTJERkZcXHUzMDJBLVxcdTMwMkZcXHUzMDk5XFx1MzA5QVxcdUE2NkYtXFx1QTY3MlxcdUE2NzQtXFx1QTY3RFxcdUE2OUVcXHVBNjlGXFx1QTZGMFxcdUE2RjFcXHVBODAyXFx1QTgwNlxcdUE4MEJcXHVBODIzLVxcdUE4MjdcXHVBODgwXFx1QTg4MVxcdUE4QjQtXFx1QThDNVxcdUE4RTAtXFx1QThGMVxcdUE4RkZcXHVBOTI2LVxcdUE5MkRcXHVBOTQ3LVxcdUE5NTNcXHVBOTgwLVxcdUE5ODNcXHVBOUIzLVxcdUE5QzBcXHVBOUU1XFx1QUEyOS1cXHVBQTM2XFx1QUE0M1xcdUFBNENcXHVBQTREXFx1QUE3Qi1cXHVBQTdEXFx1QUFCMFxcdUFBQjItXFx1QUFCNFxcdUFBQjdcXHVBQUI4XFx1QUFCRVxcdUFBQkZcXHVBQUMxXFx1QUFFQi1cXHVBQUVGXFx1QUFGNVxcdUFBRjZcXHVBQkUzLVxcdUFCRUFcXHVBQkVDXFx1QUJFRFxcdUZCMUVcXHVGRTAwLVxcdUZFMEZcXHVGRTIwLVxcdUZFMkZdL2csICcnKSlcbiAgICA6ICgoc3RyKSA9PiBzdHIpO1xuXG5jbGFzcyBCaXRhcFNlYXJjaCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHBhdHRlcm4sXG4gICAge1xuICAgICAgbG9jYXRpb24gPSBDb25maWcubG9jYXRpb24sXG4gICAgICB0aHJlc2hvbGQgPSBDb25maWcudGhyZXNob2xkLFxuICAgICAgZGlzdGFuY2UgPSBDb25maWcuZGlzdGFuY2UsXG4gICAgICBpbmNsdWRlTWF0Y2hlcyA9IENvbmZpZy5pbmNsdWRlTWF0Y2hlcyxcbiAgICAgIGZpbmRBbGxNYXRjaGVzID0gQ29uZmlnLmZpbmRBbGxNYXRjaGVzLFxuICAgICAgbWluTWF0Y2hDaGFyTGVuZ3RoID0gQ29uZmlnLm1pbk1hdGNoQ2hhckxlbmd0aCxcbiAgICAgIGlzQ2FzZVNlbnNpdGl2ZSA9IENvbmZpZy5pc0Nhc2VTZW5zaXRpdmUsXG4gICAgICBpZ25vcmVEaWFjcml0aWNzID0gQ29uZmlnLmlnbm9yZURpYWNyaXRpY3MsXG4gICAgICBpZ25vcmVMb2NhdGlvbiA9IENvbmZpZy5pZ25vcmVMb2NhdGlvblxuICAgIH0gPSB7fVxuICApIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBsb2NhdGlvbixcbiAgICAgIHRocmVzaG9sZCxcbiAgICAgIGRpc3RhbmNlLFxuICAgICAgaW5jbHVkZU1hdGNoZXMsXG4gICAgICBmaW5kQWxsTWF0Y2hlcyxcbiAgICAgIG1pbk1hdGNoQ2hhckxlbmd0aCxcbiAgICAgIGlzQ2FzZVNlbnNpdGl2ZSxcbiAgICAgIGlnbm9yZURpYWNyaXRpY3MsXG4gICAgICBpZ25vcmVMb2NhdGlvblxuICAgIH07XG5cbiAgICBwYXR0ZXJuID0gaXNDYXNlU2Vuc2l0aXZlID8gcGF0dGVybiA6IHBhdHRlcm4udG9Mb3dlckNhc2UoKTtcbiAgICBwYXR0ZXJuID0gaWdub3JlRGlhY3JpdGljcyA/IHN0cmlwRGlhY3JpdGljcyhwYXR0ZXJuKSA6IHBhdHRlcm47XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcblxuICAgIHRoaXMuY2h1bmtzID0gW107XG5cbiAgICBpZiAoIXRoaXMucGF0dGVybi5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGFkZENodW5rID0gKHBhdHRlcm4sIHN0YXJ0SW5kZXgpID0+IHtcbiAgICAgIHRoaXMuY2h1bmtzLnB1c2goe1xuICAgICAgICBwYXR0ZXJuLFxuICAgICAgICBhbHBoYWJldDogY3JlYXRlUGF0dGVybkFscGhhYmV0KHBhdHRlcm4pLFxuICAgICAgICBzdGFydEluZGV4XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgY29uc3QgbGVuID0gdGhpcy5wYXR0ZXJuLmxlbmd0aDtcblxuICAgIGlmIChsZW4gPiBNQVhfQklUUykge1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgY29uc3QgcmVtYWluZGVyID0gbGVuICUgTUFYX0JJVFM7XG4gICAgICBjb25zdCBlbmQgPSBsZW4gLSByZW1haW5kZXI7XG5cbiAgICAgIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgICAgIGFkZENodW5rKHRoaXMucGF0dGVybi5zdWJzdHIoaSwgTUFYX0JJVFMpLCBpKTtcbiAgICAgICAgaSArPSBNQVhfQklUUztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlbWFpbmRlcikge1xuICAgICAgICBjb25zdCBzdGFydEluZGV4ID0gbGVuIC0gTUFYX0JJVFM7XG4gICAgICAgIGFkZENodW5rKHRoaXMucGF0dGVybi5zdWJzdHIoc3RhcnRJbmRleCksIHN0YXJ0SW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhZGRDaHVuayh0aGlzLnBhdHRlcm4sIDApO1xuICAgIH1cbiAgfVxuXG4gIHNlYXJjaEluKHRleHQpIHtcbiAgICBjb25zdCB7IGlzQ2FzZVNlbnNpdGl2ZSwgaWdub3JlRGlhY3JpdGljcywgaW5jbHVkZU1hdGNoZXMgfSA9IHRoaXMub3B0aW9ucztcblxuICAgIHRleHQgPSBpc0Nhc2VTZW5zaXRpdmUgPyB0ZXh0IDogdGV4dC50b0xvd2VyQ2FzZSgpO1xuICAgIHRleHQgPSBpZ25vcmVEaWFjcml0aWNzID8gc3RyaXBEaWFjcml0aWNzKHRleHQpIDogdGV4dDtcblxuICAgIC8vIEV4YWN0IG1hdGNoXG4gICAgaWYgKHRoaXMucGF0dGVybiA9PT0gdGV4dCkge1xuICAgICAgbGV0IHJlc3VsdCA9IHtcbiAgICAgICAgaXNNYXRjaDogdHJ1ZSxcbiAgICAgICAgc2NvcmU6IDBcbiAgICAgIH07XG5cbiAgICAgIGlmIChpbmNsdWRlTWF0Y2hlcykge1xuICAgICAgICByZXN1bHQuaW5kaWNlcyA9IFtbMCwgdGV4dC5sZW5ndGggLSAxXV07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIHVzZSBCaXRhcCBhbGdvcml0aG1cbiAgICBjb25zdCB7XG4gICAgICBsb2NhdGlvbixcbiAgICAgIGRpc3RhbmNlLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgZmluZEFsbE1hdGNoZXMsXG4gICAgICBtaW5NYXRjaENoYXJMZW5ndGgsXG4gICAgICBpZ25vcmVMb2NhdGlvblxuICAgIH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICBsZXQgYWxsSW5kaWNlcyA9IFtdO1xuICAgIGxldCB0b3RhbFNjb3JlID0gMDtcbiAgICBsZXQgaGFzTWF0Y2hlcyA9IGZhbHNlO1xuXG4gICAgdGhpcy5jaHVua3MuZm9yRWFjaCgoeyBwYXR0ZXJuLCBhbHBoYWJldCwgc3RhcnRJbmRleCB9KSA9PiB7XG4gICAgICBjb25zdCB7IGlzTWF0Y2gsIHNjb3JlLCBpbmRpY2VzIH0gPSBzZWFyY2godGV4dCwgcGF0dGVybiwgYWxwaGFiZXQsIHtcbiAgICAgICAgbG9jYXRpb246IGxvY2F0aW9uICsgc3RhcnRJbmRleCxcbiAgICAgICAgZGlzdGFuY2UsXG4gICAgICAgIHRocmVzaG9sZCxcbiAgICAgICAgZmluZEFsbE1hdGNoZXMsXG4gICAgICAgIG1pbk1hdGNoQ2hhckxlbmd0aCxcbiAgICAgICAgaW5jbHVkZU1hdGNoZXMsXG4gICAgICAgIGlnbm9yZUxvY2F0aW9uXG4gICAgICB9KTtcblxuICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgaGFzTWF0Y2hlcyA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHRvdGFsU2NvcmUgKz0gc2NvcmU7XG5cbiAgICAgIGlmIChpc01hdGNoICYmIGluZGljZXMpIHtcbiAgICAgICAgYWxsSW5kaWNlcyA9IFsuLi5hbGxJbmRpY2VzLCAuLi5pbmRpY2VzXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCByZXN1bHQgPSB7XG4gICAgICBpc01hdGNoOiBoYXNNYXRjaGVzLFxuICAgICAgc2NvcmU6IGhhc01hdGNoZXMgPyB0b3RhbFNjb3JlIC8gdGhpcy5jaHVua3MubGVuZ3RoIDogMVxuICAgIH07XG5cbiAgICBpZiAoaGFzTWF0Y2hlcyAmJiBpbmNsdWRlTWF0Y2hlcykge1xuICAgICAgcmVzdWx0LmluZGljZXMgPSBhbGxJbmRpY2VzO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRcbiAgfVxufVxuXG5jbGFzcyBCYXNlTWF0Y2gge1xuICBjb25zdHJ1Y3RvcihwYXR0ZXJuKSB7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbiAgfVxuICBzdGF0aWMgaXNNdWx0aU1hdGNoKHBhdHRlcm4pIHtcbiAgICByZXR1cm4gZ2V0TWF0Y2gocGF0dGVybiwgdGhpcy5tdWx0aVJlZ2V4KVxuICB9XG4gIHN0YXRpYyBpc1NpbmdsZU1hdGNoKHBhdHRlcm4pIHtcbiAgICByZXR1cm4gZ2V0TWF0Y2gocGF0dGVybiwgdGhpcy5zaW5nbGVSZWdleClcbiAgfVxuICBzZWFyY2goLyp0ZXh0Ki8pIHt9XG59XG5cbmZ1bmN0aW9uIGdldE1hdGNoKHBhdHRlcm4sIGV4cCkge1xuICBjb25zdCBtYXRjaGVzID0gcGF0dGVybi5tYXRjaChleHApO1xuICByZXR1cm4gbWF0Y2hlcyA/IG1hdGNoZXNbMV0gOiBudWxsXG59XG5cbi8vIFRva2VuOiAnZmlsZVxuXG5jbGFzcyBFeGFjdE1hdGNoIGV4dGVuZHMgQmFzZU1hdGNoIHtcbiAgY29uc3RydWN0b3IocGF0dGVybikge1xuICAgIHN1cGVyKHBhdHRlcm4pO1xuICB9XG4gIHN0YXRpYyBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2V4YWN0J1xuICB9XG4gIHN0YXRpYyBnZXQgbXVsdGlSZWdleCgpIHtcbiAgICByZXR1cm4gL149XCIoLiopXCIkL1xuICB9XG4gIHN0YXRpYyBnZXQgc2luZ2xlUmVnZXgoKSB7XG4gICAgcmV0dXJuIC9ePSguKikkL1xuICB9XG4gIHNlYXJjaCh0ZXh0KSB7XG4gICAgY29uc3QgaXNNYXRjaCA9IHRleHQgPT09IHRoaXMucGF0dGVybjtcblxuICAgIHJldHVybiB7XG4gICAgICBpc01hdGNoLFxuICAgICAgc2NvcmU6IGlzTWF0Y2ggPyAwIDogMSxcbiAgICAgIGluZGljZXM6IFswLCB0aGlzLnBhdHRlcm4ubGVuZ3RoIC0gMV1cbiAgICB9XG4gIH1cbn1cblxuLy8gVG9rZW46ICFmaXJlXG5cbmNsYXNzIEludmVyc2VFeGFjdE1hdGNoIGV4dGVuZHMgQmFzZU1hdGNoIHtcbiAgY29uc3RydWN0b3IocGF0dGVybikge1xuICAgIHN1cGVyKHBhdHRlcm4pO1xuICB9XG4gIHN0YXRpYyBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2ludmVyc2UtZXhhY3QnXG4gIH1cbiAgc3RhdGljIGdldCBtdWx0aVJlZ2V4KCkge1xuICAgIHJldHVybiAvXiFcIiguKilcIiQvXG4gIH1cbiAgc3RhdGljIGdldCBzaW5nbGVSZWdleCgpIHtcbiAgICByZXR1cm4gL14hKC4qKSQvXG4gIH1cbiAgc2VhcmNoKHRleHQpIHtcbiAgICBjb25zdCBpbmRleCA9IHRleHQuaW5kZXhPZih0aGlzLnBhdHRlcm4pO1xuICAgIGNvbnN0IGlzTWF0Y2ggPSBpbmRleCA9PT0gLTE7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaXNNYXRjaCxcbiAgICAgIHNjb3JlOiBpc01hdGNoID8gMCA6IDEsXG4gICAgICBpbmRpY2VzOiBbMCwgdGV4dC5sZW5ndGggLSAxXVxuICAgIH1cbiAgfVxufVxuXG4vLyBUb2tlbjogXmZpbGVcblxuY2xhc3MgUHJlZml4RXhhY3RNYXRjaCBleHRlbmRzIEJhc2VNYXRjaCB7XG4gIGNvbnN0cnVjdG9yKHBhdHRlcm4pIHtcbiAgICBzdXBlcihwYXR0ZXJuKTtcbiAgfVxuICBzdGF0aWMgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdwcmVmaXgtZXhhY3QnXG4gIH1cbiAgc3RhdGljIGdldCBtdWx0aVJlZ2V4KCkge1xuICAgIHJldHVybiAvXlxcXlwiKC4qKVwiJC9cbiAgfVxuICBzdGF0aWMgZ2V0IHNpbmdsZVJlZ2V4KCkge1xuICAgIHJldHVybiAvXlxcXiguKikkL1xuICB9XG4gIHNlYXJjaCh0ZXh0KSB7XG4gICAgY29uc3QgaXNNYXRjaCA9IHRleHQuc3RhcnRzV2l0aCh0aGlzLnBhdHRlcm4pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlzTWF0Y2gsXG4gICAgICBzY29yZTogaXNNYXRjaCA/IDAgOiAxLFxuICAgICAgaW5kaWNlczogWzAsIHRoaXMucGF0dGVybi5sZW5ndGggLSAxXVxuICAgIH1cbiAgfVxufVxuXG4vLyBUb2tlbjogIV5maXJlXG5cbmNsYXNzIEludmVyc2VQcmVmaXhFeGFjdE1hdGNoIGV4dGVuZHMgQmFzZU1hdGNoIHtcbiAgY29uc3RydWN0b3IocGF0dGVybikge1xuICAgIHN1cGVyKHBhdHRlcm4pO1xuICB9XG4gIHN0YXRpYyBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2ludmVyc2UtcHJlZml4LWV4YWN0J1xuICB9XG4gIHN0YXRpYyBnZXQgbXVsdGlSZWdleCgpIHtcbiAgICByZXR1cm4gL14hXFxeXCIoLiopXCIkL1xuICB9XG4gIHN0YXRpYyBnZXQgc2luZ2xlUmVnZXgoKSB7XG4gICAgcmV0dXJuIC9eIVxcXiguKikkL1xuICB9XG4gIHNlYXJjaCh0ZXh0KSB7XG4gICAgY29uc3QgaXNNYXRjaCA9ICF0ZXh0LnN0YXJ0c1dpdGgodGhpcy5wYXR0ZXJuKTtcblxuICAgIHJldHVybiB7XG4gICAgICBpc01hdGNoLFxuICAgICAgc2NvcmU6IGlzTWF0Y2ggPyAwIDogMSxcbiAgICAgIGluZGljZXM6IFswLCB0ZXh0Lmxlbmd0aCAtIDFdXG4gICAgfVxuICB9XG59XG5cbi8vIFRva2VuOiAuZmlsZSRcblxuY2xhc3MgU3VmZml4RXhhY3RNYXRjaCBleHRlbmRzIEJhc2VNYXRjaCB7XG4gIGNvbnN0cnVjdG9yKHBhdHRlcm4pIHtcbiAgICBzdXBlcihwYXR0ZXJuKTtcbiAgfVxuICBzdGF0aWMgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdzdWZmaXgtZXhhY3QnXG4gIH1cbiAgc3RhdGljIGdldCBtdWx0aVJlZ2V4KCkge1xuICAgIHJldHVybiAvXlwiKC4qKVwiXFwkJC9cbiAgfVxuICBzdGF0aWMgZ2V0IHNpbmdsZVJlZ2V4KCkge1xuICAgIHJldHVybiAvXiguKilcXCQkL1xuICB9XG4gIHNlYXJjaCh0ZXh0KSB7XG4gICAgY29uc3QgaXNNYXRjaCA9IHRleHQuZW5kc1dpdGgodGhpcy5wYXR0ZXJuKTtcblxuICAgIHJldHVybiB7XG4gICAgICBpc01hdGNoLFxuICAgICAgc2NvcmU6IGlzTWF0Y2ggPyAwIDogMSxcbiAgICAgIGluZGljZXM6IFt0ZXh0Lmxlbmd0aCAtIHRoaXMucGF0dGVybi5sZW5ndGgsIHRleHQubGVuZ3RoIC0gMV1cbiAgICB9XG4gIH1cbn1cblxuLy8gVG9rZW46ICEuZmlsZSRcblxuY2xhc3MgSW52ZXJzZVN1ZmZpeEV4YWN0TWF0Y2ggZXh0ZW5kcyBCYXNlTWF0Y2gge1xuICBjb25zdHJ1Y3RvcihwYXR0ZXJuKSB7XG4gICAgc3VwZXIocGF0dGVybik7XG4gIH1cbiAgc3RhdGljIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAnaW52ZXJzZS1zdWZmaXgtZXhhY3QnXG4gIH1cbiAgc3RhdGljIGdldCBtdWx0aVJlZ2V4KCkge1xuICAgIHJldHVybiAvXiFcIiguKilcIlxcJCQvXG4gIH1cbiAgc3RhdGljIGdldCBzaW5nbGVSZWdleCgpIHtcbiAgICByZXR1cm4gL14hKC4qKVxcJCQvXG4gIH1cbiAgc2VhcmNoKHRleHQpIHtcbiAgICBjb25zdCBpc01hdGNoID0gIXRleHQuZW5kc1dpdGgodGhpcy5wYXR0ZXJuKTtcbiAgICByZXR1cm4ge1xuICAgICAgaXNNYXRjaCxcbiAgICAgIHNjb3JlOiBpc01hdGNoID8gMCA6IDEsXG4gICAgICBpbmRpY2VzOiBbMCwgdGV4dC5sZW5ndGggLSAxXVxuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBGdXp6eU1hdGNoIGV4dGVuZHMgQmFzZU1hdGNoIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcGF0dGVybixcbiAgICB7XG4gICAgICBsb2NhdGlvbiA9IENvbmZpZy5sb2NhdGlvbixcbiAgICAgIHRocmVzaG9sZCA9IENvbmZpZy50aHJlc2hvbGQsXG4gICAgICBkaXN0YW5jZSA9IENvbmZpZy5kaXN0YW5jZSxcbiAgICAgIGluY2x1ZGVNYXRjaGVzID0gQ29uZmlnLmluY2x1ZGVNYXRjaGVzLFxuICAgICAgZmluZEFsbE1hdGNoZXMgPSBDb25maWcuZmluZEFsbE1hdGNoZXMsXG4gICAgICBtaW5NYXRjaENoYXJMZW5ndGggPSBDb25maWcubWluTWF0Y2hDaGFyTGVuZ3RoLFxuICAgICAgaXNDYXNlU2Vuc2l0aXZlID0gQ29uZmlnLmlzQ2FzZVNlbnNpdGl2ZSxcbiAgICAgIGlnbm9yZURpYWNyaXRpY3MgPSBDb25maWcuaWdub3JlRGlhY3JpdGljcyxcbiAgICAgIGlnbm9yZUxvY2F0aW9uID0gQ29uZmlnLmlnbm9yZUxvY2F0aW9uXG4gICAgfSA9IHt9XG4gICkge1xuICAgIHN1cGVyKHBhdHRlcm4pO1xuICAgIHRoaXMuX2JpdGFwU2VhcmNoID0gbmV3IEJpdGFwU2VhcmNoKHBhdHRlcm4sIHtcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgZGlzdGFuY2UsXG4gICAgICBpbmNsdWRlTWF0Y2hlcyxcbiAgICAgIGZpbmRBbGxNYXRjaGVzLFxuICAgICAgbWluTWF0Y2hDaGFyTGVuZ3RoLFxuICAgICAgaXNDYXNlU2Vuc2l0aXZlLFxuICAgICAgaWdub3JlRGlhY3JpdGljcyxcbiAgICAgIGlnbm9yZUxvY2F0aW9uXG4gICAgfSk7XG4gIH1cbiAgc3RhdGljIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAnZnV6enknXG4gIH1cbiAgc3RhdGljIGdldCBtdWx0aVJlZ2V4KCkge1xuICAgIHJldHVybiAvXlwiKC4qKVwiJC9cbiAgfVxuICBzdGF0aWMgZ2V0IHNpbmdsZVJlZ2V4KCkge1xuICAgIHJldHVybiAvXiguKikkL1xuICB9XG4gIHNlYXJjaCh0ZXh0KSB7XG4gICAgcmV0dXJuIHRoaXMuX2JpdGFwU2VhcmNoLnNlYXJjaEluKHRleHQpXG4gIH1cbn1cblxuLy8gVG9rZW46ICdmaWxlXG5cbmNsYXNzIEluY2x1ZGVNYXRjaCBleHRlbmRzIEJhc2VNYXRjaCB7XG4gIGNvbnN0cnVjdG9yKHBhdHRlcm4pIHtcbiAgICBzdXBlcihwYXR0ZXJuKTtcbiAgfVxuICBzdGF0aWMgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdpbmNsdWRlJ1xuICB9XG4gIHN0YXRpYyBnZXQgbXVsdGlSZWdleCgpIHtcbiAgICByZXR1cm4gL14nXCIoLiopXCIkL1xuICB9XG4gIHN0YXRpYyBnZXQgc2luZ2xlUmVnZXgoKSB7XG4gICAgcmV0dXJuIC9eJyguKikkL1xuICB9XG4gIHNlYXJjaCh0ZXh0KSB7XG4gICAgbGV0IGxvY2F0aW9uID0gMDtcbiAgICBsZXQgaW5kZXg7XG5cbiAgICBjb25zdCBpbmRpY2VzID0gW107XG4gICAgY29uc3QgcGF0dGVybkxlbiA9IHRoaXMucGF0dGVybi5sZW5ndGg7XG5cbiAgICAvLyBHZXQgYWxsIGV4YWN0IG1hdGNoZXNcbiAgICB3aGlsZSAoKGluZGV4ID0gdGV4dC5pbmRleE9mKHRoaXMucGF0dGVybiwgbG9jYXRpb24pKSA+IC0xKSB7XG4gICAgICBsb2NhdGlvbiA9IGluZGV4ICsgcGF0dGVybkxlbjtcbiAgICAgIGluZGljZXMucHVzaChbaW5kZXgsIGxvY2F0aW9uIC0gMV0pO1xuICAgIH1cblxuICAgIGNvbnN0IGlzTWF0Y2ggPSAhIWluZGljZXMubGVuZ3RoO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlzTWF0Y2gsXG4gICAgICBzY29yZTogaXNNYXRjaCA/IDAgOiAxLFxuICAgICAgaW5kaWNlc1xuICAgIH1cbiAgfVxufVxuXG4vLyDinZdPcmRlciBpcyBpbXBvcnRhbnQuIERPIE5PVCBDSEFOR0UuXG5jb25zdCBzZWFyY2hlcnMgPSBbXG4gIEV4YWN0TWF0Y2gsXG4gIEluY2x1ZGVNYXRjaCxcbiAgUHJlZml4RXhhY3RNYXRjaCxcbiAgSW52ZXJzZVByZWZpeEV4YWN0TWF0Y2gsXG4gIEludmVyc2VTdWZmaXhFeGFjdE1hdGNoLFxuICBTdWZmaXhFeGFjdE1hdGNoLFxuICBJbnZlcnNlRXhhY3RNYXRjaCxcbiAgRnV6enlNYXRjaFxuXTtcblxuY29uc3Qgc2VhcmNoZXJzTGVuID0gc2VhcmNoZXJzLmxlbmd0aDtcblxuLy8gUmVnZXggdG8gc3BsaXQgYnkgc3BhY2VzLCBidXQga2VlcCBhbnl0aGluZyBpbiBxdW90ZXMgdG9nZXRoZXJcbmNvbnN0IFNQQUNFX1JFID0gLyArKD89KD86W15cXFwiXSpcXFwiW15cXFwiXSpcXFwiKSpbXlxcXCJdKiQpLztcbmNvbnN0IE9SX1RPS0VOID0gJ3wnO1xuXG4vLyBSZXR1cm4gYSAyRCBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcXVlcnksIGZvciBzaW1wbGVyIHBhcnNpbmcuXG4vLyBFeGFtcGxlOlxuLy8gXCJeY29yZSBnbyQgfCByYiQgfCBweSQgeHkkXCIgPT4gW1tcIl5jb3JlXCIsIFwiZ28kXCJdLCBbXCJyYiRcIl0sIFtcInB5JFwiLCBcInh5JFwiXV1cbmZ1bmN0aW9uIHBhcnNlUXVlcnkocGF0dGVybiwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBwYXR0ZXJuLnNwbGl0KE9SX1RPS0VOKS5tYXAoKGl0ZW0pID0+IHtcbiAgICBsZXQgcXVlcnkgPSBpdGVtXG4gICAgICAudHJpbSgpXG4gICAgICAuc3BsaXQoU1BBQ0VfUkUpXG4gICAgICAuZmlsdGVyKChpdGVtKSA9PiBpdGVtICYmICEhaXRlbS50cmltKCkpO1xuXG4gICAgbGV0IHJlc3VsdHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gcXVlcnkubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IHF1ZXJ5SXRlbSA9IHF1ZXJ5W2ldO1xuXG4gICAgICAvLyAxLiBIYW5kbGUgbXVsdGlwbGUgcXVlcnkgbWF0Y2ggKGkuZSwgb25jZSB0aGF0IGFyZSBxdW90ZWQsIGxpa2UgYFwiaGVsbG8gd29ybGRcImApXG4gICAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICAgIGxldCBpZHggPSAtMTtcbiAgICAgIHdoaWxlICghZm91bmQgJiYgKytpZHggPCBzZWFyY2hlcnNMZW4pIHtcbiAgICAgICAgY29uc3Qgc2VhcmNoZXIgPSBzZWFyY2hlcnNbaWR4XTtcbiAgICAgICAgbGV0IHRva2VuID0gc2VhcmNoZXIuaXNNdWx0aU1hdGNoKHF1ZXJ5SXRlbSk7XG4gICAgICAgIGlmICh0b2tlbikge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChuZXcgc2VhcmNoZXIodG9rZW4sIG9wdGlvbnMpKTtcbiAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIuIEhhbmRsZSBzaW5nbGUgcXVlcnkgbWF0Y2hlcyAoaS5lLCBvbmNlIHRoYXQgYXJlICpub3QqIHF1b3RlZClcbiAgICAgIGlkeCA9IC0xO1xuICAgICAgd2hpbGUgKCsraWR4IDwgc2VhcmNoZXJzTGVuKSB7XG4gICAgICAgIGNvbnN0IHNlYXJjaGVyID0gc2VhcmNoZXJzW2lkeF07XG4gICAgICAgIGxldCB0b2tlbiA9IHNlYXJjaGVyLmlzU2luZ2xlTWF0Y2gocXVlcnlJdGVtKTtcbiAgICAgICAgaWYgKHRva2VuKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKG5ldyBzZWFyY2hlcih0b2tlbiwgb3B0aW9ucykpO1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0c1xuICB9KVxufVxuXG4vLyBUaGVzZSBleHRlbmRlZCBtYXRjaGVycyBjYW4gcmV0dXJuIGFuIGFycmF5IG9mIG1hdGNoZXMsIGFzIG9wcG9zZWRcbi8vIHRvIGEgc2luZ2wgbWF0Y2hcbmNvbnN0IE11bHRpTWF0Y2hTZXQgPSBuZXcgU2V0KFtGdXp6eU1hdGNoLnR5cGUsIEluY2x1ZGVNYXRjaC50eXBlXSk7XG5cbi8qKlxuICogQ29tbWFuZC1saWtlIHNlYXJjaGluZ1xuICogPT09PT09PT09PT09PT09PT09PT09PVxuICpcbiAqIEdpdmVuIG11bHRpcGxlIHNlYXJjaCB0ZXJtcyBkZWxpbWl0ZWQgYnkgc3BhY2VzLmUuZy4gYF5qc2NyaXB0IC5weXRob24kIHJ1YnkgIWphdmFgLFxuICogc2VhcmNoIGluIGEgZ2l2ZW4gdGV4dC5cbiAqXG4gKiBTZWFyY2ggc3ludGF4OlxuICpcbiAqIHwgVG9rZW4gICAgICAgfCBNYXRjaCB0eXBlICAgICAgICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIHxcbiAqIHwgYGpzY3JpcHRgICAgfCBmdXp6eS1tYXRjaCAgICAgICAgICAgICAgICB8IEl0ZW1zIHRoYXQgZnV6enkgbWF0Y2ggYGpzY3JpcHRgICAgICAgIHxcbiAqIHwgYD1zY2hlbWVgICAgfCBleGFjdC1tYXRjaCAgICAgICAgICAgICAgICB8IEl0ZW1zIHRoYXQgYXJlIGBzY2hlbWVgICAgICAgICAgICAgICAgIHxcbiAqIHwgYCdweXRob25gICAgfCBpbmNsdWRlLW1hdGNoICAgICAgICAgICAgICB8IEl0ZW1zIHRoYXQgaW5jbHVkZSBgcHl0aG9uYCAgICAgICAgICAgIHxcbiAqIHwgYCFydWJ5YCAgICAgfCBpbnZlcnNlLWV4YWN0LW1hdGNoICAgICAgICB8IEl0ZW1zIHRoYXQgZG8gbm90IGluY2x1ZGUgYHJ1YnlgICAgICAgIHxcbiAqIHwgYF5qYXZhYCAgICAgfCBwcmVmaXgtZXhhY3QtbWF0Y2ggICAgICAgICB8IEl0ZW1zIHRoYXQgc3RhcnQgd2l0aCBgamF2YWAgICAgICAgICAgIHxcbiAqIHwgYCFeZWFybGFuZ2AgfCBpbnZlcnNlLXByZWZpeC1leGFjdC1tYXRjaCB8IEl0ZW1zIHRoYXQgZG8gbm90IHN0YXJ0IHdpdGggYGVhcmxhbmdgIHxcbiAqIHwgYC5qcyRgICAgICAgfCBzdWZmaXgtZXhhY3QtbWF0Y2ggICAgICAgICB8IEl0ZW1zIHRoYXQgZW5kIHdpdGggYC5qc2AgICAgICAgICAgICAgIHxcbiAqIHwgYCEuZ28kYCAgICAgfCBpbnZlcnNlLXN1ZmZpeC1leGFjdC1tYXRjaCB8IEl0ZW1zIHRoYXQgZG8gbm90IGVuZCB3aXRoIGAuZ29gICAgICAgIHxcbiAqXG4gKiBBIHNpbmdsZSBwaXBlIGNoYXJhY3RlciBhY3RzIGFzIGFuIE9SIG9wZXJhdG9yLiBGb3IgZXhhbXBsZSwgdGhlIGZvbGxvd2luZ1xuICogcXVlcnkgbWF0Y2hlcyBlbnRyaWVzIHRoYXQgc3RhcnQgd2l0aCBgY29yZWAgYW5kIGVuZCB3aXRoIGVpdGhlcmBnb2AsIGByYmAsXG4gKiBvcmBweWAuXG4gKlxuICogYGBgXG4gKiBeY29yZSBnbyQgfCByYiQgfCBweSRcbiAqIGBgYFxuICovXG5jbGFzcyBFeHRlbmRlZFNlYXJjaCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHBhdHRlcm4sXG4gICAge1xuICAgICAgaXNDYXNlU2Vuc2l0aXZlID0gQ29uZmlnLmlzQ2FzZVNlbnNpdGl2ZSxcbiAgICAgIGlnbm9yZURpYWNyaXRpY3MgPSBDb25maWcuaWdub3JlRGlhY3JpdGljcyxcbiAgICAgIGluY2x1ZGVNYXRjaGVzID0gQ29uZmlnLmluY2x1ZGVNYXRjaGVzLFxuICAgICAgbWluTWF0Y2hDaGFyTGVuZ3RoID0gQ29uZmlnLm1pbk1hdGNoQ2hhckxlbmd0aCxcbiAgICAgIGlnbm9yZUxvY2F0aW9uID0gQ29uZmlnLmlnbm9yZUxvY2F0aW9uLFxuICAgICAgZmluZEFsbE1hdGNoZXMgPSBDb25maWcuZmluZEFsbE1hdGNoZXMsXG4gICAgICBsb2NhdGlvbiA9IENvbmZpZy5sb2NhdGlvbixcbiAgICAgIHRocmVzaG9sZCA9IENvbmZpZy50aHJlc2hvbGQsXG4gICAgICBkaXN0YW5jZSA9IENvbmZpZy5kaXN0YW5jZVxuICAgIH0gPSB7fVxuICApIHtcbiAgICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBpc0Nhc2VTZW5zaXRpdmUsXG4gICAgICBpZ25vcmVEaWFjcml0aWNzLFxuICAgICAgaW5jbHVkZU1hdGNoZXMsXG4gICAgICBtaW5NYXRjaENoYXJMZW5ndGgsXG4gICAgICBmaW5kQWxsTWF0Y2hlcyxcbiAgICAgIGlnbm9yZUxvY2F0aW9uLFxuICAgICAgbG9jYXRpb24sXG4gICAgICB0aHJlc2hvbGQsXG4gICAgICBkaXN0YW5jZVxuICAgIH07XG5cbiAgICBwYXR0ZXJuID0gaXNDYXNlU2Vuc2l0aXZlID8gcGF0dGVybiA6IHBhdHRlcm4udG9Mb3dlckNhc2UoKTtcbiAgICBwYXR0ZXJuID0gaWdub3JlRGlhY3JpdGljcyA/IHN0cmlwRGlhY3JpdGljcyhwYXR0ZXJuKSA6IHBhdHRlcm47XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbiAgICB0aGlzLnF1ZXJ5ID0gcGFyc2VRdWVyeSh0aGlzLnBhdHRlcm4sIHRoaXMub3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgY29uZGl0aW9uKF8sIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy51c2VFeHRlbmRlZFNlYXJjaFxuICB9XG5cbiAgc2VhcmNoSW4odGV4dCkge1xuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5xdWVyeTtcblxuICAgIGlmICghcXVlcnkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlzTWF0Y2g6IGZhbHNlLFxuICAgICAgICBzY29yZTogMVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHsgaW5jbHVkZU1hdGNoZXMsIGlzQ2FzZVNlbnNpdGl2ZSwgaWdub3JlRGlhY3JpdGljcyB9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgdGV4dCA9IGlzQ2FzZVNlbnNpdGl2ZSA/IHRleHQgOiB0ZXh0LnRvTG93ZXJDYXNlKCk7XG4gICAgdGV4dCA9IGlnbm9yZURpYWNyaXRpY3MgPyBzdHJpcERpYWNyaXRpY3ModGV4dCkgOiB0ZXh0O1xuXG4gICAgbGV0IG51bU1hdGNoZXMgPSAwO1xuICAgIGxldCBhbGxJbmRpY2VzID0gW107XG4gICAgbGV0IHRvdGFsU2NvcmUgPSAwO1xuXG4gICAgLy8gT1JzXG4gICAgZm9yIChsZXQgaSA9IDAsIHFMZW4gPSBxdWVyeS5sZW5ndGg7IGkgPCBxTGVuOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IHNlYXJjaGVycyA9IHF1ZXJ5W2ldO1xuXG4gICAgICAvLyBSZXNldCBpbmRpY2VzXG4gICAgICBhbGxJbmRpY2VzLmxlbmd0aCA9IDA7XG4gICAgICBudW1NYXRjaGVzID0gMDtcblxuICAgICAgLy8gQU5Ec1xuICAgICAgZm9yIChsZXQgaiA9IDAsIHBMZW4gPSBzZWFyY2hlcnMubGVuZ3RoOyBqIDwgcExlbjsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IHNlYXJjaGVyID0gc2VhcmNoZXJzW2pdO1xuICAgICAgICBjb25zdCB7IGlzTWF0Y2gsIGluZGljZXMsIHNjb3JlIH0gPSBzZWFyY2hlci5zZWFyY2godGV4dCk7XG5cbiAgICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgICBudW1NYXRjaGVzICs9IDE7XG4gICAgICAgICAgdG90YWxTY29yZSArPSBzY29yZTtcbiAgICAgICAgICBpZiAoaW5jbHVkZU1hdGNoZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBzZWFyY2hlci5jb25zdHJ1Y3Rvci50eXBlO1xuICAgICAgICAgICAgaWYgKE11bHRpTWF0Y2hTZXQuaGFzKHR5cGUpKSB7XG4gICAgICAgICAgICAgIGFsbEluZGljZXMgPSBbLi4uYWxsSW5kaWNlcywgLi4uaW5kaWNlc107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhbGxJbmRpY2VzLnB1c2goaW5kaWNlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRvdGFsU2NvcmUgPSAwO1xuICAgICAgICAgIG51bU1hdGNoZXMgPSAwO1xuICAgICAgICAgIGFsbEluZGljZXMubGVuZ3RoID0gMDtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE9SIGNvbmRpdGlvbiwgc28gaWYgVFJVRSwgcmV0dXJuXG4gICAgICBpZiAobnVtTWF0Y2hlcykge1xuICAgICAgICBsZXQgcmVzdWx0ID0ge1xuICAgICAgICAgIGlzTWF0Y2g6IHRydWUsXG4gICAgICAgICAgc2NvcmU6IHRvdGFsU2NvcmUgLyBudW1NYXRjaGVzXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGluY2x1ZGVNYXRjaGVzKSB7XG4gICAgICAgICAgcmVzdWx0LmluZGljZXMgPSBhbGxJbmRpY2VzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE5vdGhpbmcgd2FzIG1hdGNoZWRcbiAgICByZXR1cm4ge1xuICAgICAgaXNNYXRjaDogZmFsc2UsXG4gICAgICBzY29yZTogMVxuICAgIH1cbiAgfVxufVxuXG5jb25zdCByZWdpc3RlcmVkU2VhcmNoZXJzID0gW107XG5cbmZ1bmN0aW9uIHJlZ2lzdGVyKC4uLmFyZ3MpIHtcbiAgcmVnaXN0ZXJlZFNlYXJjaGVycy5wdXNoKC4uLmFyZ3MpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTZWFyY2hlcihwYXR0ZXJuLCBvcHRpb25zKSB7XG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSByZWdpc3RlcmVkU2VhcmNoZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgbGV0IHNlYXJjaGVyQ2xhc3MgPSByZWdpc3RlcmVkU2VhcmNoZXJzW2ldO1xuICAgIGlmIChzZWFyY2hlckNsYXNzLmNvbmRpdGlvbihwYXR0ZXJuLCBvcHRpb25zKSkge1xuICAgICAgcmV0dXJuIG5ldyBzZWFyY2hlckNsYXNzKHBhdHRlcm4sIG9wdGlvbnMpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBCaXRhcFNlYXJjaChwYXR0ZXJuLCBvcHRpb25zKVxufVxuXG5jb25zdCBMb2dpY2FsT3BlcmF0b3IgPSB7XG4gIEFORDogJyRhbmQnLFxuICBPUjogJyRvcidcbn07XG5cbmNvbnN0IEtleVR5cGUgPSB7XG4gIFBBVEg6ICckcGF0aCcsXG4gIFBBVFRFUk46ICckdmFsJ1xufTtcblxuY29uc3QgaXNFeHByZXNzaW9uID0gKHF1ZXJ5KSA9PlxuICAhIShxdWVyeVtMb2dpY2FsT3BlcmF0b3IuQU5EXSB8fCBxdWVyeVtMb2dpY2FsT3BlcmF0b3IuT1JdKTtcblxuY29uc3QgaXNQYXRoID0gKHF1ZXJ5KSA9PiAhIXF1ZXJ5W0tleVR5cGUuUEFUSF07XG5cbmNvbnN0IGlzTGVhZiA9IChxdWVyeSkgPT5cbiAgIWlzQXJyYXkocXVlcnkpICYmIGlzT2JqZWN0KHF1ZXJ5KSAmJiAhaXNFeHByZXNzaW9uKHF1ZXJ5KTtcblxuY29uc3QgY29udmVydFRvRXhwbGljaXQgPSAocXVlcnkpID0+ICh7XG4gIFtMb2dpY2FsT3BlcmF0b3IuQU5EXTogT2JqZWN0LmtleXMocXVlcnkpLm1hcCgoa2V5KSA9PiAoe1xuICAgIFtrZXldOiBxdWVyeVtrZXldXG4gIH0pKVxufSk7XG5cbi8vIFdoZW4gYGF1dG9gIGlzIGB0cnVlYCwgdGhlIHBhcnNlIGZ1bmN0aW9uIHdpbGwgaW5mZXIgYW5kIGluaXRpYWxpemUgYW5kIGFkZFxuLy8gdGhlIGFwcHJvcHJpYXRlIGBTZWFyY2hlcmAgaW5zdGFuY2VcbmZ1bmN0aW9uIHBhcnNlKHF1ZXJ5LCBvcHRpb25zLCB7IGF1dG8gPSB0cnVlIH0gPSB7fSkge1xuICBjb25zdCBuZXh0ID0gKHF1ZXJ5KSA9PiB7XG4gICAgbGV0IGtleXMgPSBPYmplY3Qua2V5cyhxdWVyeSk7XG5cbiAgICBjb25zdCBpc1F1ZXJ5UGF0aCA9IGlzUGF0aChxdWVyeSk7XG5cbiAgICBpZiAoIWlzUXVlcnlQYXRoICYmIGtleXMubGVuZ3RoID4gMSAmJiAhaXNFeHByZXNzaW9uKHF1ZXJ5KSkge1xuICAgICAgcmV0dXJuIG5leHQoY29udmVydFRvRXhwbGljaXQocXVlcnkpKVxuICAgIH1cblxuICAgIGlmIChpc0xlYWYocXVlcnkpKSB7XG4gICAgICBjb25zdCBrZXkgPSBpc1F1ZXJ5UGF0aCA/IHF1ZXJ5W0tleVR5cGUuUEFUSF0gOiBrZXlzWzBdO1xuXG4gICAgICBjb25zdCBwYXR0ZXJuID0gaXNRdWVyeVBhdGggPyBxdWVyeVtLZXlUeXBlLlBBVFRFUk5dIDogcXVlcnlba2V5XTtcblxuICAgICAgaWYgKCFpc1N0cmluZyhwYXR0ZXJuKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoTE9HSUNBTF9TRUFSQ0hfSU5WQUxJRF9RVUVSWV9GT1JfS0VZKGtleSkpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9iaiA9IHtcbiAgICAgICAga2V5SWQ6IGNyZWF0ZUtleUlkKGtleSksXG4gICAgICAgIHBhdHRlcm5cbiAgICAgIH07XG5cbiAgICAgIGlmIChhdXRvKSB7XG4gICAgICAgIG9iai5zZWFyY2hlciA9IGNyZWF0ZVNlYXJjaGVyKHBhdHRlcm4sIG9wdGlvbnMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gb2JqXG4gICAgfVxuXG4gICAgbGV0IG5vZGUgPSB7XG4gICAgICBjaGlsZHJlbjogW10sXG4gICAgICBvcGVyYXRvcjoga2V5c1swXVxuICAgIH07XG5cbiAgICBrZXlzLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBxdWVyeVtrZXldO1xuXG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChuZXh0KGl0ZW0pKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gbm9kZVxuICB9O1xuXG4gIGlmICghaXNFeHByZXNzaW9uKHF1ZXJ5KSkge1xuICAgIHF1ZXJ5ID0gY29udmVydFRvRXhwbGljaXQocXVlcnkpO1xuICB9XG5cbiAgcmV0dXJuIG5leHQocXVlcnkpXG59XG5cbi8vIFByYWN0aWNhbCBzY29yaW5nIGZ1bmN0aW9uXG5mdW5jdGlvbiBjb21wdXRlU2NvcmUoXG4gIHJlc3VsdHMsXG4gIHsgaWdub3JlRmllbGROb3JtID0gQ29uZmlnLmlnbm9yZUZpZWxkTm9ybSB9XG4pIHtcbiAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQpID0+IHtcbiAgICBsZXQgdG90YWxTY29yZSA9IDE7XG5cbiAgICByZXN1bHQubWF0Y2hlcy5mb3JFYWNoKCh7IGtleSwgbm9ybSwgc2NvcmUgfSkgPT4ge1xuICAgICAgY29uc3Qgd2VpZ2h0ID0ga2V5ID8ga2V5LndlaWdodCA6IG51bGw7XG5cbiAgICAgIHRvdGFsU2NvcmUgKj0gTWF0aC5wb3coXG4gICAgICAgIHNjb3JlID09PSAwICYmIHdlaWdodCA/IE51bWJlci5FUFNJTE9OIDogc2NvcmUsXG4gICAgICAgICh3ZWlnaHQgfHwgMSkgKiAoaWdub3JlRmllbGROb3JtID8gMSA6IG5vcm0pXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgcmVzdWx0LnNjb3JlID0gdG90YWxTY29yZTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybU1hdGNoZXMocmVzdWx0LCBkYXRhKSB7XG4gIGNvbnN0IG1hdGNoZXMgPSByZXN1bHQubWF0Y2hlcztcbiAgZGF0YS5tYXRjaGVzID0gW107XG5cbiAgaWYgKCFpc0RlZmluZWQobWF0Y2hlcykpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIG1hdGNoZXMuZm9yRWFjaCgobWF0Y2gpID0+IHtcbiAgICBpZiAoIWlzRGVmaW5lZChtYXRjaC5pbmRpY2VzKSB8fCAhbWF0Y2guaW5kaWNlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHsgaW5kaWNlcywgdmFsdWUgfSA9IG1hdGNoO1xuXG4gICAgbGV0IG9iaiA9IHtcbiAgICAgIGluZGljZXMsXG4gICAgICB2YWx1ZVxuICAgIH07XG5cbiAgICBpZiAobWF0Y2gua2V5KSB7XG4gICAgICBvYmoua2V5ID0gbWF0Y2gua2V5LnNyYztcbiAgICB9XG5cbiAgICBpZiAobWF0Y2guaWR4ID4gLTEpIHtcbiAgICAgIG9iai5yZWZJbmRleCA9IG1hdGNoLmlkeDtcbiAgICB9XG5cbiAgICBkYXRhLm1hdGNoZXMucHVzaChvYmopO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdHJhbnNmb3JtU2NvcmUocmVzdWx0LCBkYXRhKSB7XG4gIGRhdGEuc2NvcmUgPSByZXN1bHQuc2NvcmU7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdChcbiAgcmVzdWx0cyxcbiAgZG9jcyxcbiAge1xuICAgIGluY2x1ZGVNYXRjaGVzID0gQ29uZmlnLmluY2x1ZGVNYXRjaGVzLFxuICAgIGluY2x1ZGVTY29yZSA9IENvbmZpZy5pbmNsdWRlU2NvcmVcbiAgfSA9IHt9XG4pIHtcbiAgY29uc3QgdHJhbnNmb3JtZXJzID0gW107XG5cbiAgaWYgKGluY2x1ZGVNYXRjaGVzKSB0cmFuc2Zvcm1lcnMucHVzaCh0cmFuc2Zvcm1NYXRjaGVzKTtcbiAgaWYgKGluY2x1ZGVTY29yZSkgdHJhbnNmb3JtZXJzLnB1c2godHJhbnNmb3JtU2NvcmUpO1xuXG4gIHJldHVybiByZXN1bHRzLm1hcCgocmVzdWx0KSA9PiB7XG4gICAgY29uc3QgeyBpZHggfSA9IHJlc3VsdDtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBpdGVtOiBkb2NzW2lkeF0sXG4gICAgICByZWZJbmRleDogaWR4XG4gICAgfTtcblxuICAgIGlmICh0cmFuc2Zvcm1lcnMubGVuZ3RoKSB7XG4gICAgICB0cmFuc2Zvcm1lcnMuZm9yRWFjaCgodHJhbnNmb3JtZXIpID0+IHtcbiAgICAgICAgdHJhbnNmb3JtZXIocmVzdWx0LCBkYXRhKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRhXG4gIH0pXG59XG5cbmNsYXNzIEZ1c2Uge1xuICBjb25zdHJ1Y3Rvcihkb2NzLCBvcHRpb25zID0ge30sIGluZGV4KSB7XG4gICAgdGhpcy5vcHRpb25zID0geyAuLi5Db25maWcsIC4uLm9wdGlvbnMgfTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMub3B0aW9ucy51c2VFeHRlbmRlZFNlYXJjaCAmJlxuICAgICAgIXRydWVcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihFWFRFTkRFRF9TRUFSQ0hfVU5BVkFJTEFCTEUpXG4gICAgfVxuXG4gICAgdGhpcy5fa2V5U3RvcmUgPSBuZXcgS2V5U3RvcmUodGhpcy5vcHRpb25zLmtleXMpO1xuXG4gICAgdGhpcy5zZXRDb2xsZWN0aW9uKGRvY3MsIGluZGV4KTtcbiAgfVxuXG4gIHNldENvbGxlY3Rpb24oZG9jcywgaW5kZXgpIHtcbiAgICB0aGlzLl9kb2NzID0gZG9jcztcblxuICAgIGlmIChpbmRleCAmJiAhKGluZGV4IGluc3RhbmNlb2YgRnVzZUluZGV4KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKElOQ09SUkVDVF9JTkRFWF9UWVBFKVxuICAgIH1cblxuICAgIHRoaXMuX215SW5kZXggPVxuICAgICAgaW5kZXggfHxcbiAgICAgIGNyZWF0ZUluZGV4KHRoaXMub3B0aW9ucy5rZXlzLCB0aGlzLl9kb2NzLCB7XG4gICAgICAgIGdldEZuOiB0aGlzLm9wdGlvbnMuZ2V0Rm4sXG4gICAgICAgIGZpZWxkTm9ybVdlaWdodDogdGhpcy5vcHRpb25zLmZpZWxkTm9ybVdlaWdodFxuICAgICAgfSk7XG4gIH1cblxuICBhZGQoZG9jKSB7XG4gICAgaWYgKCFpc0RlZmluZWQoZG9jKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fZG9jcy5wdXNoKGRvYyk7XG4gICAgdGhpcy5fbXlJbmRleC5hZGQoZG9jKTtcbiAgfVxuXG4gIHJlbW92ZShwcmVkaWNhdGUgPSAoLyogZG9jLCBpZHggKi8pID0+IGZhbHNlKSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IHRoaXMuX2RvY3MubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IGRvYyA9IHRoaXMuX2RvY3NbaV07XG4gICAgICBpZiAocHJlZGljYXRlKGRvYywgaSkpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVBdChpKTtcbiAgICAgICAgaSAtPSAxO1xuICAgICAgICBsZW4gLT0gMTtcblxuICAgICAgICByZXN1bHRzLnB1c2goZG9jKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0c1xuICB9XG5cbiAgcmVtb3ZlQXQoaWR4KSB7XG4gICAgdGhpcy5fZG9jcy5zcGxpY2UoaWR4LCAxKTtcbiAgICB0aGlzLl9teUluZGV4LnJlbW92ZUF0KGlkeCk7XG4gIH1cblxuICBnZXRJbmRleCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbXlJbmRleFxuICB9XG5cbiAgc2VhcmNoKHF1ZXJ5LCB7IGxpbWl0ID0gLTEgfSA9IHt9KSB7XG4gICAgY29uc3Qge1xuICAgICAgaW5jbHVkZU1hdGNoZXMsXG4gICAgICBpbmNsdWRlU2NvcmUsXG4gICAgICBzaG91bGRTb3J0LFxuICAgICAgc29ydEZuLFxuICAgICAgaWdub3JlRmllbGROb3JtXG4gICAgfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGxldCByZXN1bHRzID0gaXNTdHJpbmcocXVlcnkpXG4gICAgICA/IGlzU3RyaW5nKHRoaXMuX2RvY3NbMF0pXG4gICAgICAgID8gdGhpcy5fc2VhcmNoU3RyaW5nTGlzdChxdWVyeSlcbiAgICAgICAgOiB0aGlzLl9zZWFyY2hPYmplY3RMaXN0KHF1ZXJ5KVxuICAgICAgOiB0aGlzLl9zZWFyY2hMb2dpY2FsKHF1ZXJ5KTtcblxuICAgIGNvbXB1dGVTY29yZShyZXN1bHRzLCB7IGlnbm9yZUZpZWxkTm9ybSB9KTtcblxuICAgIGlmIChzaG91bGRTb3J0KSB7XG4gICAgICByZXN1bHRzLnNvcnQoc29ydEZuKTtcbiAgICB9XG5cbiAgICBpZiAoaXNOdW1iZXIobGltaXQpICYmIGxpbWl0ID4gLTEpIHtcbiAgICAgIHJlc3VsdHMgPSByZXN1bHRzLnNsaWNlKDAsIGxpbWl0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZm9ybWF0KHJlc3VsdHMsIHRoaXMuX2RvY3MsIHtcbiAgICAgIGluY2x1ZGVNYXRjaGVzLFxuICAgICAgaW5jbHVkZVNjb3JlXG4gICAgfSlcbiAgfVxuXG4gIF9zZWFyY2hTdHJpbmdMaXN0KHF1ZXJ5KSB7XG4gICAgY29uc3Qgc2VhcmNoZXIgPSBjcmVhdGVTZWFyY2hlcihxdWVyeSwgdGhpcy5vcHRpb25zKTtcbiAgICBjb25zdCB7IHJlY29yZHMgfSA9IHRoaXMuX215SW5kZXg7XG4gICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gICAgLy8gSXRlcmF0ZSBvdmVyIGV2ZXJ5IHN0cmluZyBpbiB0aGUgaW5kZXhcbiAgICByZWNvcmRzLmZvckVhY2goKHsgdjogdGV4dCwgaTogaWR4LCBuOiBub3JtIH0pID0+IHtcbiAgICAgIGlmICghaXNEZWZpbmVkKHRleHQpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGlzTWF0Y2gsIHNjb3JlLCBpbmRpY2VzIH0gPSBzZWFyY2hlci5zZWFyY2hJbih0ZXh0KTtcblxuICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgICBpdGVtOiB0ZXh0LFxuICAgICAgICAgIGlkeCxcbiAgICAgICAgICBtYXRjaGVzOiBbeyBzY29yZSwgdmFsdWU6IHRleHQsIG5vcm0sIGluZGljZXMgfV1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0c1xuICB9XG5cbiAgX3NlYXJjaExvZ2ljYWwocXVlcnkpIHtcblxuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBwYXJzZShxdWVyeSwgdGhpcy5vcHRpb25zKTtcblxuICAgIGNvbnN0IGV2YWx1YXRlID0gKG5vZGUsIGl0ZW0sIGlkeCkgPT4ge1xuICAgICAgaWYgKCFub2RlLmNoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IHsga2V5SWQsIHNlYXJjaGVyIH0gPSBub2RlO1xuXG4gICAgICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLl9maW5kTWF0Y2hlcyh7XG4gICAgICAgICAga2V5OiB0aGlzLl9rZXlTdG9yZS5nZXQoa2V5SWQpLFxuICAgICAgICAgIHZhbHVlOiB0aGlzLl9teUluZGV4LmdldFZhbHVlRm9ySXRlbUF0S2V5SWQoaXRlbSwga2V5SWQpLFxuICAgICAgICAgIHNlYXJjaGVyXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChtYXRjaGVzICYmIG1hdGNoZXMubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWR4LFxuICAgICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgICBtYXRjaGVzXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFtdXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBldmFsdWF0ZShjaGlsZCwgaXRlbSwgaWR4KTtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICByZXMucHVzaCguLi5yZXN1bHQpO1xuICAgICAgICB9IGVsc2UgaWYgKG5vZGUub3BlcmF0b3IgPT09IExvZ2ljYWxPcGVyYXRvci5BTkQpIHtcbiAgICAgICAgICByZXR1cm4gW11cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc1xuICAgIH07XG5cbiAgICBjb25zdCByZWNvcmRzID0gdGhpcy5fbXlJbmRleC5yZWNvcmRzO1xuICAgIGNvbnN0IHJlc3VsdE1hcCA9IHt9O1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcblxuICAgIHJlY29yZHMuZm9yRWFjaCgoeyAkOiBpdGVtLCBpOiBpZHggfSkgPT4ge1xuICAgICAgaWYgKGlzRGVmaW5lZChpdGVtKSkge1xuICAgICAgICBsZXQgZXhwUmVzdWx0cyA9IGV2YWx1YXRlKGV4cHJlc3Npb24sIGl0ZW0sIGlkeCk7XG5cbiAgICAgICAgaWYgKGV4cFJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gRGVkdXBlIHdoZW4gYWRkaW5nXG4gICAgICAgICAgaWYgKCFyZXN1bHRNYXBbaWR4XSkge1xuICAgICAgICAgICAgcmVzdWx0TWFwW2lkeF0gPSB7IGlkeCwgaXRlbSwgbWF0Y2hlczogW10gfTtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChyZXN1bHRNYXBbaWR4XSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGV4cFJlc3VsdHMuZm9yRWFjaCgoeyBtYXRjaGVzIH0pID0+IHtcbiAgICAgICAgICAgIHJlc3VsdE1hcFtpZHhdLm1hdGNoZXMucHVzaCguLi5tYXRjaGVzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdHNcbiAgfVxuXG4gIF9zZWFyY2hPYmplY3RMaXN0KHF1ZXJ5KSB7XG4gICAgY29uc3Qgc2VhcmNoZXIgPSBjcmVhdGVTZWFyY2hlcihxdWVyeSwgdGhpcy5vcHRpb25zKTtcbiAgICBjb25zdCB7IGtleXMsIHJlY29yZHMgfSA9IHRoaXMuX215SW5kZXg7XG4gICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gICAgLy8gTGlzdCBpcyBBcnJheTxPYmplY3Q+XG4gICAgcmVjb3Jkcy5mb3JFYWNoKCh7ICQ6IGl0ZW0sIGk6IGlkeCB9KSA9PiB7XG4gICAgICBpZiAoIWlzRGVmaW5lZChpdGVtKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgbGV0IG1hdGNoZXMgPSBbXTtcblxuICAgICAgLy8gSXRlcmF0ZSBvdmVyIGV2ZXJ5IGtleSAoaS5lLCBwYXRoKSwgYW5kIGZldGNoIHRoZSB2YWx1ZSBhdCB0aGF0IGtleVxuICAgICAga2V5cy5mb3JFYWNoKChrZXksIGtleUluZGV4KSA9PiB7XG4gICAgICAgIG1hdGNoZXMucHVzaChcbiAgICAgICAgICAuLi50aGlzLl9maW5kTWF0Y2hlcyh7XG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICB2YWx1ZTogaXRlbVtrZXlJbmRleF0sXG4gICAgICAgICAgICBzZWFyY2hlclxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKG1hdGNoZXMubGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgaWR4LFxuICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgbWF0Y2hlc1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHRzXG4gIH1cbiAgX2ZpbmRNYXRjaGVzKHsga2V5LCB2YWx1ZSwgc2VhcmNoZXIgfSkge1xuICAgIGlmICghaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFtdXG4gICAgfVxuXG4gICAgbGV0IG1hdGNoZXMgPSBbXTtcblxuICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgdmFsdWUuZm9yRWFjaCgoeyB2OiB0ZXh0LCBpOiBpZHgsIG46IG5vcm0gfSkgPT4ge1xuICAgICAgICBpZiAoIWlzRGVmaW5lZCh0ZXh0KSkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyBpc01hdGNoLCBzY29yZSwgaW5kaWNlcyB9ID0gc2VhcmNoZXIuc2VhcmNoSW4odGV4dCk7XG5cbiAgICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgICBtYXRjaGVzLnB1c2goe1xuICAgICAgICAgICAgc2NvcmUsXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICB2YWx1ZTogdGV4dCxcbiAgICAgICAgICAgIGlkeCxcbiAgICAgICAgICAgIG5vcm0sXG4gICAgICAgICAgICBpbmRpY2VzXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IHY6IHRleHQsIG46IG5vcm0gfSA9IHZhbHVlO1xuXG4gICAgICBjb25zdCB7IGlzTWF0Y2gsIHNjb3JlLCBpbmRpY2VzIH0gPSBzZWFyY2hlci5zZWFyY2hJbih0ZXh0KTtcblxuICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgbWF0Y2hlcy5wdXNoKHsgc2NvcmUsIGtleSwgdmFsdWU6IHRleHQsIG5vcm0sIGluZGljZXMgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hdGNoZXNcbiAgfVxufVxuXG5GdXNlLnZlcnNpb24gPSAnNy4xLjAnO1xuRnVzZS5jcmVhdGVJbmRleCA9IGNyZWF0ZUluZGV4O1xuRnVzZS5wYXJzZUluZGV4ID0gcGFyc2VJbmRleDtcbkZ1c2UuY29uZmlnID0gQ29uZmlnO1xuXG57XG4gIEZ1c2UucGFyc2VRdWVyeSA9IHBhcnNlO1xufVxuXG57XG4gIHJlZ2lzdGVyKEV4dGVuZGVkU2VhcmNoKTtcbn1cblxuZXhwb3J0IHsgRnVzZSBhcyBkZWZhdWx0IH07XG4iLCJpbXBvcnQgeyB1c2VTdGF0ZSwgdXNlQ2FsbGJhY2ssIHVzZVJlZiwgdXNlTWVtbyB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlQXRvbVZhbHVlIH0gZnJvbSBcImpvdGFpXCI7XG5pbXBvcnQgRnVzZSBmcm9tIFwiZnVzZS5qc1wiO1xuXG5pbXBvcnQgeyBhdXRvY29tcGxldGVTdGF0ZUF0b20gfSBmcm9tIFwic3JjL2F0b21zL2dsb2JhbFNlYXJjaFwiO1xuaW1wb3J0IHsgYW1wbGl0dWRlVHJhY2tFdmVudEF0b20gfSBmcm9tIFwic3JjL2F0b21zL2FtcGxpdHVkZS9hbXBsaXR1ZGVUcmFja0V2ZW50QXRvbVwiO1xuaW1wb3J0IHsgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSB9IGZyb20gXCJzcmMvY29udGV4dHMvYW1wbGl0dWRlQ29udGV4dFwiO1xuaW1wb3J0IHsgU3BpZmZ5V2lkZ2V0cyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3NwaWZmeVdpZGdldHNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBVc2VTZWFyY2hJbnB1dFByb3BzIHtcbiAgaW5pdGlhbFNlYXJjaFRleHQ/OiBzdHJpbmc7XG4gIHNlYXJjaE9yaWdpbjogU3BpZmZ5V2lkZ2V0cztcbiAgb25TZWFyY2hTdWJtaXQ/OiAocXVlcnk6IHN0cmluZykgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVc2VTZWFyY2hJbnB1dFJldHVybiB7XG4gIC8vIFN0YXRlXG4gIHNlYXJjaFRleHQ6IHN0cmluZztcbiAgaGFzVGV4dDogYm9vbGVhbjtcbiAgaXNGb2N1c2VkOiBib29sZWFuO1xuICBmb2N1c2VkSW5kZXg6IG51bWJlcjtcbiAgZm9jdXNlZE9wdGlvbklkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGF1dG9jb21wbGV0ZVJlc3VsdHM6IHN0cmluZ1tdO1xuICBzaG91bGRTaG93QXV0b2NvbXBsZXRlOiBib29sZWFuO1xuICBcbiAgLy8gSGFuZGxlcnNcbiAgaGFuZGxlU2VhcmNoSW5wdXRDaGFuZ2U6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICBoYW5kbGVTZWFyY2hJbnB1dEZvY3VzOiAoKSA9PiB2b2lkO1xuICBoYW5kbGVTZWFyY2hJbnB1dEJsdXI6ICgpID0+IHZvaWQ7XG4gIGhhbmRsZUtleURvd246IChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4gdm9pZDtcbiAgaGFuZGxlQXV0b2NvbXBsZXRlU2VsZWN0OiAoc3VnZ2VzdGlvbjogc3RyaW5nLCByYW5rUG9zaXRpb24/OiBudW1iZXIpID0+IHZvaWQ7XG4gIGhhbmRsZVN1Ym1pdFNlYXJjaDogKCkgPT4gdm9pZDtcbiAgXG4gIC8vIFV0aWxpdGllc1xuICBzZXRTZWFyY2hUZXh0OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkO1xuICByZXNldFNlYXJjaDogKCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGNvbnN0IHVzZVNlYXJjaElucHV0ID0gKHtcbiAgaW5pdGlhbFNlYXJjaFRleHQgPSBcIlwiLFxuICBzZWFyY2hPcmlnaW4sXG4gIG9uU2VhcmNoU3VibWl0LFxufTogVXNlU2VhcmNoSW5wdXRQcm9wcyk6IFVzZVNlYXJjaElucHV0UmV0dXJuID0+IHtcbiAgY29uc3QgdHJhY2sgPSB1c2VBdG9tVmFsdWUoYW1wbGl0dWRlVHJhY2tFdmVudEF0b20pO1xuXG4gIC8vIFN0YXRlXG4gIGNvbnN0IFtzZWFyY2hUZXh0LCBzZXRTZWFyY2hUZXh0XSA9IHVzZVN0YXRlKGluaXRpYWxTZWFyY2hUZXh0KTtcbiAgY29uc3QgW2hhc1RleHQsIHNldEhhc1RleHRdID0gdXNlU3RhdGUoaW5pdGlhbFNlYXJjaFRleHQudHJpbSgpLmxlbmd0aCA+IDApO1xuICBjb25zdCBbaXNGb2N1c2VkLCBzZXRJc0ZvY3VzZWRdID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBbZm9jdXNlZEluZGV4LCBzZXRGb2N1c2VkSW5kZXhdID0gdXNlU3RhdGUoLTEpO1xuICBjb25zdCBbZm9jdXNlZE9wdGlvbklkLCBzZXRGb2N1c2VkT3B0aW9uSWRdID0gdXNlU3RhdGU8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgICB1bmRlZmluZWRcbiAgKTtcbiAgY29uc3QgYXV0b2NvbXBsZXRlU3RhdGUgPSB1c2VBdG9tVmFsdWUoYXV0b2NvbXBsZXRlU3RhdGVBdG9tKTtcbiAgY29uc3QgZ2xvYmFsQXV0b2NvbXBsZXRlUmVzdWx0cyA9IGF1dG9jb21wbGV0ZVN0YXRlLnJlc3VsdHM7XG4gIGNvbnN0IGlzQXV0b2NvbXBsZXRlRW5hYmxlZCA9IGdsb2JhbEF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoID4gMDtcblxuICAvLyBSZWZzXG4gIGNvbnN0IGlzU2VsZWN0aW5nQXV0b2NvbXBsZXRlID0gdXNlUmVmKGZhbHNlKTtcblxuICAvLyBDb21wdXRlZFxuICBjb25zdCBzaG91bGRTaG93QXV0b2NvbXBsZXRlID0gaGFzVGV4dCAmJiBpc0ZvY3VzZWQgJiYgaXNBdXRvY29tcGxldGVFbmFibGVkO1xuXG4gIGNvbnN0IGF1dG9jb21wbGV0ZVJlc3VsdHNMaW1pdCA9IDU7XG5cbiAgLy8gQ29uZmlndXJlIEZ1c2UuanMgZm9yIGZ1enp5IHNlYXJjaCB3aXRoIGN1c3RvbSBzY29yaW5nXG4gIGNvbnN0IGZ1c2VPcHRpb25zID0gdXNlTWVtbyhcbiAgICAoKSA9PiAoe1xuICAgICAgaW5jbHVkZVNjb3JlOiB0cnVlLFxuICAgICAgaW5jbHVkZU1hdGNoZXM6IHRydWUsXG4gICAgICAvLyBGdXp6eSBtYXRjaGluZyB0aHJlc2hvbGQgKDAuMCA9IHBlcmZlY3QgbWF0Y2gsIDEuMCA9IG1hdGNoIGFueXRoaW5nKVxuICAgICAgdGhyZXNob2xkOiAwLjMsXG4gICAgICAvLyBMb2NhdGlvbiB3aGVyZSBtYXRjaCBpcyBleHBlY3RlZCAoMCA9IGJlZ2lubmluZylcbiAgICAgIGxvY2F0aW9uOiAwLFxuICAgICAgLy8gRGlzdGFuY2UgZnJvbSBsb2NhdGlvbiB3aGVyZSBtYXRjaCBjYW4gYmUgZm91bmQgLSBzbWFsbGVyIGZvciBwcmVmaXggcHJlZmVyZW5jZVxuICAgICAgZGlzdGFuY2U6IDQsXG4gICAgICAvLyBNaW5pbXVtIGNoYXJhY3RlciBsZW5ndGggYmVmb3JlIGZ1enp5IG1hdGNoaW5nIHN0YXJ0c1xuICAgICAgbWluTWF0Y2hDaGFyTGVuZ3RoOiAxLFxuICAgICAgLy8gS2V5cyB0byBzZWFyY2ggKHdlJ3JlIHNlYXJjaGluZyBzdHJpbmdzIGRpcmVjdGx5LCBzbyBubyBrZXlzIG5lZWRlZClcbiAgICAgIGtleXM6IFtdLFxuICAgICAgLy8gVXNlIGV4dGVuZGVkIHNlYXJjaCBmb3IgZXhhY3QgbWF0Y2hlcyBhbmQgcHJlZml4IG1hdGNoaW5nXG4gICAgICB1c2VFeHRlbmRlZFNlYXJjaDogZmFsc2UsXG4gICAgICAvLyBEb24ndCBpZ25vcmUgbG9jYXRpb24gLSB0aGlzIGhlbHBzIHByaW9yaXRpemUgbWF0Y2hlcyBhdCB0aGUgYmVnaW5uaW5nXG4gICAgICBpZ25vcmVMb2NhdGlvbjogZmFsc2UsXG4gICAgfSksXG4gICAgW11cbiAgKTtcblxuICBjb25zdCBmdXNlID0gdXNlTWVtbygoKSA9PiB7XG4gICAgaWYgKCFnbG9iYWxBdXRvY29tcGxldGVSZXN1bHRzLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIG5ldyBGdXNlKGdsb2JhbEF1dG9jb21wbGV0ZVJlc3VsdHMsIGZ1c2VPcHRpb25zKTtcbiAgfSwgW2dsb2JhbEF1dG9jb21wbGV0ZVJlc3VsdHMsIGZ1c2VPcHRpb25zXSk7XG5cbiAgLy8gQXV0b2NvbXBsZXRlIGZ1enp5IHNlYXJjaCB1c2luZyBGdXNlLmpzXG4gIGNvbnN0IGF1dG9jb21wbGV0ZVJlc3VsdHMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoIWlzQXV0b2NvbXBsZXRlRW5hYmxlZCB8fCAhZnVzZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGlmICghc2VhcmNoVGV4dC50cmltKCkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBmdXNlUmVzdWx0cyA9IGZ1c2Uuc2VhcmNoKHNlYXJjaFRleHQpO1xuXG4gICAgLy8gVXNlIG9ubHkgRnVzZS5qcyBzY29yaW5nIChyZXN1bHRzIGFyZSBhbHJlYWR5IHNvcnRlZCBieSByZWxldmFuY2UpXG4gICAgcmV0dXJuIGZ1c2VSZXN1bHRzXG4gICAgICAuc2xpY2UoMCwgYXV0b2NvbXBsZXRlUmVzdWx0c0xpbWl0KVxuICAgICAgLm1hcCgocmVzdWx0KSA9PiByZXN1bHQuaXRlbSk7XG4gIH0sIFtpc0F1dG9jb21wbGV0ZUVuYWJsZWQsIGZ1c2UsIHNlYXJjaFRleHQsIGF1dG9jb21wbGV0ZVJlc3VsdHNMaW1pdF0pO1xuXG4gIC8vIEhhbmRsZXJzXG4gIGNvbnN0IGhhbmRsZVNlYXJjaElucHV0Q2hhbmdlID0gdXNlQ2FsbGJhY2soXG4gICAgKG5ld1ZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIGlzIGNoYW5naW5nIHRleHQsIHRoZXkgbXVzdCBiZSBpbnRlcmFjdGluZyB3aXRoIHRoZSBpbnB1dFxuICAgICAgLy8gU28gd2UgY2FuIHNhZmVseSBhc3N1bWUgdGhleSdyZSBmb2N1c2VkXG4gICAgICBpZiAobmV3VmFsdWUgIT09IHNlYXJjaFRleHQpIHtcbiAgICAgICAgc2V0SXNGb2N1c2VkKHRydWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAobmV3VmFsdWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHRyYWNrPy4oe1xuICAgICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hJbnB1dFN0YXJ0ZWQsXG4gICAgICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICAgICAgc2VhcmNoT3JpZ2luLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgc2V0U2VhcmNoVGV4dChuZXdWYWx1ZSk7XG4gICAgICBzZXRIYXNUZXh0KG5ld1ZhbHVlLnRyaW0oKS5sZW5ndGggPiAwKTtcbiAgICAgIHNldEZvY3VzZWRJbmRleCgtMSk7XG4gICAgICBzZXRGb2N1c2VkT3B0aW9uSWQodW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIFtzZWFyY2hPcmlnaW4sIHNlYXJjaFRleHQsIHRyYWNrXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZVNlYXJjaElucHV0Rm9jdXMgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgc2V0SXNGb2N1c2VkKHRydWUpO1xuICB9LCBbXSk7XG5cbiAgY29uc3QgaGFuZGxlU2VhcmNoSW5wdXRCbHVyID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKCFpc1NlbGVjdGluZ0F1dG9jb21wbGV0ZS5jdXJyZW50KSB7XG4gICAgICAgIHNldElzRm9jdXNlZChmYWxzZSk7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleCgtMSk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZCh1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0sIDE1MCk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBoYW5kbGVTdWJtaXRTZWFyY2ggPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgc2V0SXNGb2N1c2VkKGZhbHNlKTtcbiAgICBpZiAoc2VhcmNoVGV4dC50cmltKCkgJiYgb25TZWFyY2hTdWJtaXQpIHtcbiAgICAgIHRyYWNrPy4oe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoUXVlcnlTdWJtaXR0ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBzZWFyY2hPcmlnaW4sXG4gICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LnRyaW0oKSxcbiAgICAgICAgfSxcbiAgICAgICAgYWxzb1NlbmRUb0dvb2dsZUFuYWx5dGljczogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgb25TZWFyY2hTdWJtaXQoc2VhcmNoVGV4dC50cmltKCkpO1xuICAgIH1cbiAgfSwgW3NlYXJjaFRleHQsIG9uU2VhcmNoU3VibWl0LCBzZWFyY2hPcmlnaW4sIHRyYWNrXSk7XG5cbiAgY29uc3QgaGFuZGxlQXV0b2NvbXBsZXRlU2VsZWN0ID0gdXNlQ2FsbGJhY2soXG4gICAgKHN1Z2dlc3Rpb246IHN0cmluZywgcmFua1Bvc2l0aW9uPzogbnVtYmVyKSA9PiB7XG4gICAgICBpc1NlbGVjdGluZ0F1dG9jb21wbGV0ZS5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIHNldFNlYXJjaFRleHQoc3VnZ2VzdGlvbik7XG4gICAgICBzZXRIYXNUZXh0KHN1Z2dlc3Rpb24udHJpbSgpLmxlbmd0aCA+IDApO1xuICAgICAgc2V0SXNGb2N1c2VkKGZhbHNlKTtcblxuICAgICAgdHJhY2s/Lih7XG4gICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hJbnB1dFN0YXJ0ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBzZWFyY2hPcmlnaW4sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKG9uU2VhcmNoU3VibWl0KSB7XG4gICAgICAgIG9uU2VhcmNoU3VibWl0KHN1Z2dlc3Rpb24udHJpbSgpKTtcbiAgICAgIH1cblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlzU2VsZWN0aW5nQXV0b2NvbXBsZXRlLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIH0sIDEwMCk7XG4gICAgfSxcbiAgICBbb25TZWFyY2hTdWJtaXQsIHNlYXJjaE9yaWdpbiwgdHJhY2tdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlS2V5RG93biA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd0Rvd25cIikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBuZXdJbmRleCA9IChmb2N1c2VkSW5kZXggKyAxKSAlIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoO1xuICAgICAgICBzZXRGb2N1c2VkSW5kZXgobmV3SW5kZXgpO1xuICAgICAgICBzZXRGb2N1c2VkT3B0aW9uSWQoYG9wdGlvbi0ke25ld0luZGV4fWApO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dVcFwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IG5ld0luZGV4ID1cbiAgICAgICAgICAoZm9jdXNlZEluZGV4IC0gMSArIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoKSAlXG4gICAgICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cy5sZW5ndGg7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleChuZXdJbmRleCk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZChgb3B0aW9uLSR7bmV3SW5kZXh9YCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiKSB7XG4gICAgICAgIGlmIChmb2N1c2VkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25UZXh0ID0gYXV0b2NvbXBsZXRlUmVzdWx0c1tmb2N1c2VkSW5kZXhdO1xuICAgICAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdChzdWdnZXN0aW9uVGV4dCwgZm9jdXNlZEluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiRXNjYXBlXCIpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgc2V0Rm9jdXNlZEluZGV4KC0xKTtcbiAgICAgICAgc2V0Rm9jdXNlZE9wdGlvbklkKHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbXG4gICAgICBhdXRvY29tcGxldGVSZXN1bHRzLFxuICAgICAgZm9jdXNlZEluZGV4LFxuICAgICAgaGFuZGxlQXV0b2NvbXBsZXRlU2VsZWN0LFxuICAgICAgaGFuZGxlU3VibWl0U2VhcmNoLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBzZXRTZWFyY2hUZXh0VXRpbGl0eSA9IHVzZUNhbGxiYWNrKCh0ZXh0OiBzdHJpbmcpID0+IHtcbiAgICBzZXRTZWFyY2hUZXh0KHRleHQpO1xuICAgIHNldEhhc1RleHQodGV4dC50cmltKCkubGVuZ3RoID4gMCk7XG4gIH0sIFtdKTtcblxuICBjb25zdCByZXNldFNlYXJjaCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRTZWFyY2hUZXh0KFwiXCIpO1xuICAgIHNldEhhc1RleHQoZmFsc2UpO1xuICAgIHNldElzRm9jdXNlZChmYWxzZSk7XG4gICAgc2V0Rm9jdXNlZEluZGV4KC0xKTtcbiAgICBzZXRGb2N1c2VkT3B0aW9uSWQodW5kZWZpbmVkKTtcbiAgfSwgW10pO1xuXG4gIHJldHVybiB7XG4gICAgLy8gU3RhdGVcbiAgICBzZWFyY2hUZXh0LFxuICAgIGhhc1RleHQsXG4gICAgaXNGb2N1c2VkLFxuICAgIGZvY3VzZWRJbmRleCxcbiAgICBmb2N1c2VkT3B0aW9uSWQsXG4gICAgYXV0b2NvbXBsZXRlUmVzdWx0cyxcbiAgICBzaG91bGRTaG93QXV0b2NvbXBsZXRlLFxuXG4gICAgLy8gSGFuZGxlcnNcbiAgICBoYW5kbGVTZWFyY2hJbnB1dENoYW5nZSxcbiAgICBoYW5kbGVTZWFyY2hJbnB1dEZvY3VzLFxuICAgIGhhbmRsZVNlYXJjaElucHV0Qmx1cixcbiAgICBoYW5kbGVLZXlEb3duLFxuICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICBoYW5kbGVTdWJtaXRTZWFyY2gsXG5cbiAgICAvLyBVdGlsaXRpZXNcbiAgICBzZXRTZWFyY2hUZXh0OiBzZXRTZWFyY2hUZXh0VXRpbGl0eSxcbiAgICByZXNldFNlYXJjaCxcbiAgfTtcbn07IiwiaW1wb3J0IHsgUHJvZHVjdFJldHJpZXZhbFBhcmFtcywgUHJvZHVjdFJldHJpZXZhbFJlc3VsdCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8vIFRoaXMgd2lsbCBiZSBzZXQgYnkgdGhlIFByb2R1Y3RSZXRyaWV2YWxQcm92aWRlciB3aGVuIGl0IGluaXRpYWxpemVzXG5sZXQgcHJvZHVjdFJldHJpZXZhbEZ1bmN0aW9uOlxuICB8ICgocGFyYW1zOiBQcm9kdWN0UmV0cmlldmFsUGFyYW1zKSA9PiBQcm9taXNlPFByb2R1Y3RSZXRyaWV2YWxSZXN1bHQ+KVxuICB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgY29uc3Qgc2V0UHJvZHVjdFJldHJpZXZhbEZ1bmN0aW9uID0gKFxuICBmbjogKHBhcmFtczogUHJvZHVjdFJldHJpZXZhbFBhcmFtcykgPT4gUHJvbWlzZTxQcm9kdWN0UmV0cmlldmFsUmVzdWx0PlxuKSA9PiB7XG4gIHByb2R1Y3RSZXRyaWV2YWxGdW5jdGlvbiA9IGZuO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFByb2R1Y3RSZXRyaWV2YWxGdW5jdGlvbiA9ICgpID0+IHtcbiAgaWYgKCFwcm9kdWN0UmV0cmlldmFsRnVuY3Rpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcIlByb2R1Y3QgcmV0cmlldmFsIGZ1bmN0aW9uIG5vdCBpbml0aWFsaXplZC4gTWFrZSBzdXJlIFByb2R1Y3RSZXRyaWV2YWxQcm92aWRlciBpcyBtb3VudGVkLlwiXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcHJvZHVjdFJldHJpZXZhbEZ1bmN0aW9uO1xufTtcblxuZXhwb3J0IGNvbnN0IGNsZWFyUHJvZHVjdFJldHJpZXZhbEZ1bmN0aW9uID0gKCkgPT4ge1xuICBwcm9kdWN0UmV0cmlldmFsRnVuY3Rpb24gPSBudWxsO1xufTsiLCJcbmltcG9ydCB7IGF0b20gfSBmcm9tIFwiam90YWlcIjtcbmltcG9ydCB7IGdldFByb2R1Y3RSZXRyaWV2YWxGdW5jdGlvbiB9IGZyb20gXCIuL3Byb2R1Y3RSZXRyaWV2YWxBZGFwdGVyXCI7XG5pbXBvcnQgeyBQcm9kdWN0UmV0cmlldmFsUGFyYW1zLCBQcm9kdWN0UmV0cmlldmFsUmVzdWx0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuaW50ZXJmYWNlIFByb2R1Y3RSZXRyaWV2YWxTdGF0ZSB7XG4gIGRhdGE6IFByb2R1Y3RSZXRyaWV2YWxSZXN1bHQgfCBudWxsO1xuICBsb2FkaW5nOiBib29sZWFuO1xuICBlcnJvcjogc3RyaW5nIHwgbnVsbDtcbiAgbGFzdFByb2R1Y3RJZHM6IHN0cmluZ1tdIHwgbnVsbDtcbn1cblxuZXhwb3J0IGNvbnN0IHByb2R1Y3RSZXRyaWV2YWxBdG9tID0gYXRvbTxQcm9kdWN0UmV0cmlldmFsU3RhdGU+KHtcbiAgZGF0YTogbnVsbCxcbiAgbG9hZGluZzogZmFsc2UsXG4gIGVycm9yOiBudWxsLFxuICBsYXN0UHJvZHVjdElkczogbnVsbCxcbn0pO1xuXG5leHBvcnQgY29uc3QgcGVyZm9ybVByb2R1Y3RSZXRyaWV2YWxBdG9tID0gYXRvbShcbiAgbnVsbCxcbiAgYXN5bmMgKGdldCwgc2V0LCBwYXJhbXM6IFByb2R1Y3RSZXRyaWV2YWxQYXJhbXMpID0+IHtcbiAgICBjb25zdCBjdXJyZW50U3RhdGUgPSBnZXQocHJvZHVjdFJldHJpZXZhbEF0b20pO1xuXG4gICAgaWYgKGN1cnJlbnRTdGF0ZS5sb2FkaW5nKSB7XG4gICAgICByZXR1cm47IC8vIFByZXZlbnQgY29uY3VycmVudCByZXRyaWV2YWxzXG4gICAgfVxuXG4gICAgc2V0KHByb2R1Y3RSZXRyaWV2YWxBdG9tLCB7XG4gICAgICBkYXRhOiBudWxsLFxuICAgICAgbG9hZGluZzogdHJ1ZSxcbiAgICAgIGVycm9yOiBudWxsLFxuICAgICAgbGFzdFByb2R1Y3RJZHM6IHBhcmFtcy5wcm9kdWN0SWRzLFxuICAgIH0pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJldHJpZXZlUHJvZHVjdHMgPSBnZXRQcm9kdWN0UmV0cmlldmFsRnVuY3Rpb24oKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJldHJpZXZlUHJvZHVjdHMocGFyYW1zKTtcbiAgICAgIHNldChwcm9kdWN0UmV0cmlldmFsQXRvbSwge1xuICAgICAgICBkYXRhOiByZXN1bHQsXG4gICAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgICAgbGFzdFByb2R1Y3RJZHM6IHBhcmFtcy5wcm9kdWN0SWRzLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9XG4gICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogXCJBbiB1bmtub3duIGVycm9yIG9jY3VycmVkXCI7XG4gICAgICBzZXQocHJvZHVjdFJldHJpZXZhbEF0b20sIHtcbiAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgIGVycm9yOiBlcnJvck1lc3NhZ2UsXG4gICAgICAgIGxhc3RQcm9kdWN0SWRzOiBwYXJhbXMucHJvZHVjdElkcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuKTtcblxuLy8gR2V0IGp1c3QgdGhlIHByb2R1Y3RzIGFycmF5IChhbHJlYWR5IG5vcm1hbGl6ZWQgYnkgc2VydmljZSlcbmV4cG9ydCBjb25zdCByZXRyaWV2ZWRQcm9kdWN0c0F0b20gPSBhdG9tKChnZXQpID0+IHtcbiAgY29uc3QgcmV0cmlldmFsRGF0YSA9IGdldChwcm9kdWN0UmV0cmlldmFsQXRvbSkuZGF0YTtcbiAgcmV0dXJuIHJldHJpZXZhbERhdGE/LnByb2R1Y3RzIHx8IFtdO1xufSk7XG5cbmV4cG9ydCBjb25zdCBwcm9kdWN0UmV0cmlldmFsTG9hZGluZ0F0b20gPSBhdG9tKChnZXQpID0+IHtcbiAgcmV0dXJuIGdldChwcm9kdWN0UmV0cmlldmFsQXRvbSkubG9hZGluZztcbn0pO1xuXG5leHBvcnQgY29uc3QgcHJvZHVjdFJldHJpZXZhbEVycm9yQXRvbSA9IGF0b20oKGdldCkgPT4ge1xuICByZXR1cm4gZ2V0KHByb2R1Y3RSZXRyaWV2YWxBdG9tKS5lcnJvcjtcbn0pOyIsImltcG9ydCB7IHVzZUF0b21WYWx1ZSwgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgdXNlRWZmZWN0IH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VGZWF0dXJlRmxhZ1NlcnZpY2UgfSBmcm9tIFwic3JjL2NvbnRleHRzL2ZlYXR1cmVGbGFnU2VydmljZUNvbnRleHQvZmVhdHVyZUZsYWdTZXJ2aWNlQ29udGV4dFwiO1xuaW1wb3J0IHtcbiAgcmV0cmlldmVkUHJvZHVjdHNBdG9tLFxuICBwZXJmb3JtUHJvZHVjdFJldHJpZXZhbEF0b20sXG4gIHByb2R1Y3RSZXRyaWV2YWxBdG9tLFxufSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC9wcm9kdWN0UmV0cmlldmFsQVBJXCI7XG5pbXBvcnQgeyB1c2VOZXdPcmdDb25maWcgfSBmcm9tIFwiLi4vTmV3T3JnQ29uZmlnXCI7XG5pbXBvcnQgeyBTZWFyY2hSZXNwb25zZVByb2R1Y3RBdHRyaWJ1dGVzIH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvYXBpL3Jlc3BvbnNlXCI7XG5pbXBvcnQgeyBGZWF0dXJlR2F0ZXMgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVsc1wiO1xuXG4vKipcbiAqIEEgaG9vayB0byBnZXQgcmVjb21tZW5kZWQgcHJvZHVjdHMuXG4gKiBJdCBjaGVja3MgdGhlIGBJc1JlY29tbWVuZGVkUHJvZHVjdHNFbmFibGVkYCBmZWF0dXJlIGdhdGUgYW5kIHRyaWdnZXJzIGZldGNoaW5nIGlmIG5lZWRlZC5cbiAqIElmIHRoZSBnYXRlIGlzIGVuYWJsZWQsIGl0IHJldHVybnMgdGhlIGxpc3Qgb2YgcmVjb21tZW5kZWQgcHJvZHVjdHMuXG4gKiBJZiB0aGUgZ2F0ZSBpcyBkaXNhYmxlZCwgaXQgcmV0dXJucyBhbiBlbXB0eSBhcnJheS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgbGlzdCBvZiByZWNvbW1lbmRlZCBwcm9kdWN0cyBvciBhbiBlbXB0eSBhcnJheS5cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZVJlY29tbWVuZGVkUHJvZHVjdHMgPVxuICAoKTogU2VhcmNoUmVzcG9uc2VQcm9kdWN0QXR0cmlidXRlc1tcImF0dHJpYnV0ZXNcIl1bXSA9PiB7XG4gICAgY29uc3QgeyBmZWF0dXJlRmxhZ1NlcnZpY2UgfSA9IHVzZUZlYXR1cmVGbGFnU2VydmljZSgpO1xuICAgIGNvbnN0IGlzRW5hYmxlZCA9IGZlYXR1cmVGbGFnU2VydmljZT8uaXNGZWF0dXJlR2F0ZUVuYWJsZWQoXG4gICAgICBGZWF0dXJlR2F0ZXMuSXNSZWNvbW1lbmRlZFByb2R1Y3RzRW5hYmxlZFxuICAgICk7XG4gICAgY29uc3QgcmVjb21tZW5kZWRQcm9kdWN0cyA9IHVzZUF0b21WYWx1ZShyZXRyaWV2ZWRQcm9kdWN0c0F0b20pO1xuICAgIGNvbnN0IHBlcmZvcm1Qcm9kdWN0UmV0cmlldmFsID0gdXNlU2V0QXRvbShwZXJmb3JtUHJvZHVjdFJldHJpZXZhbEF0b20pO1xuICAgIGNvbnN0IHsgbGFzdFByb2R1Y3RJZHMgfSA9IHVzZUF0b21WYWx1ZShwcm9kdWN0UmV0cmlldmFsQXRvbSk7XG4gICAgY29uc3Qgb3JnVUlDb25maWcgPSB1c2VOZXdPcmdDb25maWcoKTtcblxuICAgIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCByZWNvbW1lbmRlZFByb2R1Y3RJZHMgPSBvcmdVSUNvbmZpZy5mcm9udGVuZENvbmZpZz8udWlDb25maWdzPy5zZWFyY2hDb25maWdcbiAgICAgICAgPyBvcmdVSUNvbmZpZy5mcm9udGVuZENvbmZpZz8udWlDb25maWdzPy5zZWFyY2hDb25maWcucmVjb21tZW5kZWRQcm9kdWN0c1xuICAgICAgICA6IFtdO1xuICAgICAgLy8gRmV0Y2ggb25seSBpZiB0aGUgZmVhdHVyZSBpcyBlbmFibGVkLCB0aGVyZSBhcmUgSURzIHRvIGZldGNoLCBhbmQgd2UgaGF2ZW4ndCBhbHJlYWR5IGZldGNoZWQgdGhlbS5cbiAgICAgIGlmIChcbiAgICAgICAgaXNFbmFibGVkICYmXG4gICAgICAgIHJlY29tbWVuZGVkUHJvZHVjdElkcyAmJlxuICAgICAgICByZWNvbW1lbmRlZFByb2R1Y3RJZHMubGVuZ3RoID4gMCAmJlxuICAgICAgICAhbGFzdFByb2R1Y3RJZHNcbiAgICAgICkge1xuICAgICAgICBwZXJmb3JtUHJvZHVjdFJldHJpZXZhbCh7IHByb2R1Y3RJZHM6IHJlY29tbWVuZGVkUHJvZHVjdElkcyB9KTtcbiAgICAgIH1cbiAgICB9LCBbaXNFbmFibGVkLCBwZXJmb3JtUHJvZHVjdFJldHJpZXZhbCwgbGFzdFByb2R1Y3RJZHMsIG9yZ1VJQ29uZmlnXSk7XG5cbiAgICByZXR1cm4gaXNFbmFibGVkID8gcmVjb21tZW5kZWRQcm9kdWN0cyA6IFtdO1xuICB9OyIsImltcG9ydCB7IHVzZUF0b20sIHVzZUF0b21WYWx1ZSwgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmIH0gZnJvbSBcInJlYWN0XCI7XG5cbmltcG9ydCB7XG4gIGFkZFNlYXJjaEZpbHRlckF0b20sXG4gIGNsZWFyU2VhcmNoRmlsdGVyc0F0b20sXG4gIGNyZWF0ZUZpbHRlck9wdGlvbixcbiAgZmlsdGVyZWRTZWFyY2hQcm9kdWN0c0F0b20sXG4gIHBlcmZvcm1TZWFyY2hBdG9tLFxuICByZW1vdmVTZWFyY2hGaWx0ZXJBdG9tLFxuICBzZWFyY2hBdG9tLFxuICBzZWFyY2hGaWx0ZXJzQXRvbSxcbiAgc2VhcmNoUGFyYW1zQXRvbSxcbiAgc2VhcmNoUHJvZHVjdFNvcnRpbmdBdG9tLFxuICBzZWFyY2hTZWxlY3RlZEZpbHRlcnNBdG9tLFxuICBTZWxlY3RlZEZpbHRlck9wdGlvbixcbn0gZnJvbSBcInNyYy9hdG9tcy9zZWFyY2hcIjtcbmltcG9ydCB7XG4gIGlzRmlsdGVyT3BlbkF0b20sXG59IGZyb20gXCJzcmMvYXRvbXMvZ2xvYmFsU2VhcmNoL2dsb2JhbFNlYXJjaFwiO1xuaW1wb3J0IHsgZm9ybWF0RmlsdGVyRGlzcGxheU5hbWUgfSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC91dGlsc1wiO1xuaW1wb3J0IHsgUHJvZHVjdFNvcnRpbmcgfSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC90eXBlc1wiO1xuaW1wb3J0IHtcbiAgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgdXNlQW1wbGl0dWRlLFxufSBmcm9tIFwic3JjL2NvbnRleHRzL2FtcGxpdHVkZUNvbnRleHQvYW1wbGl0dWRlQ29udGV4dFwiO1xuaW1wb3J0IHsgU3BpZmZ5V2lkZ2V0cyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3NwaWZmeVdpZGdldHNcIjtcbmltcG9ydCB7IFByb2R1Y3RDYXJkQ29uZmlnIH0gZnJvbSBcInNyYy9jb250ZXh0cy90eXBlc1wiO1xuaW1wb3J0IHsgU2VhcmNoUmVzdWx0IH0gZnJvbSBcInNyYy9hcHBsaWNhdGlvbi9tb2RlbHMvYXBpL3NlYXJjaFwiO1xuaW1wb3J0IHsgU2VhcmNoUmVzcG9uc2VQcm9kdWN0IH0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiO1xuaW1wb3J0IHtcbiAgU2VhcmNoRmlsdGVyRGF0dW0sXG4gIFNlbGVjdEZpbHRlckl0ZW0sXG59IGZyb20gXCJzcmMvdHlwZXMvc2VhcmNoLWZpbHRlci10eXBlc1wiO1xuaW1wb3J0IHsgZ2V0U2VhcmNoUmVzdWx0c1N0YXRlLCBTZWFyY2hSZXN1bHRzU3RhdGUgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IG9yZ1Nob3J0TmFtZUF0b20gfSBmcm9tIFwic3JjL2F0b21zL2Vudml2ZS9lbnZpdmVDb25maWdcIjtcbmltcG9ydCB7IHVzZVRyYWNrQ29tcG9uZW50VmlzaWJsZUV2ZW50IH0gZnJvbSBcIi4uL1RyYWNrQ29tcG9uZW50VmlzaWJsZUV2ZW50XCI7XG5pbXBvcnQgeyBhbXBsaXR1ZGVUcmFja0V2ZW50QXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvYW1wbGl0dWRlL2FtcGxpdHVkZVRyYWNrRXZlbnRBdG9tXCI7XG5pbXBvcnQgeyBuZXdPcmdDb25maWdBdG9tIH0gZnJvbSBcInNyYy9hdG9tcy9vcmdcIjtcbmltcG9ydCB7IHJldHJpZXZlZFByb2R1Y3RzQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvc2VhcmNoL3Byb2R1Y3RSZXRyaWV2YWxBUElcIjtcbmltcG9ydCB7IHVzZVNlYXJjaElucHV0IH0gZnJvbSBcIi4vdXNlU2VhcmNoSW5wdXRcIjtcbmltcG9ydCB7IFNlYXJjaFJlc3BvbnNlUHJvZHVjdEF0dHJpYnV0ZXMgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVsc1wiO1xuaW1wb3J0IHsgdXNlTmV3T3JnQ29uZmlnIH0gZnJvbSBcIi4uL05ld09yZ0NvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlUmVjb21tZW5kZWRQcm9kdWN0cyB9IGZyb20gXCIuL3VzZVJlY29tbWVuZGVkUHJvZHVjdHNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSZXN1bHRzSG9jUHJvcHMge1xuICAvLyBEYXRhXG4gIHNlYXJjaERhdGE6IFNlYXJjaFJlc3VsdCB8IG51bGw7XG4gIHNlYXJjaFJlc3BvbnNlSWQ6IHN0cmluZztcbiAgbWVyY2hhbnRTaG9ydE5hbWU6IHN0cmluZztcbiAgcHJvZHVjdENhcmRDb25maWc6IFByb2R1Y3RDYXJkQ29uZmlnO1xuICBwcm9kdWN0TGlzdDogU2VhcmNoUmVzcG9uc2VQcm9kdWN0W107XG4gIGF1dG9jb21wbGV0ZVJlc3VsdHM6IHN0cmluZ1tdO1xuICBzZWFyY2hGaWx0ZXJzOiBTZWFyY2hGaWx0ZXJEYXR1bVtdO1xuICBhdmFpbGFibGVEeW5hbWljRmlsdGVyczogeyBuYW1lOiBzdHJpbmc7IGRpc3BsYXlOYW1lOiBzdHJpbmcgfVtdO1xuICBzZWxlY3RlZEZpbHRlck9wdGlvbnM6IFNlbGVjdGVkRmlsdGVyT3B0aW9uW107XG4gIHJlY29tbWVuZGVkUHJvZHVjdHM6IFNlYXJjaFJlc3BvbnNlUHJvZHVjdEF0dHJpYnV0ZXNbJ2F0dHJpYnV0ZXMnXVtdO1xuXG4gIC8vIFN0YXRlXG4gIHNlYXJjaFRleHQ6IHN0cmluZztcbiAgcXVlcnk6IHN0cmluZztcbiAgc2VhcmNoUmVzdWx0c1N0YXRlOiBTZWFyY2hSZXN1bHRzU3RhdGU7XG4gIGlzTG9hZGluZ1NlYXJjaDogYm9vbGVhbjtcbiAgaXNGaWx0ZXJPcGVuOiBib29sZWFuO1xuICBzaG91bGRTaG93QXV0b2NvbXBsZXRlOiBib29sZWFuO1xuICBmb2N1c2VkSW5kZXg6IG51bWJlcjtcbiAgZm9jdXNlZE9wdGlvbklkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgLy8gVUlcbiAgZmlsdGVyQnV0dG9uVGV4dDogc3RyaW5nO1xuXG4gIC8vIEV2ZW50IEhhbmRsZXJzXG4gIG9uU2VhcmNoSW5wdXRDaGFuZ2U6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICBvblN1Ym1pdFNlYXJjaDogKCkgPT4gdm9pZDtcbiAgb25BdXRvY29tcGxldGVTZWxlY3Q6IChzdWdnZXN0aW9uOiBzdHJpbmcpID0+IHZvaWQ7XG4gIG9uS2V5RG93bjogKGV2ZW50OiBSZWFjdC5LZXlib2FyZEV2ZW50PEhUTUxJbnB1dEVsZW1lbnQ+KSA9PiB2b2lkO1xuICBvblNlYXJjaElucHV0Rm9jdXM6ICgpID0+IHZvaWQ7XG4gIG9uU2VhcmNoSW5wdXRCbHVyOiAoKSA9PiB2b2lkO1xuICBvblRvZ2dsZUR5bmFtaWNGaWx0ZXI6ICh7IGZpbHRlciwgZHluYW1pY0ZpbHRlckRpc3BsYXlOYW1lIH06IHsgZmlsdGVyOiBzdHJpbmc7IGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZTogc3RyaW5nIH0pID0+IHZvaWQ7XG4gIG9uU2VsZWN0RmlsdGVySXRlbTogU2VsZWN0RmlsdGVySXRlbTtcbiAgb25SZW1vdmVGaWx0ZXI6IChmaWx0ZXI6IFNlbGVjdGVkRmlsdGVyT3B0aW9uKSA9PiB2b2lkO1xuICBvbkNsZWFyQWxsRmlsdGVyczogKCkgPT4gdm9pZDtcbiAgc2V0SXNGaWx0ZXJPcGVuOiAoaXNGaWx0ZXJPcGVuOiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIC8vIFJlZnNcbiAgc2VhcmNoUmVzdWx0c1JlZjogUmVhY3QuUmVmT2JqZWN0PEhUTUxEaXZFbGVtZW50Pjtcbn1cblxuZXhwb3J0IGNvbnN0IHVzZVNlYXJjaCA9ICgpOiBTZWFyY2hSZXN1bHRzSG9jUHJvcHMgPT4ge1xuICAvLyBBdG9tc1xuICBjb25zdCBjb25maWcgPSB1c2VOZXdPcmdDb25maWcoKTtcbiAgY29uc3Qgb3JnU2hvcnROYW1lID0gdXNlQXRvbVZhbHVlKG9yZ1Nob3J0TmFtZUF0b20pO1xuICBjb25zdCB7IGRhdGE6IHNlYXJjaERhdGEsIGxvYWRpbmc6IGlzTG9hZGluZ1NlYXJjaCB9ID1cbiAgICB1c2VBdG9tVmFsdWUoc2VhcmNoQXRvbSk7XG4gIGNvbnN0IHByb2R1Y3RMaXN0ID0gdXNlQXRvbVZhbHVlKGZpbHRlcmVkU2VhcmNoUHJvZHVjdHNBdG9tKTtcbiAgY29uc3QgcGVyZm9ybVNlYXJjaCA9IHVzZVNldEF0b20ocGVyZm9ybVNlYXJjaEF0b20pO1xuICBjb25zdCBbeyBxdWVyeSB9XSA9IHVzZUF0b20oc2VhcmNoUGFyYW1zQXRvbSk7XG4gIGNvbnN0IFtpc0ZpbHRlck9wZW4sIHNldElzRmlsdGVyT3Blbl0gPSB1c2VBdG9tKGlzRmlsdGVyT3BlbkF0b20pO1xuICBjb25zdCBbc2VsZWN0ZWRGaWx0ZXJPcHRpb25zXSA9IHVzZUF0b20oc2VhcmNoU2VsZWN0ZWRGaWx0ZXJzQXRvbSk7XG4gIGNvbnN0IGFkZEZpbHRlciA9IHVzZVNldEF0b20oYWRkU2VhcmNoRmlsdGVyQXRvbSk7XG4gIGNvbnN0IHJlbW92ZUZpbHRlciA9IHVzZVNldEF0b20ocmVtb3ZlU2VhcmNoRmlsdGVyQXRvbSk7XG4gIGNvbnN0IFtwcm9kdWN0U29ydGluZywgc2V0UHJvZHVjdFNvcnRpbmddID0gdXNlQXRvbShzZWFyY2hQcm9kdWN0U29ydGluZ0F0b20pO1xuICBjb25zdCBjbGVhckZpbHRlcnMgPSB1c2VTZXRBdG9tKGNsZWFyU2VhcmNoRmlsdGVyc0F0b20pO1xuICBjb25zdCBzZWFyY2hGaWx0ZXJzID0gdXNlQXRvbVZhbHVlKHNlYXJjaEZpbHRlcnNBdG9tKTtcbiAgY29uc3QgcmVjb21tZW5kZWRQcm9kdWN0cyA9IHVzZVJlY29tbWVuZGVkUHJvZHVjdHMoKTtcblxuICAvLyBSZWZzXG4gIGNvbnN0IHNlYXJjaFJlc3VsdHNSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KG51bGwpO1xuICBcbiAgLy8gVXRpbGl0aWVzXG4gIGNvbnN0IHNjcm9sbFRvVG9wID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IHNlYXJjaFJlc3VsdHNSZWYuY3VycmVudDtcbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAnc21vb3RoJyB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LnNjcm9sbFRvKHsgdG9wOiAwLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfVxuICB9LCBbXSk7XG4gIFxuICAvLyBTZWFyY2ggSW5wdXQgSG9va1xuICBjb25zdCBzZWFyY2hJbnB1dCA9IHVzZVNlYXJjaElucHV0KHtcbiAgICBpbml0aWFsU2VhcmNoVGV4dDogcXVlcnkgfHwgJycsXG4gICAgc2VhcmNoT3JpZ2luOiBTcGlmZnlXaWRnZXRzLlNlYXJjaFJlc3VsdHMsXG4gICAgb25TZWFyY2hTdWJtaXQ6IChzZWFyY2hRdWVyeSkgPT4ge1xuICAgICAgcGVyZm9ybVNlYXJjaCh7IHF1ZXJ5OiBzZWFyY2hRdWVyeSB9KTtcbiAgICB9LFxuICB9KTtcbiAgXG4gIGNvbnN0IHtcbiAgICBzZWFyY2hUZXh0LFxuICAgIGZvY3VzZWRJbmRleCxcbiAgICBmb2N1c2VkT3B0aW9uSWQsXG4gICAgYXV0b2NvbXBsZXRlUmVzdWx0cyxcbiAgICBzaG91bGRTaG93QXV0b2NvbXBsZXRlLFxuICAgIGhhbmRsZVNlYXJjaElucHV0Q2hhbmdlLFxuICAgIGhhbmRsZVNlYXJjaElucHV0Rm9jdXMsXG4gICAgaGFuZGxlU2VhcmNoSW5wdXRCbHVyLFxuICAgIGhhbmRsZUtleURvd24sXG4gICAgaGFuZGxlQXV0b2NvbXBsZXRlU2VsZWN0LFxuICAgIGhhbmRsZVN1Ym1pdFNlYXJjaCxcbiAgICBzZXRTZWFyY2hUZXh0LFxuICB9ID0gc2VhcmNoSW5wdXQ7XG4gIGNvbnN0IHNlYXJjaFJlc3VsdHNTdGF0ZSA9IGdldFNlYXJjaFJlc3VsdHNTdGF0ZShpc0xvYWRpbmdTZWFyY2gsIHNlYXJjaERhdGEpO1xuXG4gIGNvbnN0IGR5bmFtaWNGaWx0ZXJzID0gc2VhcmNoRGF0YT8uZmlsdGVycyB8fCBbXTtcblxuICAvLyBQcm92aWRlIGZhbGxiYWNrIHZhbHVlcyB3aGVuIG9yZ1VJQ29uZmlnIGlzIG5vdCB5ZXQgYXZhaWxhYmxlXG4gIGNvbnN0IHNhZmVQcm9kdWN0Q2FyZENvbmZpZyA9IGNvbmZpZz8uZnJvbnRlbmRDb25maWc/LnVpQ29uZmlnc1xuICAgID8ucHJvZHVjdENhcmRDb25maWcgfHwge1xuICAgIHZhcmlhbnQ6IFwibWluaW1hbFwiLFxuICAgIGhvdmVyVmFyaWFudDogXCJub25lXCIsXG4gICAgbGF5b3V0VmFyaWFudDogXCJzcXVhcmVcIixcbiAgfTtcbiAgY29uc3Qgc2FmZU1lcmNoYW50U2hvcnROYW1lID0gb3JnU2hvcnROYW1lIHx8IFwiXCI7XG5cbiAgY29uc3QgYXZhaWxhYmxlRHluYW1pY0ZpbHRlcnMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICByZXR1cm4gZHluYW1pY0ZpbHRlcnNcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChkeW5hbWljRmlsdGVyTmFtZSkgPT5cbiAgICAgICAgICAhc2VsZWN0ZWRGaWx0ZXJPcHRpb25zLnNvbWUoKG9wdGlvbikgPT4gb3B0aW9uLmlkID09PSBgZHluYW1pYzoke2R5bmFtaWNGaWx0ZXJOYW1lfWApLFxuICAgICAgKVxuICAgICAgLm1hcCgoZHluYW1pY0ZpbHRlck5hbWUpID0+ICh7XG4gICAgICAgIG5hbWU6IGR5bmFtaWNGaWx0ZXJOYW1lLFxuICAgICAgICBkaXNwbGF5TmFtZTogZm9ybWF0RmlsdGVyRGlzcGxheU5hbWUoZHluYW1pY0ZpbHRlck5hbWUpLFxuICAgICAgfSkpO1xuICB9LCBbZHluYW1pY0ZpbHRlcnMsIHNlbGVjdGVkRmlsdGVyT3B0aW9uc10pO1xuXG4gIGNvbnN0IGZpbHRlcnMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBjb25zdCBzb3J0T3B0aW9ucyA9IFtcbiAgICAgIHtcbiAgICAgICAgZmlsdGVySXRlbUlkOiBTdHJpbmcoUHJvZHVjdFNvcnRpbmcuRkVBVFVSRUQpLFxuICAgICAgICBkaXNwbGF5TmFtZTogJ1JlbGV2YW5jZScsXG4gICAgICAgIHByb2R1Y3RDb3VudDogMCxcbiAgICAgICAgaXNTZWxlY3RlZDogcHJvZHVjdFNvcnRpbmcgPT09IFByb2R1Y3RTb3J0aW5nLkZFQVRVUkVELFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZmlsdGVySXRlbUlkOiBTdHJpbmcoUHJvZHVjdFNvcnRpbmcuUFJJQ0VfQVNDKSxcbiAgICAgICAgZGlzcGxheU5hbWU6ICdQcmljZTogTG93IHRvIEhpZ2gnLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5QUklDRV9BU0MsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5QUklDRV9ERVNDKSxcbiAgICAgICAgZGlzcGxheU5hbWU6ICdQcmljZTogSGlnaCB0byBMb3cnLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5QUklDRV9ERVNDLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIFt7IGZpbHRlcklkOiAnc29ydCcsIGRpc3BsYXlOYW1lOiAnU09SVCcsIGl0ZW1zOiBzb3J0T3B0aW9ucyB9LCAuLi5zZWFyY2hGaWx0ZXJzXSBhcyBTZWFyY2hGaWx0ZXJEYXR1bVtdO1xuICB9LCBbcHJvZHVjdFNvcnRpbmcsIHNlYXJjaEZpbHRlcnNdKTtcblxuICBjb25zdCBmaWx0ZXJCdXR0b25UZXh0ID0gdXNlTWVtbygoKSA9PiB7XG4gICAgY29uc3Qgc2VsZWN0ZWRDb3VudCA9IGZpbHRlcnMucmVkdWNlKChhY2M6IG51bWJlciwgZmlsdGVyKSA9PiB7XG4gICAgICBpZiAoZmlsdGVyLmZpbHRlcklkID09PSAnc29ydCcpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBmaWx0ZXIuaXRlbXMuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmlzU2VsZWN0ZWQpLmxlbmd0aDtcbiAgICB9LCAwKTtcbiAgICBpZiAoc2VsZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuICdGaWx0ZXIgJiBTb3J0JztcbiAgICB9XG4gICAgcmV0dXJuIGBGaWx0ZXIgJiBTb3J0ICgke3NlbGVjdGVkQ291bnR9KWA7XG4gIH0sIFtmaWx0ZXJzXSk7XG5cbiAgLy8gQ2FsbGJhY2tzXG4gIGNvbnN0IHsgdHJhY2tFdmVudCB9ID0gdXNlQW1wbGl0dWRlKCk7XG5cblxuICBjb25zdCBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKHsgZmlsdGVyLCBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUgfTogeyBmaWx0ZXI6IHN0cmluZzsgZHluYW1pY0ZpbHRlckRpc3BsYXlOYW1lOiBzdHJpbmcgfSkgPT4ge1xuICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hGaWx0ZXJDbGlja2VkLFxuICAgICAgICBldmVudFByb3BzOiB7XG4gICAgICAgICAgZmlsdGVyVHlwZTogJ0R5bmFtaWMnLFxuICAgICAgICAgIGZpbHRlclZhbHVlOiBmaWx0ZXIsXG4gICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhZGRGaWx0ZXIoY3JlYXRlRmlsdGVyT3B0aW9uKCdkeW5hbWljJywgZmlsdGVyLCBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUpKTtcbiAgICAgIHNjcm9sbFRvVG9wKCk7XG4gICAgfSxcbiAgICBbYWRkRmlsdGVyLCBzZWFyY2hUZXh0LCBzY3JvbGxUb1RvcF0sXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlUmVtb3ZlRmlsdGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKGZpbHRlcjogU2VsZWN0ZWRGaWx0ZXJPcHRpb24pID0+IHtcbiAgICAgIHJlbW92ZUZpbHRlcihmaWx0ZXIuaWQpO1xuICAgICAgc2Nyb2xsVG9Ub3AoKTtcbiAgICB9LFxuICAgIFtyZW1vdmVGaWx0ZXIsIHNjcm9sbFRvVG9wXSxcbiAgKTtcblxuXG4gIGNvbnN0IGhhbmRsZVNlbGVjdEZpbHRlckl0ZW06IFNlbGVjdEZpbHRlckl0ZW0gPSB1c2VDYWxsYmFjayhcbiAgICAoe1xuICAgICAgZmlsdGVySWQsXG4gICAgICBmaWx0ZXJJdGVtSWQsXG4gICAgICBpc1NlbGVjdGVkLFxuICAgICAgZGlzcGxheU5hbWUsXG4gICAgfToge1xuICAgICAgZmlsdGVySWQ6IHN0cmluZztcbiAgICAgIGZpbHRlckl0ZW1JZDogc3RyaW5nO1xuICAgICAgaXNTZWxlY3RlZDogYm9vbGVhbjtcbiAgICAgIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKGZpbHRlcklkID09PSAnc29ydCcpIHtcbiAgICAgICAgY29uc3QgbmV3U29ydCA9IGZpbHRlckl0ZW1JZCBhcyBQcm9kdWN0U29ydGluZztcbiAgICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaFNvcnRDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIHNvcnRUeXBlOiBuZXdTb3J0LFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBzZXRQcm9kdWN0U29ydGluZyhuZXdTb3J0KTtcbiAgICAgICAgc2Nyb2xsVG9Ub3AoKTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzU2VsZWN0ZWQpIHtcbiAgICAgICAgcmVtb3ZlRmlsdGVyKGAke2ZpbHRlcklkfToke2ZpbHRlckl0ZW1JZH1gKTtcbiAgICAgICAgc2Nyb2xsVG9Ub3AoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hGaWx0ZXJDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIGZpbHRlclR5cGU6ICdTdGF0aWMnLFxuICAgICAgICAgICAgZmlsdGVyQ2F0ZWdvcnk6IGZpbHRlcklkLFxuICAgICAgICAgICAgZmlsdGVyVmFsdWU6IGZpbHRlckl0ZW1JZCxcbiAgICAgICAgICAgIHF1ZXJ5VGV4dDogc2VhcmNoVGV4dCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYWRkRmlsdGVyKGNyZWF0ZUZpbHRlck9wdGlvbihmaWx0ZXJJZCwgZmlsdGVySXRlbUlkLCBkaXNwbGF5TmFtZSkpO1xuICAgICAgICBzY3JvbGxUb1RvcCgpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW2FkZEZpbHRlciwgcmVtb3ZlRmlsdGVyLCBzZXRQcm9kdWN0U29ydGluZywgc2VhcmNoVGV4dCwgc2Nyb2xsVG9Ub3BdLFxuICApO1xuXG5cbiAgY29uc3QgaGFuZGxlQ2xlYXJBbGxGaWx0ZXJzID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldFByb2R1Y3RTb3J0aW5nKFByb2R1Y3RTb3J0aW5nLkZFQVRVUkVEKTtcbiAgICBjbGVhckZpbHRlcnMoKTtcbiAgICBzY3JvbGxUb1RvcCgpO1xuICB9LCBbc2V0UHJvZHVjdFNvcnRpbmcsIGNsZWFyRmlsdGVycywgc2Nyb2xsVG9Ub3BdKTtcblxuICAvLyBTaWRlIEVmZmVjdHNcbiAgdXNlVHJhY2tDb21wb25lbnRWaXNpYmxlRXZlbnQoXG4gICAgU3BpZmZ5V2lkZ2V0cy5TZWFyY2hSZXN1bHRzLFxuICAgIHNlYXJjaFJlc3VsdHNSZWYsXG4gICAge30sXG4gICAgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hDb21wb25lbnRWaXNpYmxlLFxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHNlYXJjaFJlc3VsdHNTdGF0ZSA9PT0gU2VhcmNoUmVzdWx0c1N0YXRlLlJlc3VsdHMgfHwgc2VhcmNoUmVzdWx0c1N0YXRlID09PSBTZWFyY2hSZXN1bHRzU3RhdGUuTm9SZXN1bHRzKSB7XG4gICAgICB0cmFja0V2ZW50KHtcbiAgICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaFJlc3VsdHNWaWV3ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBxdWVyeVRleHQ6IHNlYXJjaFRleHQsXG4gICAgICAgICAgcmVzdWx0c0NvdW50OiBwcm9kdWN0TGlzdC5sZW5ndGgsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gIH0sIFtwcm9kdWN0TGlzdC5sZW5ndGgsIHNlYXJjaFJlc3VsdHNTdGF0ZV0pO1xuXG4gIC8vIFRoaXMgaXMgdGhlIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIHRoZSBzZWFyY2ggdGV4dCB0cmlnZ2VyaW5nIGEgc2VhcmNoXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5ICE9PSBzZWFyY2hUZXh0KSB7XG4gICAgICBjb25zdCBlc3EgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpLmdldCgnZXNxJyk7XG4gICAgICBzZXRTZWFyY2hUZXh0KHF1ZXJ5KTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogZXNxID8/IHF1ZXJ5IH0pO1xuICAgIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbcGVyZm9ybVNlYXJjaCwgcXVlcnksIHNldFNlYXJjaFRleHRdKTtcblxuICByZXR1cm4ge1xuICAgIHNlYXJjaERhdGEsXG4gICAgc2VhcmNoUmVzcG9uc2VJZDogc2VhcmNoRGF0YT8uc2VhcmNoUmVzcG9uc2VJZCA/PyAnJyxcbiAgICBtZXJjaGFudFNob3J0TmFtZTogc2FmZU1lcmNoYW50U2hvcnROYW1lLFxuICAgIHByb2R1Y3RDYXJkQ29uZmlnOiBzYWZlUHJvZHVjdENhcmRDb25maWcsXG4gICAgcHJvZHVjdExpc3QsXG4gICAgcmVjb21tZW5kZWRQcm9kdWN0cyxcbiAgICBhdXRvY29tcGxldGVSZXN1bHRzLFxuICAgIHNlYXJjaEZpbHRlcnM6IGZpbHRlcnMsXG4gICAgYXZhaWxhYmxlRHluYW1pY0ZpbHRlcnMsXG4gICAgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zLFxuICAgIHNlYXJjaFRleHQsXG4gICAgcXVlcnk6IHF1ZXJ5IHx8ICcnLFxuICAgIHNlYXJjaFJlc3VsdHNTdGF0ZSxcbiAgICBpc0xvYWRpbmdTZWFyY2gsXG4gICAgaXNGaWx0ZXJPcGVuLFxuICAgIHNob3VsZFNob3dBdXRvY29tcGxldGUsXG4gICAgZm9jdXNlZEluZGV4LFxuICAgIGZvY3VzZWRPcHRpb25JZCxcbiAgICBmaWx0ZXJCdXR0b25UZXh0LFxuICAgIG9uU2VhcmNoSW5wdXRDaGFuZ2U6IGhhbmRsZVNlYXJjaElucHV0Q2hhbmdlLFxuICAgIG9uU3VibWl0U2VhcmNoOiBoYW5kbGVTdWJtaXRTZWFyY2gsXG4gICAgb25BdXRvY29tcGxldGVTZWxlY3Q6IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICBvbktleURvd246IGhhbmRsZUtleURvd24sXG4gICAgb25TZWFyY2hJbnB1dEZvY3VzOiBoYW5kbGVTZWFyY2hJbnB1dEZvY3VzLFxuICAgIG9uU2VhcmNoSW5wdXRCbHVyOiBoYW5kbGVTZWFyY2hJbnB1dEJsdXIsXG4gICAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyLFxuICAgIG9uU2VsZWN0RmlsdGVySXRlbTogaGFuZGxlU2VsZWN0RmlsdGVySXRlbSxcbiAgICBvblJlbW92ZUZpbHRlcjogaGFuZGxlUmVtb3ZlRmlsdGVyLFxuICAgIG9uQ2xlYXJBbGxGaWx0ZXJzOiBoYW5kbGVDbGVhckFsbEZpbHRlcnMsXG4gICAgc2V0SXNGaWx0ZXJPcGVuLFxuICAgIHNlYXJjaFJlc3VsdHNSZWYsXG4gIH07XG59OyJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVNBLFNBQVMsUUFBUSxPQUFPO0FBQ3RCLFFBQU8sQ0FBQyxNQUFNLFVBQ1YsT0FBTyxNQUFNLEtBQUssbUJBQ2xCLE1BQU0sUUFBUSxNQUFNOztBQUkxQixNQUFNLFdBQVc7QUFDakIsU0FBUyxhQUFhLE9BQU87QUFFM0IsS0FBSSxPQUFPLFNBQVMsU0FDbEIsUUFBTztDQUVULElBQUksU0FBUyxRQUFRO0FBQ3JCLFFBQU8sVUFBVSxPQUFPLElBQUksU0FBUyxDQUFDLFdBQVcsT0FBTzs7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