@envive-ai/react-hooks 0.2.6-alpha.13 → 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.
- package/dist/{NewOrgConfig-DJm6_abA.cjs → NewOrgConfig-Bo1seKr6.cjs} +2 -2
- package/dist/{NewOrgConfig-BfbTlFg1.js → NewOrgConfig-yptI2imS.js} +2 -2
- package/dist/{SystemSettingsContext-BbTKNBvJ.js → SystemSettingsContext-BY1BFgAQ.js} +2 -2
- package/dist/{SystemSettingsContext-6ZHzQkCE.cjs → SystemSettingsContext-EDpRMMt2.cjs} +2 -2
- package/dist/{TrackComponentVisibleEvent-BJgNOypY.js → TrackComponentVisibleEvent-CXhKOwKQ.js} +3 -3
- package/dist/{TrackComponentVisibleEvent-BRC2FTp-.cjs → TrackComponentVisibleEvent-CgxCqrIt.cjs} +7 -7
- package/dist/amplitudeContext-C8tT74Mi.cjs +286 -0
- package/dist/{amplitudeContext-B73xamNe.d.cts → amplitudeContext-CCVyp5RU.d.cts} +1 -1
- package/dist/amplitudeContext-DCk6Va-j.js +264 -0
- package/dist/{amplitudeContext-CZUzMXHl.d.ts → amplitudeContext-DcRur97Z.d.ts} +1 -1
- package/dist/app-BbPSHefQ.cjs +156 -0
- package/dist/app-CflxT_xI.js +110 -0
- package/dist/application/models/graphql/index.cjs +3 -2
- package/dist/application/models/graphql/index.d.cts +2 -2
- package/dist/application/models/graphql/index.d.ts +2 -2
- package/dist/application/models/graphql/index.js +2 -2
- package/dist/application/models/guards/api/index.d.cts +2 -1
- package/dist/application/models/guards/api/index.d.ts +3 -2
- package/dist/application/models/guards/utils.d.cts +1 -1
- package/dist/application/models/guards/utils.d.ts +1 -1
- package/dist/application/models/index.cjs +3 -3
- package/dist/application/models/index.d.cts +11 -10
- package/dist/application/models/index.d.ts +12 -11
- package/dist/application/models/index.js +2 -2
- package/dist/application/models/utilityTypes/index.d.ts +1 -1
- package/dist/application/models/variantInfo/index.d.cts +1 -1
- package/dist/application/models/variantInfo/index.d.ts +1 -1
- package/dist/application/utils/index.cjs +8 -6
- package/dist/application/utils/index.d.cts +14 -13
- package/dist/application/utils/index.d.ts +17 -16
- package/dist/application/utils/index.js +8 -6
- package/dist/{atomStore-DNji91Im.cjs → atomStore-CmZbgQHc.cjs} +1 -1
- package/dist/{atomStore-DXTVqiKc.js → atomStore-DEcDhiLp.js} +1 -1
- package/dist/atoms/app/index.cjs +9 -14
- package/dist/atoms/app/index.d.cts +19 -18
- package/dist/atoms/app/index.d.ts +20 -19
- package/dist/atoms/app/index.js +4 -9
- package/dist/atoms/atomStore/index.cjs +1 -1
- package/dist/atoms/atomStore/index.js +1 -1
- package/dist/atoms/chat/index.cjs +9 -8
- package/dist/atoms/chat/index.d.cts +39 -38
- package/dist/atoms/chat/index.d.ts +40 -39
- package/dist/atoms/chat/index.js +9 -8
- package/dist/atoms/globalSearch/index.cjs +1 -2
- package/dist/atoms/globalSearch/index.d.cts +5 -5
- package/dist/atoms/globalSearch/index.d.ts +6 -6
- package/dist/atoms/globalSearch/index.js +1 -2
- package/dist/atoms/org/index.cjs +8 -7
- package/dist/atoms/org/index.d.cts +30 -29
- package/dist/atoms/org/index.d.ts +31 -30
- package/dist/atoms/org/index.js +4 -3
- package/dist/atoms/search/index.cjs +16 -15
- package/dist/atoms/search/index.d.cts +13 -12
- package/dist/atoms/search/index.d.ts +14 -13
- package/dist/atoms/search/index.js +16 -15
- package/dist/atoms/search/types.cjs +1 -1
- package/dist/atoms/search/types.d.cts +4 -2
- package/dist/atoms/search/types.d.ts +4 -2
- package/dist/atoms/search/types.js +1 -1
- package/dist/atoms/search/utils.cjs +1 -1
- package/dist/atoms/search/utils.d.ts +1 -1
- package/dist/atoms/search/utils.js +1 -1
- package/dist/{cdnContext-DOSIofl8.cjs → cdnContext-CaDyQ_5p.cjs} +1 -1
- package/dist/{cdnContext-CEGBVVBU.js → cdnContext-CtrIlAqX.js} +1 -1
- package/dist/{chat-DH70QqJp.js → chat-BjhQCyW_.js} +8 -7
- package/dist/{chat-CqPuT9_V.cjs → chat-BkPax29G.cjs} +16 -9
- package/dist/{chatElementDisplayLocation-DWmfNX_u.d.cts → chatElementDisplayLocation-B7vr33eG.d.cts} +1 -1
- package/dist/{chatElementDisplayLocation-CpgV2wR1.d.ts → chatElementDisplayLocation-D4XF0UfI.d.ts} +1 -1
- package/dist/{chatSearch-C7Y-hb-6.js → chatSearch-BsYlFvpv.js} +7 -7
- package/dist/{chatSearch-DLV4BUGA.cjs → chatSearch-C3N3iIxu.cjs} +7 -7
- package/dist/{chatState-CcFtSqJT.cjs → chatState-CJ52Ag_7.cjs} +5 -5
- package/dist/{chatState-DKnNHmwe.js → chatState-CXA1vF16.js} +3 -3
- package/dist/commerce-api-DA1QGGMK.cjs +319 -0
- package/dist/commerce-api-rgj30eEp.js +312 -0
- package/dist/config/index.d.cts +4 -4
- package/dist/config/index.d.ts +4 -4
- package/dist/config/locators/components/chat/index.d.cts +1 -1
- package/dist/config/locators/components/chat/index.d.ts +1 -1
- package/dist/config/locators/components/common/index.d.cts +1 -1
- package/dist/config/locators/components/common/index.d.ts +1 -1
- package/dist/config/locators/components/index.d.cts +1 -1
- package/dist/config/locators/components/index.d.ts +1 -1
- package/dist/config/locators/index.d.cts +4 -4
- package/dist/config/locators/index.d.ts +4 -4
- package/dist/contexts/amplitudeContext/index.cjs +10 -9
- package/dist/contexts/amplitudeContext/index.d.cts +1 -1
- package/dist/contexts/amplitudeContext/index.d.ts +1 -1
- package/dist/contexts/amplitudeContext/index.js +7 -6
- package/dist/contexts/cdnContext/index.cjs +1 -1
- package/dist/contexts/cdnContext/index.js +1 -1
- package/dist/contexts/chatContext/index.cjs +32 -27
- package/dist/contexts/chatContext/index.d.cts +2 -2
- package/dist/contexts/chatContext/index.d.ts +4 -4
- package/dist/contexts/chatContext/index.js +22 -17
- package/dist/contexts/enviveConfigContext/index.d.cts +3 -3
- package/dist/contexts/enviveConfigContext/index.d.ts +3 -3
- package/dist/contexts/enviveCssContext/index.cjs +7 -7
- package/dist/contexts/enviveCssContext/index.js +7 -7
- package/dist/contexts/featureFlagContext/index.cjs +1 -1
- package/dist/contexts/featureFlagContext/index.d.cts +3 -3
- package/dist/contexts/featureFlagContext/index.d.ts +3 -3
- package/dist/contexts/featureFlagContext/index.js +1 -1
- package/dist/contexts/featureFlagServiceContext/index.d.cts +4 -4
- package/dist/contexts/featureFlagServiceContext/index.d.ts +4 -4
- package/dist/contexts/graphqlContext/index.cjs +3 -3
- package/dist/contexts/graphqlContext/index.d.cts +13 -12
- package/dist/contexts/graphqlContext/index.d.ts +14 -13
- package/dist/contexts/graphqlContext/index.js +3 -3
- package/dist/contexts/newOrgConfigContext/index.cjs +6 -6
- package/dist/contexts/newOrgConfigContext/index.d.cts +14 -13
- package/dist/contexts/newOrgConfigContext/index.d.ts +15 -14
- package/dist/contexts/newOrgConfigContext/index.js +6 -6
- package/dist/contexts/searchContext/index.cjs +10 -13
- package/dist/contexts/searchContext/index.d.cts +1 -1
- package/dist/contexts/searchContext/index.d.ts +2 -2
- package/dist/contexts/searchContext/index.js +10 -13
- package/dist/contexts/sessionStorageContext/index.cjs +1 -1
- package/dist/contexts/sessionStorageContext/index.js +1 -1
- package/dist/contexts/shopifyUrlContext/index.cjs +1 -1
- package/dist/contexts/shopifyUrlContext/index.d.cts +3 -3
- package/dist/contexts/shopifyUrlContext/index.d.ts +3 -3
- package/dist/contexts/shopifyUrlContext/index.js +1 -1
- package/dist/contexts/systemSettingsContext/index.cjs +1 -1
- package/dist/contexts/systemSettingsContext/index.d.cts +14 -13
- package/dist/contexts/systemSettingsContext/index.d.ts +15 -14
- package/dist/contexts/systemSettingsContext/index.js +1 -1
- package/dist/contexts/types.d.cts +3 -3
- package/dist/contexts/types.d.ts +3 -3
- package/dist/contexts/userIdentityContext/index.cjs +14 -8
- package/dist/contexts/userIdentityContext/index.d.cts +1 -1
- package/dist/contexts/userIdentityContext/index.d.ts +1 -1
- package/dist/contexts/userIdentityContext/index.js +12 -6
- package/dist/{domObserver-Bqf3ooj8.cjs → domObserver-COKvTfZV.cjs} +1 -1
- package/dist/{domObserver-v9ODTyfT.js → domObserver-DEiUh0qg.js} +1 -1
- package/dist/{featureFlagServiceContext-V0J-69ty.d.ts → featureFlagServiceContext-CpxlOkI9.d.ts} +2 -2
- package/dist/{featureFlagServiceContext-Be_LUbFf.d.cts → featureFlagServiceContext-p5UBwPM3.d.cts} +2 -2
- package/dist/frontendConfig-Cawh5iqv.d.ts +859 -0
- package/dist/frontendConfig-iZipB5FG.d.cts +859 -0
- package/dist/{globalSearch-FBk2epe8.cjs → globalSearch-BOG3wmck.cjs} +1 -1
- package/dist/{globalSearch-Ccxq8hNF.js → globalSearch-BQEX-2Ml.js} +1 -1
- package/dist/graphql-CkxgqsXP.js +48 -0
- package/dist/graphql-i3dtpVTl.cjs +71 -0
- package/dist/graphqlConfig-BnfE0ql5.cjs +39 -0
- package/dist/graphqlConfig-CZGjJ8hP.js +14 -0
- package/dist/{graphqlContext-D67VEQg3.d.cts → graphqlContext-BeyKU1Dr.d.cts} +2 -2
- package/dist/{graphqlContext-BQA6gnpH.d.ts → graphqlContext-CXQl0hq2.d.ts} +3 -3
- package/dist/{graphqlContext-W0cZNBf1.cjs → graphqlContext-DP8T3-Kd.cjs} +4 -4
- package/dist/{graphqlContext-Ci5GRAdH.js → graphqlContext-czH0kIZg.js} +3 -3
- package/dist/hooks/AmplitudeOperations/index.cjs +8 -8
- package/dist/hooks/AmplitudeOperations/index.d.cts +1 -1
- package/dist/hooks/AmplitudeOperations/index.d.ts +1 -1
- package/dist/hooks/AmplitudeOperations/index.js +8 -8
- package/dist/hooks/AppDetails/index.cjs +7 -12
- package/dist/hooks/AppDetails/index.d.cts +12 -11
- package/dist/hooks/AppDetails/index.d.ts +13 -12
- package/dist/hooks/AppDetails/index.js +7 -12
- package/dist/hooks/CdnOperations/index.cjs +1 -1
- package/dist/hooks/CdnOperations/index.js +1 -1
- package/dist/hooks/ChatToggle/index.cjs +13 -12
- package/dist/hooks/ChatToggle/index.d.cts +1 -1
- package/dist/hooks/ChatToggle/index.d.ts +1 -1
- package/dist/hooks/ChatToggle/index.js +10 -9
- package/dist/hooks/ChatToggleAnalytics/index.cjs +9 -9
- package/dist/hooks/ChatToggleAnalytics/index.d.cts +1 -1
- package/dist/hooks/ChatToggleAnalytics/index.d.ts +1 -1
- package/dist/hooks/ChatToggleAnalytics/index.js +9 -9
- package/dist/hooks/Debounce/index.cjs +20 -2
- package/dist/hooks/Debounce/index.js +18 -2
- package/dist/hooks/ElementObserver/index.cjs +1 -1
- package/dist/hooks/ElementObserver/index.d.cts +1 -1
- package/dist/hooks/ElementObserver/index.d.ts +1 -1
- package/dist/hooks/ElementObserver/index.js +1 -1
- package/dist/hooks/GrabAndScroll/index.d.cts +2 -2
- package/dist/hooks/GrabAndScroll/index.d.ts +2 -2
- package/dist/hooks/GraphQLConfig/index.cjs +4 -4
- package/dist/hooks/GraphQLConfig/index.d.cts +13 -12
- package/dist/hooks/GraphQLConfig/index.d.ts +14 -13
- package/dist/hooks/GraphQLConfig/index.js +4 -4
- package/dist/hooks/IdentifyUser/index.cjs +14 -8
- package/dist/hooks/IdentifyUser/index.js +13 -7
- package/dist/hooks/ImageResolver/index.cjs +2 -2
- package/dist/hooks/ImageResolver/index.js +2 -2
- package/dist/hooks/Intersection/index.cjs +1 -1
- package/dist/hooks/Intersection/index.js +1 -1
- package/dist/hooks/MessageFilter/index.cjs +2 -2
- package/dist/hooks/MessageFilter/index.d.cts +12 -11
- package/dist/hooks/MessageFilter/index.d.ts +13 -12
- package/dist/hooks/MessageFilter/index.js +2 -2
- package/dist/hooks/NewOrgConfig/index.cjs +7 -7
- package/dist/hooks/NewOrgConfig/index.d.cts +14 -13
- package/dist/hooks/NewOrgConfig/index.d.ts +15 -14
- package/dist/hooks/NewOrgConfig/index.js +7 -7
- package/dist/hooks/Search/index.cjs +1469 -159
- package/dist/hooks/Search/index.d.cts +21 -17
- package/dist/hooks/Search/index.d.ts +22 -18
- package/dist/hooks/Search/index.js +1464 -154
- package/dist/hooks/SearchOperations/index.cjs +11 -14
- package/dist/hooks/SearchOperations/index.d.cts +1 -1
- package/dist/hooks/SearchOperations/index.d.ts +2 -2
- package/dist/hooks/SearchOperations/index.js +11 -14
- package/dist/hooks/SessionStorageOperations/index.cjs +1 -1
- package/dist/hooks/SessionStorageOperations/index.js +1 -1
- package/dist/hooks/ShopifyUrlOperations/index.cjs +1 -1
- package/dist/hooks/ShopifyUrlOperations/index.d.cts +5 -5
- package/dist/hooks/ShopifyUrlOperations/index.d.ts +5 -5
- package/dist/hooks/ShopifyUrlOperations/index.js +1 -1
- package/dist/hooks/SystemSettingsContext/index.cjs +2 -2
- package/dist/hooks/SystemSettingsContext/index.d.cts +14 -13
- package/dist/hooks/SystemSettingsContext/index.d.ts +15 -14
- package/dist/hooks/SystemSettingsContext/index.js +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/index.cjs +8 -8
- package/dist/hooks/TrackComponentVisibleEvent/index.d.cts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/index.d.ts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/index.js +8 -8
- package/dist/hooks/UpdateAnalyticsProps/index.cjs +11 -11
- package/dist/hooks/UpdateAnalyticsProps/index.js +6 -6
- package/dist/hooks/utils.d.cts +12 -11
- package/dist/hooks/utils.d.ts +13 -12
- package/dist/{index-BeYfyZ6k.d.ts → index--9_c4tze.d.ts} +1 -1
- package/dist/index-BEpDGqnz.d.cts +41 -0
- package/dist/{index-xHVrsrbz.d.ts → index-BKvFVPUX.d.ts} +1 -1
- package/dist/{index-DJTrxIFJ.d.ts → index-BNHIIgYk.d.ts} +1 -1
- package/dist/{index-BeGt0Aw3.d.cts → index-BSd8767K.d.cts} +5 -5
- package/dist/index-BUDrAxnl.d.ts +673 -0
- package/dist/{index-DzbkQtaK.d.cts → index-CCboEuTO.d.cts} +1 -1
- package/dist/{index-FQjyuD3D.d.cts → index-COXkY78t.d.cts} +1 -1
- package/dist/{index-xhBQ1HBx.d.ts → index-CUO68KG3.d.ts} +34 -34
- package/dist/{index-DazMsEy_.d.ts → index-D7htGSQC.d.ts} +1 -1
- package/dist/index-DM_5fh8c.d.ts +101 -0
- package/dist/index-DU7uw0ba.d.cts +101 -0
- package/dist/{index-Da1s8h5C.d.cts → index-DZtnHhlr.d.cts} +1 -1
- package/dist/{index-h809JLbL.d.ts → index-Dtw-hJdt.d.ts} +1 -1
- package/dist/{index-Dfwnna1j.d.ts → index-Dxpscrvz.d.ts} +1 -1
- package/dist/index-Dy3TTIOm.d.cts +673 -0
- package/dist/index-ErVcwUnR.d.ts +41 -0
- package/dist/{index-Cyq5HiC0.d.cts → index-OkKEOL6H.d.cts} +1 -1
- package/dist/{index-9NE86em3.d.cts → index-hAqp0oYb.d.cts} +1 -1
- package/dist/interceptors/index.d.cts +13 -12
- package/dist/interceptors/index.d.ts +14 -13
- package/dist/interceptors/types.d.cts +12 -11
- package/dist/interceptors/types.d.ts +13 -12
- package/dist/models-CWOgrLCm.js +1284 -0
- package/dist/models-DqdLOi2I.cjs +1519 -0
- package/dist/{newOrgConfigAtom-DxILMn2I.cjs → newOrgConfigAtom-CPA6Gp6n.cjs} +1 -1
- package/dist/{newOrgConfigAtom-sqve6LZU.js → newOrgConfigAtom-DEUj6H-p.js} +1 -1
- package/dist/{newOrgConfigContext-Cl4H9c3q.cjs → newOrgConfigContext-Bet9CgKP.cjs} +3 -3
- package/dist/{newOrgConfigContext-DQiuf8nd.js → newOrgConfigContext-Bi_dBNe5.js} +3 -3
- package/dist/{newOrgConfigContext-5Bw7RwT-.d.cts → newOrgConfigContext-CJI3tsVV.d.cts} +2 -2
- package/dist/{newOrgConfigContext-CS8IA5Eg.d.ts → newOrgConfigContext-I2qceBB4.d.ts} +2 -2
- package/dist/{nodeSelector-BiCDowlK.d.ts → nodeSelector-B5NfnUHv.d.ts} +1 -1
- package/dist/{nodeSelector-B3bPtEjX.d.cts → nodeSelector-vKB44CDB.d.cts} +1 -1
- package/dist/{org-DlAesvQ_.cjs → org-B_cWn2bt.cjs} +1 -1
- package/dist/{org-vi0njpBh.js → org-h32_LSEb.js} +1 -1
- package/dist/orgAnalyticsConfig-Bm23fw4s.cjs +39 -0
- package/dist/orgAnalyticsConfig-CpBmga08.js +14 -0
- package/dist/responseGenerics-D9bS-Dd6.d.ts +148 -0
- package/dist/{index-CCa4tZuO.d.ts → responseGenerics-DWLV09cQ.d.cts} +4 -40
- package/dist/{search-y-ioX5Mz.d.cts → search-6RrxBXD6.d.cts} +1 -1
- package/dist/{search-CXXslzAO.cjs → search-Csh2n66W.cjs} +5 -5
- package/dist/{search-DBSMrXWv.js → search-DkiqkogN.js} +5 -5
- package/dist/{search-1NQLQD9d.d.ts → search-DrJiCT7d.d.ts} +2 -2
- package/dist/{search-filter-types-BxaNSLs_.d.cts → search-filter-types-BItKtezf.d.cts} +1 -1
- package/dist/{search-filter-types-DPgeG8FS.d.ts → search-filter-types-CGFhksO3.d.ts} +1 -1
- package/dist/{searchContext-mvwUJncR.js → searchContext-BmgoAFMF.js} +4 -4
- package/dist/{searchContext-DXW6xvXv.cjs → searchContext-DksJfC1s.cjs} +6 -6
- package/dist/{searchServiceAdapter-DEv1tTn0.cjs → searchServiceAdapter-BGlvoZFE.cjs} +1 -1
- package/dist/{searchServiceAdapter-WyCU55NV.js → searchServiceAdapter-Db6jEcJs.js} +1 -1
- package/dist/{sessionStorageContext-1Ks_d4Z0.cjs → sessionStorageContext-B6FsNKjj.cjs} +1 -1
- package/dist/{sessionStorageContext-CDcl7NVl.js → sessionStorageContext-CLYCm83p.js} +1 -1
- package/dist/{shopifyUrlContext-CejRZfj7.js → shopifyUrlContext-C-PkSgNC.js} +1 -1
- package/dist/{shopifyUrlContext-lnHoAOEf.cjs → shopifyUrlContext-ZOcARiMR.cjs} +1 -1
- package/dist/{spiffyWidgets-B1uc84_g.d.ts → spiffyWidgets-CR6F7FRE.d.ts} +1 -1
- package/dist/{spiffyWidgets-BuS00VaQ.d.cts → spiffyWidgets-eNbU1gMc.d.cts} +1 -1
- package/dist/{systemSettingsContext-CVUxEcsU.js → systemSettingsContext-DF0jSq9m.js} +1 -1
- package/dist/{systemSettingsContext-B0Kyq7nA.cjs → systemSettingsContext-dmE1v6w8.cjs} +1 -1
- package/dist/{test-types-y6kp-tiw.d.ts → test-types-BEml_bm3.d.ts} +1 -1
- package/dist/{test-types-ThQiO_cc.d.cts → test-types-Dsu8RJZu.d.cts} +1 -1
- package/dist/types/index.cjs +1 -16
- package/dist/types/index.d.cts +3 -17
- package/dist/types/index.d.ts +3 -17
- package/dist/types/index.js +2 -16
- package/dist/{types-Db5Eux6K.d.ts → types-4LQ7LUCk.d.ts} +2 -2
- package/dist/types-BegmH0S1.d.ts +60 -0
- package/dist/types-BuvXXGxE.cjs +48 -0
- package/dist/types-CtUb63bt.js +1 -1
- package/dist/{types-zQGBI-Yo.d.cts → types-DFsSqmWx.d.cts} +2 -2
- package/dist/types-DWorwfS-.d.cts +60 -0
- package/dist/types-DXnG1tV0.js +30 -0
- package/dist/types-UUvB6h05.cjs +1 -1
- package/dist/types.d.cts +4 -23
- package/dist/types.d.ts +4 -23
- package/dist/unsupportedProductExceptions-DGENUnEA.cjs +32 -0
- package/dist/unsupportedProductExceptions-uQuuelOs.js +20 -0
- package/dist/{useAmplitudeOperations-jqa7K9dH.cjs → useAmplitudeOperations-Bo6YNbTV.cjs} +3 -3
- package/dist/{useAmplitudeOperations-DYs1h8a_.js → useAmplitudeOperations-zIRSqmMW.js} +2 -2
- package/dist/{useAppDetails-BRUqZEyt.js → useAppDetails-B584gkCs.js} +3 -3
- package/dist/{useAppDetails-C71k0brz.cjs → useAppDetails-DczgqeLG.cjs} +6 -6
- package/dist/{useGraphQLConfig-5VwS9Q_Z.js → useGraphQLConfig-7UxACM4n.js} +2 -2
- package/dist/{useGraphQLConfig-Cj26_J9I.cjs → useGraphQLConfig-D_rF2Sun.cjs} +2 -2
- package/dist/{useIntersection-Cncgxdmy.js → useIntersection-CZSEBUbv.js} +1 -1
- package/dist/{useIntersection-m4PEpvG7.cjs → useIntersection-DSDREfj6.cjs} +1 -1
- package/dist/userIdentityContext-BqbNu7xu.cjs +132 -0
- package/dist/userIdentityContext-BxFH9FNQ.js +115 -0
- package/dist/{userIdentityContext-BVODeTlN.d.ts → userIdentityContext-C6kApbuk.d.ts} +1 -1
- package/dist/{userIdentityContext-D2oFVFzo.d.cts → userIdentityContext-kU1PIo8K.d.cts} +1 -1
- package/dist/{utils-DpneNSJf.d.ts → utils-BRkGP1eb.d.ts} +1 -1
- package/dist/utils-C1ErYSoW.js +606 -0
- package/dist/{utils-BxPPugeP.d.cts → utils-CBD4g2Nc.d.cts} +4 -4
- package/dist/{utils-2SWrJ12w.cjs → utils-CvLmSsUj.cjs} +1 -1
- package/dist/{utils-CqBxIpEV.js → utils-D82gfbgU.js} +1 -1
- package/dist/{utils-B3x_9JTY.d.cts → utils-DCrwX6FT.d.cts} +1 -1
- package/dist/{utils-Covisryh.d.ts → utils-QKFAbPT6.d.ts} +4 -4
- package/dist/utils-mqfncrhI.cjs +715 -0
- package/package.json +18 -13
- package/src/application/commerce-api.ts +2 -0
- package/src/application/models/graphql/index.ts +1 -0
- package/src/application/utils/__tests__/divideArrays.test.ts +12 -13
- package/src/atoms/app/index.ts +1 -2
- package/src/atoms/search/productRetrievalAPI.ts +70 -0
- package/src/atoms/search/productRetrievalAdapter.ts +25 -0
- package/src/atoms/search/types.ts +13 -0
- package/src/contexts/enviveConfigContext/__tests__/enviveConfigContext.test.tsx +411 -0
- package/src/contexts/graphqlContext/__tests__/graphqlContext.test.tsx +790 -0
- package/src/contexts/localStorageContext/__tests__/localStorageContext.test.tsx +775 -0
- package/src/contexts/newOrgConfigContext/__tests__/newOrgConfigContext.test.tsx +495 -0
- package/src/contexts/searchContext/__tests__/searchContext.test.tsx +806 -0
- package/src/contexts/systemSettingsContext/__tests__/systemSettingsContext.test.tsx +506 -0
- package/src/contexts/types.ts +16 -14
- package/src/contexts/userIdentityContext/__tests__/userIdentityContext.test.tsx +663 -0
- package/src/contexts/userIdentityContext/userIdentityContext.tsx +6 -0
- package/src/hooks/Search/useRecommendedProducts.ts +48 -0
- package/src/hooks/Search/useSearch.tsx +89 -182
- package/src/hooks/Search/useSearchInput.ts +263 -0
- package/src/types/FilterAttribute.ts +35 -0
- package/src/types/index.ts +0 -1
- package/src/types.ts +0 -16
- package/dist/frontendConfig-CeWhVevA.d.ts +0 -857
- package/dist/frontendConfig-OWWJmuPc.d.cts +0 -857
- package/dist/graphql-3PxNRFOc.js +0 -36
- package/dist/graphql-DGYfelZp.cjs +0 -53
- package/dist/graphqlConfig-GHZ1UgCw.cjs +0 -73
- package/dist/graphqlConfig-mDg6J44N.js +0 -24
- package/dist/hooks/FloatingButtonVisibility/index.cjs +0 -73
- package/dist/hooks/FloatingButtonVisibility/index.d.cts +0 -7
- package/dist/hooks/FloatingButtonVisibility/index.d.ts +0 -7
- package/dist/hooks/FloatingButtonVisibility/index.js +0 -69
- package/dist/hooks/LastInteraction/index.cjs +0 -34
- package/dist/hooks/LastInteraction/index.d.cts +0 -17
- package/dist/hooks/LastInteraction/index.d.ts +0 -17
- package/dist/hooks/LastInteraction/index.js +0 -32
- package/dist/index-Bmub8e38.d.cts +0 -98
- package/dist/index-CiWEYzXl.d.cts +0 -184
- package/dist/index-D4c-port.d.ts +0 -676
- package/dist/index-O33GSSRr.d.cts +0 -676
- package/dist/index-bjMvkcBF.d.ts +0 -98
- package/dist/models-D-4db7XW.cjs +0 -1537
- package/dist/models-c86hYW-F.js +0 -1296
- package/dist/types-BCz-hOvv.d.ts +0 -51
- package/dist/types-CKMMb_gX.d.cts +0 -51
- package/dist/types-CS0Hrzja.js +0 -30
- package/dist/types-CxObxLKs.cjs +0 -48
- package/dist/useDebounce-DZ8Cgiwc.cjs +0 -26
- package/dist/useDebounce-v9cezyjn.js +0 -19
- package/dist/utils-CLGXsOwE.cjs +0 -1591
- package/dist/utils-jYtD3hmA.js +0 -1385
- package/src/hooks/FloatingButtonVisibility/index.ts +0 -1
- package/src/hooks/FloatingButtonVisibility/useFloatingButtonVisibility.ts +0 -99
- package/src/hooks/LastInteraction/index.ts +0 -1
- package/src/hooks/LastInteraction/useLastInteraction.ts +0 -42
- package/src/types/floatingbuttonoverrides-types.ts +0 -10
- /package/dist/{AmplitudeOperations-ni7wVevx.js → AmplitudeOperations-ChZWcSsc.js} +0 -0
- /package/dist/{AmplitudeOperations-DxQnurSG.cjs → AmplitudeOperations-JggIc1zD.cjs} +0 -0
- /package/dist/{globalSearch-BpGfkuXz.js → amplitudeContext-BItT9HmT.js} +0 -0
- /package/dist/{globalSearch-B9DRBxSM.cjs → amplitudeContext-DPtyVv3Q.cjs} +0 -0
- /package/dist/{index-CgAfoNpB.d.ts → index-A0HvA68Y.d.cts} +0 -0
- /package/dist/{index-RcVcRKH7.d.cts → index-DNVvRcKu.d.ts} +0 -0
|
@@ -1,43 +1,1428 @@
|
|
|
1
1
|
import "../../types-CtUb63bt.js";
|
|
2
2
|
import "../../events-DyUix-Bn.js";
|
|
3
|
-
import { getSearchResultsState } from "../../utils-D_kATUj6.js";
|
|
4
|
-
import { SpiffyWidgets } from "../../models-
|
|
5
|
-
import "../../featureGates-KEwAL8p_.js";
|
|
3
|
+
import { SearchResultsState, getSearchResultsState } from "../../utils-D_kATUj6.js";
|
|
4
|
+
import { SpiffyWidgets } from "../../models-CWOgrLCm.js";
|
|
5
|
+
import { FeatureGates } from "../../featureGates-KEwAL8p_.js";
|
|
6
6
|
import "../../urlsParser-DxjoLj98.js";
|
|
7
|
-
import "../../graphql-
|
|
7
|
+
import "../../graphql-CkxgqsXP.js";
|
|
8
8
|
import "../../utils-DIvMgPe8.js";
|
|
9
9
|
import "../../api-BWSsazAG.js";
|
|
10
|
-
import
|
|
10
|
+
import "../../logger-W3lqg-4b.js";
|
|
11
11
|
import "../../utilityTypes-B2KuRn37.js";
|
|
12
12
|
import "../../variantInfo-BfKlkaWU.js";
|
|
13
13
|
import "../../localStorageContext-BPZ82q-G.js";
|
|
14
14
|
import { orgShortNameAtom } from "../../enviveConfig-DZBohDpc.js";
|
|
15
|
-
import "../../
|
|
16
|
-
import
|
|
17
|
-
import "../../
|
|
15
|
+
import "../../orgAnalyticsConfig-CpBmga08.js";
|
|
16
|
+
import "../../atomStore-DEcDhiLp.js";
|
|
17
|
+
import "../../app-CflxT_xI.js";
|
|
18
18
|
import "../../enviveConfigContext-DrDjCems.js";
|
|
19
|
-
import "../../featureFlagServiceContext-FBM6DdMJ.js";
|
|
20
|
-
import "../../
|
|
21
|
-
import "../../chatState-
|
|
22
|
-
import "../../
|
|
23
|
-
import {
|
|
24
|
-
import "../../
|
|
25
|
-
import "../../
|
|
26
|
-
import
|
|
27
|
-
import "../../
|
|
28
|
-
import
|
|
29
|
-
import "../../
|
|
30
|
-
import
|
|
31
|
-
import "../../
|
|
32
|
-
import "../../
|
|
33
|
-
import "../../
|
|
34
|
-
import
|
|
35
|
-
import
|
|
36
|
-
import "../../
|
|
37
|
-
import
|
|
19
|
+
import { useFeatureFlagService } from "../../featureFlagServiceContext-FBM6DdMJ.js";
|
|
20
|
+
import { SpiffyMetricsEventName, useAmplitude } from "../../amplitudeContext-DCk6Va-j.js";
|
|
21
|
+
import "../../chatState-CXA1vF16.js";
|
|
22
|
+
import "../../graphqlConfig-CZGjJ8hP.js";
|
|
23
|
+
import { amplitudeTrackEventAtom } from "../../chat-BjhQCyW_.js";
|
|
24
|
+
import { autocompleteStateAtom, isFilterOpenAtom } from "../../globalSearch-BQEX-2Ml.js";
|
|
25
|
+
import "../../org-h32_LSEb.js";
|
|
26
|
+
import "../../newOrgConfigAtom-DEUj6H-p.js";
|
|
27
|
+
import { formatFilterDisplayName } from "../../utils-D82gfbgU.js";
|
|
28
|
+
import "../../chatSearch-BsYlFvpv.js";
|
|
29
|
+
import { ProductSorting } from "../../types-DXnG1tV0.js";
|
|
30
|
+
import "../../searchServiceAdapter-Db6jEcJs.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
|
+
import "../../useIntersection-CZSEBUbv.js";
|
|
38
|
+
import { useTrackComponentVisibleEvent } from "../../TrackComponentVisibleEvent-CXhKOwKQ.js";
|
|
38
39
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
39
|
-
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
40
|
+
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
40
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
|
|
41
1426
|
//#region src/hooks/Search/useSearch.tsx
|
|
42
1427
|
const useSearch = () => {
|
|
43
1428
|
const config = useNewOrgConfig();
|
|
@@ -45,7 +1430,6 @@ const useSearch = () => {
|
|
|
45
1430
|
const { data: searchData, loading: isLoadingSearch } = useAtomValue(searchAtom);
|
|
46
1431
|
const productList = useAtomValue(filteredSearchProductsAtom);
|
|
47
1432
|
const performSearch = useSetAtom(performSearchAtom);
|
|
48
|
-
const [{ results: autocompleteResults, isLoading: isLoadingAutocomplete }, setAutocompleteState] = useAtom(autocompleteStateAtom);
|
|
49
1433
|
const [{ query }] = useAtom(searchParamsAtom);
|
|
50
1434
|
const [isFilterOpen, setIsFilterOpen] = useAtom(isFilterOpenAtom);
|
|
51
1435
|
const [selectedFilterOptions] = useAtom(searchSelectedFiltersAtom);
|
|
@@ -54,12 +1438,26 @@ const useSearch = () => {
|
|
|
54
1438
|
const [productSorting, setProductSorting] = useAtom(searchProductSortingAtom);
|
|
55
1439
|
const clearFilters = useSetAtom(clearSearchFiltersAtom);
|
|
56
1440
|
const searchFilters = useAtomValue(searchFiltersAtom);
|
|
57
|
-
const
|
|
58
|
-
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
59
|
-
const [focusedOptionId, setFocusedOptionId] = useState(void 0);
|
|
60
|
-
const [searchText, setSearchText] = useState(query || "");
|
|
1441
|
+
const recommendedProducts = useRecommendedProducts();
|
|
61
1442
|
const searchResultsRef = useRef(null);
|
|
62
|
-
const
|
|
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
|
+
});
|
|
63
1461
|
const searchResultsState = getSearchResultsState(isLoadingSearch, searchData);
|
|
64
1462
|
const dynamicFilters = searchData?.filters || [];
|
|
65
1463
|
const safeProductCardConfig = config?.frontendConfig?.uiConfigs?.productCardConfig || {
|
|
@@ -119,76 +1517,16 @@ const useSearch = () => {
|
|
|
119
1517
|
}
|
|
120
1518
|
});
|
|
121
1519
|
addFilter(createFilterOption("dynamic", filter, dynamicFilterDisplayName));
|
|
1520
|
+
scrollToTop();
|
|
122
1521
|
}, [
|
|
123
1522
|
addFilter,
|
|
124
1523
|
searchText,
|
|
125
|
-
|
|
1524
|
+
scrollToTop
|
|
126
1525
|
]);
|
|
127
1526
|
const handleRemoveFilter = useCallback((filter) => {
|
|
128
1527
|
removeFilter(filter.id);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (searchText.trim()) {
|
|
132
|
-
trackEvent({
|
|
133
|
-
eventName: SpiffyMetricsEventName.SearchQuerySubmitted,
|
|
134
|
-
eventProps: {
|
|
135
|
-
searchOrigin: SpiffyWidgets.SearchResults,
|
|
136
|
-
queryText: searchText.trim()
|
|
137
|
-
},
|
|
138
|
-
alsoSendToGoogleAnalytics: true
|
|
139
|
-
});
|
|
140
|
-
const url = new URL(window.location.href);
|
|
141
|
-
url.searchParams.set("esq", searchText.trim());
|
|
142
|
-
window.history.pushState({}, "", url);
|
|
143
|
-
performSearch({ query: searchText.trim() });
|
|
144
|
-
}
|
|
145
|
-
}, [
|
|
146
|
-
performSearch,
|
|
147
|
-
searchText,
|
|
148
|
-
trackEvent
|
|
149
|
-
]);
|
|
150
|
-
const handleAutocompleteSelect = useCallback((suggestion) => {
|
|
151
|
-
setSearchText(suggestion);
|
|
152
|
-
handleSubmitSearch();
|
|
153
|
-
}, [handleSubmitSearch, setSearchText]);
|
|
154
|
-
const handleKeyDown = useCallback((event) => {
|
|
155
|
-
if (event.key === "ArrowDown") {
|
|
156
|
-
event.preventDefault();
|
|
157
|
-
const newIndex = (focusedIndex + 1) % autocompleteResults.length;
|
|
158
|
-
setFocusedIndex(newIndex);
|
|
159
|
-
setFocusedOptionId(`option-${newIndex}`);
|
|
160
|
-
} else if (event.key === "ArrowUp") {
|
|
161
|
-
event.preventDefault();
|
|
162
|
-
const newIndex = (focusedIndex - 1 + autocompleteResults.length) % autocompleteResults.length;
|
|
163
|
-
setFocusedIndex(newIndex);
|
|
164
|
-
setFocusedOptionId(`option-${newIndex}`);
|
|
165
|
-
} else if (event.key === "Enter") if (focusedIndex === -1) {
|
|
166
|
-
event.preventDefault();
|
|
167
|
-
handleSubmitSearch();
|
|
168
|
-
} else {
|
|
169
|
-
event.preventDefault();
|
|
170
|
-
const suggestionText = autocompleteResults[focusedIndex];
|
|
171
|
-
handleAutocompleteSelect(suggestionText);
|
|
172
|
-
}
|
|
173
|
-
else if (event.key === "Escape") {
|
|
174
|
-
event.preventDefault();
|
|
175
|
-
setFocusedIndex(-1);
|
|
176
|
-
setFocusedOptionId(void 0);
|
|
177
|
-
}
|
|
178
|
-
}, [
|
|
179
|
-
autocompleteResults,
|
|
180
|
-
focusedIndex,
|
|
181
|
-
handleAutocompleteSelect,
|
|
182
|
-
handleSubmitSearch
|
|
183
|
-
]);
|
|
184
|
-
const handleSearchInputChange = (newValue) => {
|
|
185
|
-
if (newValue.length === 1) trackEvent({
|
|
186
|
-
eventName: SpiffyMetricsEventName.SearchInputStarted,
|
|
187
|
-
eventProps: { searchOrigin: SpiffyWidgets.SearchResults }
|
|
188
|
-
});
|
|
189
|
-
setSearchText(newValue);
|
|
190
|
-
setIsDirty(true);
|
|
191
|
-
};
|
|
1528
|
+
scrollToTop();
|
|
1529
|
+
}, [removeFilter, scrollToTop]);
|
|
192
1530
|
const handleSelectFilterItem = useCallback(({ filterId, filterItemId, isSelected, displayName }) => {
|
|
193
1531
|
if (filterId === "sort") {
|
|
194
1532
|
const newSort = filterItemId;
|
|
@@ -200,8 +1538,11 @@ const useSearch = () => {
|
|
|
200
1538
|
}
|
|
201
1539
|
});
|
|
202
1540
|
setProductSorting(newSort);
|
|
203
|
-
|
|
204
|
-
else {
|
|
1541
|
+
scrollToTop();
|
|
1542
|
+
} else if (!isSelected) {
|
|
1543
|
+
removeFilter(`${filterId}:${filterItemId}`);
|
|
1544
|
+
scrollToTop();
|
|
1545
|
+
} else {
|
|
205
1546
|
trackEvent({
|
|
206
1547
|
eventName: SpiffyMetricsEventName.SearchFilterClicked,
|
|
207
1548
|
eventProps: {
|
|
@@ -212,78 +1553,44 @@ const useSearch = () => {
|
|
|
212
1553
|
}
|
|
213
1554
|
});
|
|
214
1555
|
addFilter(createFilterOption(filterId, filterItemId, displayName));
|
|
1556
|
+
scrollToTop();
|
|
215
1557
|
}
|
|
216
1558
|
}, [
|
|
217
1559
|
addFilter,
|
|
218
1560
|
removeFilter,
|
|
219
1561
|
setProductSorting,
|
|
220
1562
|
searchText,
|
|
221
|
-
|
|
1563
|
+
scrollToTop
|
|
222
1564
|
]);
|
|
223
1565
|
const handleClearAllFilters = useCallback(() => {
|
|
224
1566
|
setProductSorting(ProductSorting.FEATURED);
|
|
225
1567
|
clearFilters();
|
|
226
|
-
|
|
1568
|
+
scrollToTop();
|
|
1569
|
+
}, [
|
|
1570
|
+
setProductSorting,
|
|
1571
|
+
clearFilters,
|
|
1572
|
+
scrollToTop
|
|
1573
|
+
]);
|
|
227
1574
|
useTrackComponentVisibleEvent(SpiffyWidgets.SearchResults, searchResultsRef, {}, SpiffyMetricsEventName.SearchComponentVisible);
|
|
228
1575
|
useEffect(() => {
|
|
229
|
-
if (
|
|
1576
|
+
if (searchResultsState === SearchResultsState.Results || searchResultsState === SearchResultsState.NoResults) trackEvent({
|
|
230
1577
|
eventName: SpiffyMetricsEventName.SearchResultsViewed,
|
|
231
1578
|
eventProps: {
|
|
232
1579
|
queryText: searchText,
|
|
233
1580
|
resultsCount: productList.length
|
|
234
1581
|
}
|
|
235
1582
|
});
|
|
236
|
-
}, [
|
|
237
|
-
productList.length,
|
|
238
|
-
searchText,
|
|
239
|
-
trackEvent
|
|
240
|
-
]);
|
|
241
|
-
useEffect(() => {
|
|
242
|
-
if (query && query !== searchText) setSearchText(query);
|
|
243
|
-
}, [query]);
|
|
244
|
-
useEffect(() => {
|
|
245
|
-
const esq = new URLSearchParams(window.location.search).get("esq");
|
|
246
|
-
if (esq) {
|
|
247
|
-
setSearchText(esq);
|
|
248
|
-
performSearch({ query: esq });
|
|
249
|
-
}
|
|
250
|
-
}, [performSearch]);
|
|
251
|
-
const fetchAutocompleteSuggestions = (_query) => {
|
|
252
|
-
return Promise.resolve([]);
|
|
253
|
-
};
|
|
1583
|
+
}, [productList.length, searchResultsState]);
|
|
254
1584
|
useEffect(() => {
|
|
255
|
-
if (
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
isLoading: false
|
|
260
|
-
});
|
|
261
|
-
return;
|
|
1585
|
+
if (query && query !== searchText) {
|
|
1586
|
+
const esq = new URLSearchParams(window.location.search).get("esq");
|
|
1587
|
+
setSearchText(query);
|
|
1588
|
+
performSearch({ query: esq ?? query });
|
|
262
1589
|
}
|
|
263
|
-
setAutocompleteState((prev) => ({
|
|
264
|
-
...prev,
|
|
265
|
-
isLoading: true
|
|
266
|
-
}));
|
|
267
|
-
const fetchData = async () => {
|
|
268
|
-
try {
|
|
269
|
-
const results = await fetchAutocompleteSuggestions?.(debouncedSearchText);
|
|
270
|
-
setAutocompleteState({
|
|
271
|
-
results: results ?? [],
|
|
272
|
-
isLoading: false
|
|
273
|
-
});
|
|
274
|
-
} catch (error) {
|
|
275
|
-
logger_default.logError("Failed to fetch autocomplete suggestions:", error);
|
|
276
|
-
setAutocompleteState({
|
|
277
|
-
results: [],
|
|
278
|
-
isLoading: false
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
fetchData();
|
|
283
1590
|
}, [
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
1591
|
+
performSearch,
|
|
1592
|
+
query,
|
|
1593
|
+
setSearchText
|
|
287
1594
|
]);
|
|
288
1595
|
return {
|
|
289
1596
|
searchData,
|
|
@@ -291,16 +1598,17 @@ const useSearch = () => {
|
|
|
291
1598
|
merchantShortName: safeMerchantShortName,
|
|
292
1599
|
productCardConfig: safeProductCardConfig,
|
|
293
1600
|
productList,
|
|
1601
|
+
recommendedProducts,
|
|
294
1602
|
autocompleteResults,
|
|
295
1603
|
searchFilters: filters,
|
|
296
1604
|
availableDynamicFilters,
|
|
297
1605
|
selectedFilterOptions,
|
|
298
1606
|
searchText,
|
|
1607
|
+
query: query || "",
|
|
299
1608
|
searchResultsState,
|
|
300
|
-
isLoadingAutocomplete,
|
|
301
1609
|
isLoadingSearch,
|
|
302
1610
|
isFilterOpen,
|
|
303
|
-
|
|
1611
|
+
shouldShowAutocomplete,
|
|
304
1612
|
focusedIndex,
|
|
305
1613
|
focusedOptionId,
|
|
306
1614
|
filterButtonText,
|
|
@@ -308,6 +1616,8 @@ const useSearch = () => {
|
|
|
308
1616
|
onSubmitSearch: handleSubmitSearch,
|
|
309
1617
|
onAutocompleteSelect: handleAutocompleteSelect,
|
|
310
1618
|
onKeyDown: handleKeyDown,
|
|
1619
|
+
onSearchInputFocus: handleSearchInputFocus,
|
|
1620
|
+
onSearchInputBlur: handleSearchInputBlur,
|
|
311
1621
|
onToggleDynamicFilter: handleToggleDynamicFilter,
|
|
312
1622
|
onSelectFilterItem: handleSelectFilterItem,
|
|
313
1623
|
onRemoveFilter: handleRemoveFilter,
|
|
@@ -319,4 +1629,4 @@ const useSearch = () => {
|
|
|
319
1629
|
|
|
320
1630
|
//#endregion
|
|
321
1631
|
export { useSearch };
|
|
322
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6WyJoYW5kbGVTZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2hvb2tzL1NlYXJjaC91c2VTZWFyY2gudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZUF0b20sIHVzZUF0b21WYWx1ZSwgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlRGVib3VuY2UgfSBmcm9tIFwic3JjL2hvb2tzL0RlYm91bmNlL3VzZURlYm91bmNlXCI7XG5pbXBvcnQge1xuICBhZGRTZWFyY2hGaWx0ZXJBdG9tLFxuICBjbGVhclNlYXJjaEZpbHRlcnNBdG9tLFxuICBjcmVhdGVGaWx0ZXJPcHRpb24sXG4gIGZpbHRlcmVkU2VhcmNoUHJvZHVjdHNBdG9tLFxuICBwZXJmb3JtU2VhcmNoQXRvbSxcbiAgcmVtb3ZlU2VhcmNoRmlsdGVyQXRvbSxcbiAgc2VhcmNoQXRvbSxcbiAgc2VhcmNoRmlsdGVyc0F0b20sXG4gIHNlYXJjaFBhcmFtc0F0b20sXG4gIHNlYXJjaFByb2R1Y3RTb3J0aW5nQXRvbSxcbiAgc2VhcmNoU2VsZWN0ZWRGaWx0ZXJzQXRvbSxcbiAgU2VsZWN0ZWRGaWx0ZXJPcHRpb24sXG59IGZyb20gXCJzcmMvYXRvbXMvc2VhcmNoXCI7XG5pbXBvcnQge1xuICBhdXRvY29tcGxldGVTdGF0ZUF0b20sXG4gIGlzRmlsdGVyT3BlbkF0b20sXG59IGZyb20gXCJzcmMvYXRvbXMvZ2xvYmFsU2VhcmNoL2dsb2JhbFNlYXJjaFwiO1xuaW1wb3J0IHsgZm9ybWF0RmlsdGVyRGlzcGxheU5hbWUgfSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC91dGlsc1wiO1xuaW1wb3J0IHsgUHJvZHVjdFNvcnRpbmcgfSBmcm9tIFwic3JjL2F0b21zL3NlYXJjaC90eXBlc1wiO1xuaW1wb3J0IHtcbiAgU3BpZmZ5TWV0cmljc0V2ZW50TmFtZSxcbiAgdXNlQW1wbGl0dWRlLFxufSBmcm9tIFwic3JjL2NvbnRleHRzL2FtcGxpdHVkZUNvbnRleHQvYW1wbGl0dWRlQ29udGV4dFwiO1xuaW1wb3J0IHsgU3BpZmZ5V2lkZ2V0cyB9IGZyb20gXCJzcmMvYXBwbGljYXRpb24vbW9kZWxzL3NwaWZmeVdpZGdldHNcIjtcbmltcG9ydCB7IFByb2R1Y3RDYXJkQ29uZmlnIH0gZnJvbSBcInNyYy9jb250ZXh0cy90eXBlc1wiO1xuaW1wb3J0IExvZ2dlciBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL2xvZ2dpbmcvbG9nZ2VyXCI7XG5pbXBvcnQgeyBTZWFyY2hSZXN1bHQgfSBmcm9tIFwic3JjL2FwcGxpY2F0aW9uL21vZGVscy9hcGkvc2VhcmNoXCI7XG5pbXBvcnQgeyBTZWFyY2hSZXNwb25zZVByb2R1Y3QgfSBmcm9tIFwiQHNwaWZmeS1haS9jb21tZXJjZS1hcGktY2xpZW50XCI7XG5pbXBvcnQge1xuICBTZWFyY2hGaWx0ZXJEYXR1bSxcbiAgU2VsZWN0RmlsdGVySXRlbSxcbn0gZnJvbSBcInNyYy90eXBlcy9zZWFyY2gtZmlsdGVyLXR5cGVzXCI7XG5pbXBvcnQgeyBnZXRTZWFyY2hSZXN1bHRzU3RhdGUsIFNlYXJjaFJlc3VsdHNTdGF0ZSB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgb3JnU2hvcnROYW1lQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvZW52aXZlL2Vudml2ZUNvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlTmV3T3JnQ29uZmlnIH0gZnJvbSBcIi4uL05ld09yZ0NvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlVHJhY2tDb21wb25lbnRWaXNpYmxlRXZlbnQgfSBmcm9tIFwiLi4vVHJhY2tDb21wb25lbnRWaXNpYmxlRXZlbnRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSZXN1bHRzSG9jUHJvcHMge1xuICAvLyBEYXRhXG4gIHNlYXJjaERhdGE6IFNlYXJjaFJlc3VsdCB8IG51bGw7XG4gIHNlYXJjaFJlc3BvbnNlSWQ6IHN0cmluZztcbiAgbWVyY2hhbnRTaG9ydE5hbWU6IHN0cmluZztcbiAgcHJvZHVjdENhcmRDb25maWc6IFByb2R1Y3RDYXJkQ29uZmlnO1xuICBwcm9kdWN0TGlzdDogU2VhcmNoUmVzcG9uc2VQcm9kdWN0W107XG4gIGF1dG9jb21wbGV0ZVJlc3VsdHM6IHN0cmluZ1tdO1xuICBzZWFyY2hGaWx0ZXJzOiBTZWFyY2hGaWx0ZXJEYXR1bVtdO1xuICBhdmFpbGFibGVEeW5hbWljRmlsdGVyczogeyBuYW1lOiBzdHJpbmc7IGRpc3BsYXlOYW1lOiBzdHJpbmcgfVtdO1xuICBzZWxlY3RlZEZpbHRlck9wdGlvbnM6IFNlbGVjdGVkRmlsdGVyT3B0aW9uW107XG5cbiAgLy8gU3RhdGVcbiAgc2VhcmNoVGV4dDogc3RyaW5nO1xuICBzZWFyY2hSZXN1bHRzU3RhdGU6IFNlYXJjaFJlc3VsdHNTdGF0ZTtcbiAgaXNMb2FkaW5nQXV0b2NvbXBsZXRlOiBib29sZWFuO1xuICBpc0xvYWRpbmdTZWFyY2g6IGJvb2xlYW47XG4gIGlzRmlsdGVyT3BlbjogYm9vbGVhbjtcbiAgaXNEaXJ0eTogYm9vbGVhbjtcbiAgZm9jdXNlZEluZGV4OiBudW1iZXI7XG4gIGZvY3VzZWRPcHRpb25JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIC8vIFVJXG4gIGZpbHRlckJ1dHRvblRleHQ6IHN0cmluZztcblxuICAvLyBFdmVudCBIYW5kbGVyc1xuICBvblNlYXJjaElucHV0Q2hhbmdlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZDtcbiAgb25TdWJtaXRTZWFyY2g6ICgpID0+IHZvaWQ7XG4gIG9uQXV0b2NvbXBsZXRlU2VsZWN0OiAoc3VnZ2VzdGlvbjogc3RyaW5nKSA9PiB2b2lkO1xuICBvbktleURvd246IChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4gdm9pZDtcbiAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiAoe1xuICAgIGZpbHRlcixcbiAgICBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUsXG4gIH06IHtcbiAgICBmaWx0ZXI6IHN0cmluZztcbiAgICBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWU6IHN0cmluZztcbiAgfSkgPT4gdm9pZDtcbiAgb25TZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtO1xuICBvblJlbW92ZUZpbHRlcjogKGZpbHRlcjogU2VsZWN0ZWRGaWx0ZXJPcHRpb24pID0+IHZvaWQ7XG4gIG9uQ2xlYXJBbGxGaWx0ZXJzOiAoKSA9PiB2b2lkO1xuICBzZXRJc0ZpbHRlck9wZW46IChpc0ZpbHRlck9wZW46IGJvb2xlYW4pID0+IHZvaWQ7XG5cbiAgLy8gUmVmc1xuICBzZWFyY2hSZXN1bHRzUmVmOiBSZWFjdC5SZWZPYmplY3Q8SFRNTERpdkVsZW1lbnQ+O1xufVxuXG5leHBvcnQgY29uc3QgdXNlU2VhcmNoID0gKCk6IFNlYXJjaFJlc3VsdHNIb2NQcm9wcyA9PiB7XG4gIC8vIEF0b21zXG4gIGNvbnN0IGNvbmZpZyA9IHVzZU5ld09yZ0NvbmZpZygpO1xuICBjb25zdCBvcmdTaG9ydE5hbWUgPSB1c2VBdG9tVmFsdWUob3JnU2hvcnROYW1lQXRvbSk7XG4gIGNvbnN0IHsgZGF0YTogc2VhcmNoRGF0YSwgbG9hZGluZzogaXNMb2FkaW5nU2VhcmNoIH0gPVxuICAgIHVzZUF0b21WYWx1ZShzZWFyY2hBdG9tKTtcbiAgY29uc3QgcHJvZHVjdExpc3QgPSB1c2VBdG9tVmFsdWUoZmlsdGVyZWRTZWFyY2hQcm9kdWN0c0F0b20pO1xuICBjb25zdCBwZXJmb3JtU2VhcmNoID0gdXNlU2V0QXRvbShwZXJmb3JtU2VhcmNoQXRvbSk7XG4gIGNvbnN0IFtcbiAgICB7IHJlc3VsdHM6IGF1dG9jb21wbGV0ZVJlc3VsdHMsIGlzTG9hZGluZzogaXNMb2FkaW5nQXV0b2NvbXBsZXRlIH0sXG4gICAgc2V0QXV0b2NvbXBsZXRlU3RhdGUsXG4gIF0gPSB1c2VBdG9tKGF1dG9jb21wbGV0ZVN0YXRlQXRvbSk7XG4gIGNvbnN0IFt7IHF1ZXJ5IH1dID0gdXNlQXRvbShzZWFyY2hQYXJhbXNBdG9tKTtcbiAgY29uc3QgW2lzRmlsdGVyT3Blbiwgc2V0SXNGaWx0ZXJPcGVuXSA9IHVzZUF0b20oaXNGaWx0ZXJPcGVuQXRvbSk7XG4gIGNvbnN0IFtzZWxlY3RlZEZpbHRlck9wdGlvbnNdID0gdXNlQXRvbShzZWFyY2hTZWxlY3RlZEZpbHRlcnNBdG9tKTtcbiAgY29uc3QgYWRkRmlsdGVyID0gdXNlU2V0QXRvbShhZGRTZWFyY2hGaWx0ZXJBdG9tKTtcbiAgY29uc3QgcmVtb3ZlRmlsdGVyID0gdXNlU2V0QXRvbShyZW1vdmVTZWFyY2hGaWx0ZXJBdG9tKTtcbiAgY29uc3QgW3Byb2R1Y3RTb3J0aW5nLCBzZXRQcm9kdWN0U29ydGluZ10gPSB1c2VBdG9tKHNlYXJjaFByb2R1Y3RTb3J0aW5nQXRvbSk7XG4gIGNvbnN0IGNsZWFyRmlsdGVycyA9IHVzZVNldEF0b20oY2xlYXJTZWFyY2hGaWx0ZXJzQXRvbSk7XG4gIGNvbnN0IHNlYXJjaEZpbHRlcnMgPSB1c2VBdG9tVmFsdWUoc2VhcmNoRmlsdGVyc0F0b20pO1xuXG4gIC8vIFN0YXRlXG4gIGNvbnN0IFtpc0RpcnR5LCBzZXRJc0RpcnR5XSA9IHVzZVN0YXRlKHRydWUpO1xuICBjb25zdCBbZm9jdXNlZEluZGV4LCBzZXRGb2N1c2VkSW5kZXhdID0gdXNlU3RhdGUoLTEpO1xuICBjb25zdCBbZm9jdXNlZE9wdGlvbklkLCBzZXRGb2N1c2VkT3B0aW9uSWRdID0gdXNlU3RhdGU8c3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgICB1bmRlZmluZWRcbiAgKTtcbiAgY29uc3QgW3NlYXJjaFRleHQsIHNldFNlYXJjaFRleHRdID0gdXNlU3RhdGUocXVlcnkgfHwgXCJcIik7XG5cbiAgLy8gUmVmc1xuICBjb25zdCBzZWFyY2hSZXN1bHRzUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcblxuICAvLyBEZXJpdmVkIFN0YXRlXG4gIGNvbnN0IGRlYm91bmNlZFNlYXJjaFRleHQgPSB1c2VEZWJvdW5jZShzZWFyY2hUZXh0LCAyMDApO1xuICBjb25zdCBzZWFyY2hSZXN1bHRzU3RhdGUgPSBnZXRTZWFyY2hSZXN1bHRzU3RhdGUoaXNMb2FkaW5nU2VhcmNoLCBzZWFyY2hEYXRhKTtcblxuICBjb25zdCBkeW5hbWljRmlsdGVycyA9IHNlYXJjaERhdGE/LmZpbHRlcnMgfHwgW107XG5cbiAgLy8gUHJvdmlkZSBmYWxsYmFjayB2YWx1ZXMgd2hlbiBvcmdVSUNvbmZpZyBpcyBub3QgeWV0IGF2YWlsYWJsZVxuICBjb25zdCBzYWZlUHJvZHVjdENhcmRDb25maWcgPSBjb25maWc/LmZyb250ZW5kQ29uZmlnPy51aUNvbmZpZ3NcbiAgICA/LnByb2R1Y3RDYXJkQ29uZmlnIHx8IHtcbiAgICB2YXJpYW50OiBcIm1pbmltYWxcIixcbiAgICBob3ZlclZhcmlhbnQ6IFwibm9uZVwiLFxuICAgIGxheW91dFZhcmlhbnQ6IFwic3F1YXJlXCIsXG4gIH07XG4gIGNvbnN0IHNhZmVNZXJjaGFudFNob3J0TmFtZSA9IG9yZ1Nob3J0TmFtZSB8fCBcIlwiO1xuXG4gIGNvbnN0IGF2YWlsYWJsZUR5bmFtaWNGaWx0ZXJzID0gdXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIGR5bmFtaWNGaWx0ZXJzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoZHluYW1pY0ZpbHRlck5hbWUpID0+XG4gICAgICAgICAgIXNlbGVjdGVkRmlsdGVyT3B0aW9ucy5zb21lKFxuICAgICAgICAgICAgKG9wdGlvbikgPT4gb3B0aW9uLmlkID09PSBgZHluYW1pYzoke2R5bmFtaWNGaWx0ZXJOYW1lfWBcbiAgICAgICAgICApXG4gICAgICApXG4gICAgICAubWFwKChkeW5hbWljRmlsdGVyTmFtZSkgPT4gKHtcbiAgICAgICAgbmFtZTogZHluYW1pY0ZpbHRlck5hbWUsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBmb3JtYXRGaWx0ZXJEaXNwbGF5TmFtZShkeW5hbWljRmlsdGVyTmFtZSksXG4gICAgICB9KSk7XG4gIH0sIFtkeW5hbWljRmlsdGVycywgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zXSk7XG5cbiAgY29uc3QgZmlsdGVycyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHNvcnRPcHRpb25zID0gW1xuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5GRUFUVVJFRCksXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlJlbGV2YW5jZVwiLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5GRUFUVVJFRCxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGZpbHRlckl0ZW1JZDogU3RyaW5nKFByb2R1Y3RTb3J0aW5nLlBSSUNFX0FTQyksXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlByaWNlOiBMb3cgdG8gSGlnaFwiLFxuICAgICAgICBwcm9kdWN0Q291bnQ6IDAsXG4gICAgICAgIGlzU2VsZWN0ZWQ6IHByb2R1Y3RTb3J0aW5nID09PSBQcm9kdWN0U29ydGluZy5QUklDRV9BU0MsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBmaWx0ZXJJdGVtSWQ6IFN0cmluZyhQcm9kdWN0U29ydGluZy5QUklDRV9ERVNDKSxcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiUHJpY2U6IEhpZ2ggdG8gTG93XCIsXG4gICAgICAgIHByb2R1Y3RDb3VudDogMCxcbiAgICAgICAgaXNTZWxlY3RlZDogcHJvZHVjdFNvcnRpbmcgPT09IFByb2R1Y3RTb3J0aW5nLlBSSUNFX0RFU0MsXG4gICAgICB9LFxuICAgIF07XG5cbiAgICByZXR1cm4gW1xuICAgICAgeyBmaWx0ZXJJZDogXCJzb3J0XCIsIGRpc3BsYXlOYW1lOiBcIlNPUlRcIiwgaXRlbXM6IHNvcnRPcHRpb25zIH0sXG4gICAgICAuLi5zZWFyY2hGaWx0ZXJzLFxuICAgIF0gYXMgU2VhcmNoRmlsdGVyRGF0dW1bXTtcbiAgfSwgW3Byb2R1Y3RTb3J0aW5nLCBzZWFyY2hGaWx0ZXJzXSk7XG5cbiAgY29uc3QgZmlsdGVyQnV0dG9uVGV4dCA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGNvbnN0IHNlbGVjdGVkQ291bnQgPSBmaWx0ZXJzLnJlZHVjZSgoYWNjOiBudW1iZXIsIGZpbHRlcikgPT4ge1xuICAgICAgaWYgKGZpbHRlci5maWx0ZXJJZCA9PT0gXCJzb3J0XCIpIHtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2MgKyBmaWx0ZXIuaXRlbXMuZmlsdGVyKChpdGVtKSA9PiBpdGVtLmlzU2VsZWN0ZWQpLmxlbmd0aDtcbiAgICB9LCAwKTtcbiAgICBpZiAoc2VsZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiRmlsdGVyICYgU29ydFwiO1xuICAgIH1cbiAgICByZXR1cm4gYEZpbHRlciAmIFNvcnQgKCR7c2VsZWN0ZWRDb3VudH0pYDtcbiAgfSwgW2ZpbHRlcnNdKTtcblxuICAvLyBDYWxsYmFja3NcbiAgY29uc3QgeyB0cmFja0V2ZW50IH0gPSB1c2VBbXBsaXR1ZGUoKTtcblxuICBjb25zdCBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyID0gdXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIGZpbHRlcixcbiAgICAgIGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZSxcbiAgICB9OiB7XG4gICAgICBmaWx0ZXI6IHN0cmluZztcbiAgICAgIGR5bmFtaWNGaWx0ZXJEaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoRmlsdGVyQ2xpY2tlZCxcbiAgICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICAgIGZpbHRlclR5cGU6IFwiRHluYW1pY1wiLFxuICAgICAgICAgIGZpbHRlclZhbHVlOiBmaWx0ZXIsXG4gICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBhZGRGaWx0ZXIoXG4gICAgICAgIGNyZWF0ZUZpbHRlck9wdGlvbihcImR5bmFtaWNcIiwgZmlsdGVyLCBkeW5hbWljRmlsdGVyRGlzcGxheU5hbWUpXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FkZEZpbHRlciwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF1cbiAgKTtcblxuICBjb25zdCBoYW5kbGVSZW1vdmVGaWx0ZXIgPSB1c2VDYWxsYmFjayhcbiAgICAoZmlsdGVyOiBTZWxlY3RlZEZpbHRlck9wdGlvbikgPT4ge1xuICAgICAgcmVtb3ZlRmlsdGVyKGZpbHRlci5pZCk7XG4gICAgfSxcbiAgICBbcmVtb3ZlRmlsdGVyXVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZVN1Ym1pdFNlYXJjaCA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICBpZiAoc2VhcmNoVGV4dC50cmltKCkpIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoUXVlcnlTdWJtaXR0ZWQsXG4gICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICBzZWFyY2hPcmlnaW46IFNwaWZmeVdpZGdldHMuU2VhcmNoUmVzdWx0cyxcbiAgICAgICAgICBxdWVyeVRleHQ6IHNlYXJjaFRleHQudHJpbSgpLFxuICAgICAgICB9LFxuICAgICAgICBhbHNvU2VuZFRvR29vZ2xlQW5hbHl0aWNzOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcbiAgICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KFwiZXNxXCIsIHNlYXJjaFRleHQudHJpbSgpKTtcbiAgICAgIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSh7fSwgXCJcIiwgdXJsKTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogc2VhcmNoVGV4dC50cmltKCkgfSk7XG4gICAgfVxuICB9LCBbcGVyZm9ybVNlYXJjaCwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF0pO1xuXG4gIGNvbnN0IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCA9IHVzZUNhbGxiYWNrKFxuICAgIChzdWdnZXN0aW9uOiBzdHJpbmcpID0+IHtcbiAgICAgIHNldFNlYXJjaFRleHQoc3VnZ2VzdGlvbik7XG4gICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICB9LFxuICAgIFtoYW5kbGVTdWJtaXRTZWFyY2gsIHNldFNlYXJjaFRleHRdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlS2V5RG93biA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudDogUmVhY3QuS2V5Ym9hcmRFdmVudDxIVE1MSW5wdXRFbGVtZW50PikgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd0Rvd25cIikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCBuZXdJbmRleCA9IChmb2N1c2VkSW5kZXggKyAxKSAlIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoO1xuICAgICAgICBzZXRGb2N1c2VkSW5kZXgobmV3SW5kZXgpO1xuICAgICAgICBzZXRGb2N1c2VkT3B0aW9uSWQoYG9wdGlvbi0ke25ld0luZGV4fWApO1xuICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dVcFwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IG5ld0luZGV4ID1cbiAgICAgICAgICAoZm9jdXNlZEluZGV4IC0gMSArIGF1dG9jb21wbGV0ZVJlc3VsdHMubGVuZ3RoKSAlXG4gICAgICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cy5sZW5ndGg7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleChuZXdJbmRleCk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZChgb3B0aW9uLSR7bmV3SW5kZXh9YCk7XG4gICAgICB9IGVsc2UgaWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiKSB7XG4gICAgICAgIGlmIChmb2N1c2VkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBoYW5kbGVTdWJtaXRTZWFyY2goKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGNvbnN0IHN1Z2dlc3Rpb25UZXh0ID0gYXV0b2NvbXBsZXRlUmVzdWx0c1tmb2N1c2VkSW5kZXhdO1xuICAgICAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdChzdWdnZXN0aW9uVGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQua2V5ID09PSBcIkVzY2FwZVwiKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHNldEZvY3VzZWRJbmRleCgtMSk7XG4gICAgICAgIHNldEZvY3VzZWRPcHRpb25JZCh1bmRlZmluZWQpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW1xuICAgICAgYXV0b2NvbXBsZXRlUmVzdWx0cyxcbiAgICAgIGZvY3VzZWRJbmRleCxcbiAgICAgIGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICAgIGhhbmRsZVN1Ym1pdFNlYXJjaCxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlU2VhcmNoSW5wdXRDaGFuZ2UgPSAobmV3VmFsdWU6IHN0cmluZykgPT4ge1xuICAgIGlmIChuZXdWYWx1ZS5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoSW5wdXRTdGFydGVkLFxuICAgICAgICBldmVudFByb3BzOiB7XG4gICAgICAgICAgc2VhcmNoT3JpZ2luOiBTcGlmZnlXaWRnZXRzLlNlYXJjaFJlc3VsdHMsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgc2V0U2VhcmNoVGV4dChuZXdWYWx1ZSk7XG4gICAgc2V0SXNEaXJ0eSh0cnVlKTtcbiAgfTtcblxuICBjb25zdCBoYW5kbGVTZWxlY3RGaWx0ZXJJdGVtOiBTZWxlY3RGaWx0ZXJJdGVtID0gdXNlQ2FsbGJhY2soXG4gICAgKHtcbiAgICAgIGZpbHRlcklkLFxuICAgICAgZmlsdGVySXRlbUlkLFxuICAgICAgaXNTZWxlY3RlZCxcbiAgICAgIGRpc3BsYXlOYW1lLFxuICAgIH06IHtcbiAgICAgIGZpbHRlcklkOiBzdHJpbmc7XG4gICAgICBmaWx0ZXJJdGVtSWQ6IHN0cmluZztcbiAgICAgIGlzU2VsZWN0ZWQ6IGJvb2xlYW47XG4gICAgICBkaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmIChmaWx0ZXJJZCA9PT0gXCJzb3J0XCIpIHtcbiAgICAgICAgY29uc3QgbmV3U29ydCA9IGZpbHRlckl0ZW1JZCBhcyBQcm9kdWN0U29ydGluZztcbiAgICAgICAgdHJhY2tFdmVudCh7XG4gICAgICAgICAgZXZlbnROYW1lOiBTcGlmZnlNZXRyaWNzRXZlbnROYW1lLlNlYXJjaFNvcnRDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIHNvcnRUeXBlOiBuZXdTb3J0LFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBzZXRQcm9kdWN0U29ydGluZyhuZXdTb3J0KTtcbiAgICAgIH0gZWxzZSBpZiAoIWlzU2VsZWN0ZWQpIHtcbiAgICAgICAgcmVtb3ZlRmlsdGVyKGAke2ZpbHRlcklkfToke2ZpbHRlckl0ZW1JZH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICAgIGV2ZW50TmFtZTogU3BpZmZ5TWV0cmljc0V2ZW50TmFtZS5TZWFyY2hGaWx0ZXJDbGlja2VkLFxuICAgICAgICAgIGV2ZW50UHJvcHM6IHtcbiAgICAgICAgICAgIGZpbHRlclR5cGU6IFwiU3RhdGljXCIsXG4gICAgICAgICAgICBmaWx0ZXJDYXRlZ29yeTogZmlsdGVySWQsXG4gICAgICAgICAgICBmaWx0ZXJWYWx1ZTogZmlsdGVySXRlbUlkLFxuICAgICAgICAgICAgcXVlcnlUZXh0OiBzZWFyY2hUZXh0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBhZGRGaWx0ZXIoY3JlYXRlRmlsdGVyT3B0aW9uKGZpbHRlcklkLCBmaWx0ZXJJdGVtSWQsIGRpc3BsYXlOYW1lKSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbYWRkRmlsdGVyLCByZW1vdmVGaWx0ZXIsIHNldFByb2R1Y3RTb3J0aW5nLCBzZWFyY2hUZXh0LCB0cmFja0V2ZW50XVxuICApO1xuXG4gIGNvbnN0IGhhbmRsZUNsZWFyQWxsRmlsdGVycyA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBzZXRQcm9kdWN0U29ydGluZyhQcm9kdWN0U29ydGluZy5GRUFUVVJFRCk7XG4gICAgY2xlYXJGaWx0ZXJzKCk7XG4gIH0sIFtzZXRQcm9kdWN0U29ydGluZywgY2xlYXJGaWx0ZXJzXSk7XG5cbiAgLy8gU2lkZSBFZmZlY3RzXG4gIHVzZVRyYWNrQ29tcG9uZW50VmlzaWJsZUV2ZW50KFxuICAgIFNwaWZmeVdpZGdldHMuU2VhcmNoUmVzdWx0cyxcbiAgICBzZWFyY2hSZXN1bHRzUmVmLFxuICAgIHt9LFxuICAgIFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoQ29tcG9uZW50VmlzaWJsZVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHByb2R1Y3RMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgIHRyYWNrRXZlbnQoe1xuICAgICAgICBldmVudE5hbWU6IFNwaWZmeU1ldHJpY3NFdmVudE5hbWUuU2VhcmNoUmVzdWx0c1ZpZXdlZCxcbiAgICAgICAgZXZlbnRQcm9wczoge1xuICAgICAgICAgIHF1ZXJ5VGV4dDogc2VhcmNoVGV4dCxcbiAgICAgICAgICByZXN1bHRzQ291bnQ6IHByb2R1Y3RMaXN0Lmxlbmd0aCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfSwgW3Byb2R1Y3RMaXN0Lmxlbmd0aCwgc2VhcmNoVGV4dCwgdHJhY2tFdmVudF0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5ICE9PSBzZWFyY2hUZXh0KSB7XG4gICAgICBzZXRTZWFyY2hUZXh0KHF1ZXJ5KTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbcXVlcnldKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGVzcSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMod2luZG93LmxvY2F0aW9uLnNlYXJjaCkuZ2V0KFwiZXNxXCIpO1xuICAgIGlmIChlc3EpIHtcbiAgICAgIHNldFNlYXJjaFRleHQoZXNxKTtcbiAgICAgIHBlcmZvcm1TZWFyY2goeyBxdWVyeTogZXNxIH0pO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIFtwZXJmb3JtU2VhcmNoXSk7XG5cbiAgY29uc3QgZmV0Y2hBdXRvY29tcGxldGVTdWdnZXN0aW9ucyA9IChfcXVlcnk6IHN0cmluZykgPT4ge1xuICAgIC8vIFRPRE86IGltcGxlbWVudCBhdXRvY29tcGxldGUgc3VnZ2VzdGlvbnNcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChmZXRjaEF1dG9jb21wbGV0ZVN1Z2dlc3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlzRGlydHkgfHwgZGVib3VuY2VkU2VhcmNoVGV4dC5sZW5ndGggPD0gMikge1xuICAgICAgc2V0QXV0b2NvbXBsZXRlU3RhdGUoeyByZXN1bHRzOiBbXSwgaXNMb2FkaW5nOiBmYWxzZSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRBdXRvY29tcGxldGVTdGF0ZSgocHJldikgPT4gKHsgLi4ucHJldiwgaXNMb2FkaW5nOiB0cnVlIH0pKTtcblxuICAgIGNvbnN0IGZldGNoRGF0YSA9IGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBmZXRjaEF1dG9jb21wbGV0ZVN1Z2dlc3Rpb25zPy4oXG4gICAgICAgICAgZGVib3VuY2VkU2VhcmNoVGV4dFxuICAgICAgICApO1xuICAgICAgICBzZXRBdXRvY29tcGxldGVTdGF0ZSh7IHJlc3VsdHM6IHJlc3VsdHMgPz8gW10sIGlzTG9hZGluZzogZmFsc2UgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBMb2dnZXIubG9nRXJyb3IoXCJGYWlsZWQgdG8gZmV0Y2ggYXV0b2NvbXBsZXRlIHN1Z2dlc3Rpb25zOlwiLCBlcnJvcik7XG4gICAgICAgIHNldEF1dG9jb21wbGV0ZVN0YXRlKHsgcmVzdWx0czogW10sIGlzTG9hZGluZzogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZldGNoRGF0YSgpO1xuICB9LCBbZGVib3VuY2VkU2VhcmNoVGV4dCwgaXNEaXJ0eSwgc2V0QXV0b2NvbXBsZXRlU3RhdGVdKTtcblxuICByZXR1cm4ge1xuICAgIHNlYXJjaERhdGEsXG4gICAgc2VhcmNoUmVzcG9uc2VJZDogc2VhcmNoRGF0YT8uc2VhcmNoUmVzcG9uc2VJZCA/PyBcIlwiLFxuICAgIG1lcmNoYW50U2hvcnROYW1lOiBzYWZlTWVyY2hhbnRTaG9ydE5hbWUsXG4gICAgcHJvZHVjdENhcmRDb25maWc6IHNhZmVQcm9kdWN0Q2FyZENvbmZpZyxcbiAgICBwcm9kdWN0TGlzdCxcbiAgICBhdXRvY29tcGxldGVSZXN1bHRzLFxuICAgIHNlYXJjaEZpbHRlcnM6IGZpbHRlcnMsXG4gICAgYXZhaWxhYmxlRHluYW1pY0ZpbHRlcnMsXG4gICAgc2VsZWN0ZWRGaWx0ZXJPcHRpb25zLFxuICAgIHNlYXJjaFRleHQsXG4gICAgc2VhcmNoUmVzdWx0c1N0YXRlLFxuICAgIGlzTG9hZGluZ0F1dG9jb21wbGV0ZSxcbiAgICBpc0xvYWRpbmdTZWFyY2gsXG4gICAgaXNGaWx0ZXJPcGVuLFxuICAgIGlzRGlydHksXG4gICAgZm9jdXNlZEluZGV4LFxuICAgIGZvY3VzZWRPcHRpb25JZCxcbiAgICBmaWx0ZXJCdXR0b25UZXh0LFxuICAgIG9uU2VhcmNoSW5wdXRDaGFuZ2U6IGhhbmRsZVNlYXJjaElucHV0Q2hhbmdlLFxuICAgIG9uU3VibWl0U2VhcmNoOiBoYW5kbGVTdWJtaXRTZWFyY2gsXG4gICAgb25BdXRvY29tcGxldGVTZWxlY3Q6IGhhbmRsZUF1dG9jb21wbGV0ZVNlbGVjdCxcbiAgICBvbktleURvd246IGhhbmRsZUtleURvd24sXG4gICAgb25Ub2dnbGVEeW5hbWljRmlsdGVyOiBoYW5kbGVUb2dnbGVEeW5hbWljRmlsdGVyLFxuICAgIG9uU2VsZWN0RmlsdGVySXRlbTogaGFuZGxlU2VsZWN0RmlsdGVySXRlbSxcbiAgICBvblJlbW92ZUZpbHRlcjogaGFuZGxlUmVtb3ZlRmlsdGVyLFxuICAgIG9uQ2xlYXJBbGxGaWx0ZXJzOiBoYW5kbGVDbGVhckFsbEZpbHRlcnMsXG4gICAgc2V0SXNGaWx0ZXJPcGVuLFxuICAgIHNlYXJjaFJlc3VsdHNSZWYsXG4gIH07XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXVGQSxNQUFhLGtCQUF5QztDQUVwRCxNQUFNLFNBQVMsaUJBQWlCO0NBQ2hDLE1BQU0sZUFBZSxhQUFhLGlCQUFpQjtDQUNuRCxNQUFNLEVBQUUsTUFBTSxZQUFZLFNBQVMsb0JBQ2pDLGFBQWEsV0FBVztDQUMx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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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
|