@envive-ai/react-hooks 0.2.6-alpha-arthur-4 → 0.2.6-alpha-arthur-6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AmplitudeOperations-CHlghWFQ.cjs → AmplitudeOperations-BU9A9Jdd.cjs} +2 -2
- package/dist/{AmplitudeOperations-BNFYCh-W.js → AmplitudeOperations-Cu59kGhS.js} +2 -2
- package/dist/{NewOrgConfig-BeoqDaSB.js → NewOrgConfig-9wAXPrL1.js} +2 -2
- package/dist/{NewOrgConfig-DgWHQyUc.cjs → NewOrgConfig-B8M-0VB5.cjs} +2 -2
- package/dist/{TrackComponentVisibleEvent-vsaQaHKi.cjs → TrackComponentVisibleEvent-7iexpwkM.cjs} +2 -2
- package/dist/{TrackComponentVisibleEvent-HbfzgXtF.js → TrackComponentVisibleEvent-s4aYQ1Po.js} +2 -2
- package/dist/amplitudeContext-BDnZgp_c.js +237 -0
- package/dist/amplitudeContext-BINPUhrB.cjs +253 -0
- package/dist/{amplitudeTrackEventAtom-nkZxYoLu.cjs → amplitudeTrackEventAtom-D2dmLwju.cjs} +1 -1
- package/dist/{amplitudeTrackEventAtom-pJbLG4En.js → amplitudeTrackEventAtom-T5Hfgv1d.js} +1 -1
- package/dist/app-C6fvSwK7.js +110 -0
- package/dist/app-DLIfJpA6.cjs +150 -0
- package/dist/application/models/index.d.cts +1 -1
- package/dist/application/utils/index.d.cts +2 -2
- package/dist/application/utils/index.d.ts +2 -2
- package/dist/{atomStore-CZKe3itM.cjs → atomStore-8ppNkJ_n.cjs} +1 -1
- package/dist/{atomStore-BuopbV9k.js → atomStore-BLYJ2ZoQ.js} +1 -1
- package/dist/atoms/app/index.cjs +5 -5
- package/dist/atoms/app/index.d.cts +8 -7
- package/dist/atoms/app/index.d.ts +8 -7
- package/dist/atoms/app/index.js +4 -5
- package/dist/atoms/atomStore/index.cjs +1 -1
- package/dist/atoms/atomStore/index.d.cts +1 -1
- package/dist/atoms/atomStore/index.js +1 -1
- package/dist/atoms/chat/index.cjs +7 -20
- package/dist/atoms/chat/index.d.cts +31 -31
- package/dist/atoms/chat/index.d.ts +31 -31
- package/dist/atoms/chat/index.js +7 -20
- package/dist/atoms/globalSearch/index.cjs +1 -1
- package/dist/atoms/globalSearch/index.d.cts +6 -6
- package/dist/atoms/globalSearch/index.d.ts +6 -6
- package/dist/atoms/globalSearch/index.js +1 -1
- package/dist/atoms/org/index.cjs +8 -7
- package/dist/atoms/org/index.d.cts +16 -16
- package/dist/atoms/org/index.d.ts +16 -16
- package/dist/atoms/org/index.js +4 -3
- package/dist/atoms/search/index.cjs +7 -6
- package/dist/atoms/search/index.d.cts +14 -14
- package/dist/atoms/search/index.d.ts +15 -15
- package/dist/atoms/search/index.js +7 -6
- 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-DJ1pDg-l.js → cdnContext-QjEi8uUT.js} +2 -2
- package/dist/{cdnContext-Bs73r4Xd.cjs → cdnContext-c_ktbXSd.cjs} +2 -2
- package/dist/chat-B_uOuZIL.js +226 -0
- package/dist/chat-C37wHZ_K.cjs +326 -0
- package/dist/{chatState-DRJrYuno.js → chatState-8MDLF_t4.js} +1 -1
- package/dist/{chatState-CMoQ1TMs.cjs → chatState-DVZZ2tvl.cjs} +1 -1
- package/dist/config/locators/components/search/index.d.cts +1 -1
- package/dist/contexts/amplitudeContext/index.cjs +8 -6
- package/dist/contexts/amplitudeContext/index.js +8 -6
- package/dist/contexts/cdnContext/index.cjs +2 -2
- package/dist/contexts/cdnContext/index.js +2 -2
- package/dist/contexts/enviveConfigContext/index.cjs +3 -3
- package/dist/contexts/enviveConfigContext/index.d.cts +1 -1
- package/dist/contexts/enviveConfigContext/index.js +3 -3
- package/dist/contexts/enviveCssContext/index.cjs +10 -10
- package/dist/contexts/enviveCssContext/index.js +10 -10
- package/dist/contexts/featureFlagContext/index.cjs +3 -3
- package/dist/contexts/featureFlagContext/index.d.cts +1 -1
- package/dist/contexts/featureFlagContext/index.js +3 -3
- package/dist/contexts/featureFlagServiceContext/index.cjs +2 -2
- package/dist/contexts/featureFlagServiceContext/index.js +2 -2
- package/dist/contexts/graphqlContext/index.cjs +4 -4
- package/dist/contexts/graphqlContext/index.d.ts +2 -2
- package/dist/contexts/graphqlContext/index.js +4 -4
- package/dist/contexts/localStorageContext/index.cjs +1 -1
- package/dist/contexts/localStorageContext/index.js +1 -1
- package/dist/contexts/newOrgConfigContext/index.cjs +9 -9
- package/dist/contexts/newOrgConfigContext/index.js +9 -9
- package/dist/contexts/searchContext/index.cjs +10 -20
- package/dist/contexts/searchContext/index.js +10 -20
- 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 +1 -1
- package/dist/contexts/shopifyUrlContext/index.js +1 -1
- package/dist/contexts/systemSettingsContext/index.cjs +2 -2
- package/dist/contexts/systemSettingsContext/index.d.cts +2 -2
- package/dist/contexts/systemSettingsContext/index.d.ts +4 -4
- package/dist/contexts/systemSettingsContext/index.js +2 -2
- package/dist/contexts/userIdentityContext/index.cjs +9 -9
- package/dist/contexts/userIdentityContext/index.js +9 -9
- package/dist/{enviveConfig-Cw7o9TLb.js → enviveConfig-Bv94rcOj.js} +1 -1
- package/dist/{enviveConfig-6XJa6HAF.cjs → enviveConfig-CA2mgxjq.cjs} +1 -1
- package/dist/{enviveConfigContext-D_bCeK56.js → enviveConfigContext-DDqnpREh.js} +2 -2
- package/dist/{enviveConfigContext-DoBbJZp_.cjs → enviveConfigContext-wHEs5vdF.cjs} +2 -2
- package/dist/exceptions/index.d.ts +1 -1
- package/dist/{featureFlagServiceContext-DQYo0d6Q.cjs → featureFlagServiceContext-C9RuEQda.cjs} +1 -1
- package/dist/featureFlagServiceContext-ClnlCJV5.d.cts +1 -1
- package/dist/{featureFlagServiceContext-GIO9xKV0.js → featureFlagServiceContext-CqQvJq3j.js} +1 -1
- package/dist/{globalSearch-B8jHLScz.js → globalSearch-B_v9qfCT.js} +1 -1
- package/dist/{globalSearch-JJI1Fijh.cjs → globalSearch-OiF96VLG.cjs} +1 -1
- package/dist/graphqlConfig-9tU9_Lzt.js +14 -0
- package/dist/graphqlConfig-BxnjdY1c.cjs +39 -0
- package/dist/{graphqlContext-cAZtpn-W.js → graphqlContext--SHxTN8f.js} +2 -2
- package/dist/{graphqlContext-CXyZamIk.cjs → graphqlContext-DHhncOYt.cjs} +2 -2
- package/dist/hooks/AmplitudeOperations/index.cjs +9 -7
- package/dist/hooks/AmplitudeOperations/index.js +9 -7
- package/dist/hooks/AppDetails/index.cjs +8 -19
- package/dist/hooks/AppDetails/index.d.cts +3 -12
- package/dist/hooks/AppDetails/index.d.ts +3 -12
- package/dist/hooks/AppDetails/index.js +8 -19
- package/dist/hooks/BlockBackButton/index.d.cts +1 -1
- package/dist/hooks/CdnOperations/index.cjs +2 -2
- package/dist/hooks/CdnOperations/index.js +2 -2
- package/dist/hooks/ChatToggle/index.cjs +13 -24
- package/dist/hooks/ChatToggle/index.d.cts +1 -1
- package/dist/hooks/ChatToggle/index.js +13 -24
- package/dist/hooks/ChatToggleAnalytics/index.cjs +11 -9
- package/dist/hooks/ChatToggleAnalytics/index.js +11 -9
- package/dist/hooks/CustomerSupportHandoff/index.d.cts +1 -1
- package/dist/hooks/Debounce/index.d.ts +1 -1
- package/dist/hooks/GrabAndScroll/index.d.cts +1 -1
- package/dist/hooks/GrabAndScroll/index.d.ts +2 -2
- package/dist/hooks/GraphQLConfig/index.cjs +5 -5
- package/dist/hooks/GraphQLConfig/index.js +5 -5
- package/dist/hooks/IdentifyUser/index.cjs +9 -9
- package/dist/hooks/IdentifyUser/index.js +9 -9
- package/dist/hooks/ImageResolver/index.cjs +1 -1
- package/dist/hooks/ImageResolver/index.js +1 -1
- package/dist/hooks/LocalStorageOperations/index.cjs +1 -1
- package/dist/hooks/LocalStorageOperations/index.js +1 -1
- package/dist/hooks/NewOrgConfig/index.cjs +10 -10
- package/dist/hooks/NewOrgConfig/index.d.ts +2 -2
- package/dist/hooks/NewOrgConfig/index.js +10 -10
- package/dist/hooks/Search/index.cjs +18 -15
- package/dist/hooks/Search/index.d.cts +1 -1
- package/dist/hooks/Search/index.js +18 -15
- package/dist/hooks/SearchOperations/index.cjs +11 -21
- package/dist/hooks/SearchOperations/index.d.cts +1 -1
- package/dist/hooks/SearchOperations/index.js +11 -21
- 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 +1 -1
- package/dist/hooks/ShopifyUrlOperations/index.js +1 -1
- package/dist/hooks/SystemSettingsContext/index.cjs +2 -2
- package/dist/hooks/SystemSettingsContext/index.d.cts +4 -4
- package/dist/hooks/SystemSettingsContext/index.d.ts +4 -4
- package/dist/hooks/SystemSettingsContext/index.js +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/index.cjs +9 -7
- package/dist/hooks/TrackComponentVisibleEvent/index.js +9 -7
- package/dist/hooks/UpdateAnalyticsProps/index.cjs +11 -11
- package/dist/hooks/UpdateAnalyticsProps/index.d.cts +1 -1
- package/dist/hooks/UpdateAnalyticsProps/index.js +8 -8
- package/dist/hooks/utils.d.ts +1 -1
- package/dist/index-CMZcE7pk.d.cts +1 -1
- package/dist/index-CkaLTFlB.d.ts +1 -1
- package/dist/index-Cl35ht05.d.ts +1 -1
- package/dist/index-DIq5F_-r.d.ts +1 -1
- package/dist/index-npqPeJ1g.d.cts +1 -1
- package/dist/index-smzckpKv.d.ts +1 -1
- package/dist/interceptors/index.d.cts +1 -1
- package/dist/{localStorageContext-CvwraLEo.js → localStorageContext-ByBkX01A.js} +1 -1
- package/dist/{localStorageContext-DIIUUEvL.cjs → localStorageContext-DZeQYK5o.cjs} +1 -1
- package/dist/{newOrgConfigAtom-wQeGYEFq.js → newOrgConfigAtom--tewb_G0.js} +1 -1
- package/dist/{newOrgConfigAtom-vEChAMrW.cjs → newOrgConfigAtom-DkSi45_Q.cjs} +1 -1
- package/dist/{newOrgConfigContext-C8uWGgkE.cjs → newOrgConfigContext-Bu0aUAaQ.cjs} +5 -5
- package/dist/{newOrgConfigContext-garCXaH1.js → newOrgConfigContext-DveWXpnn.js} +5 -5
- package/dist/org-DU3Wck0R.cjs +43 -0
- package/dist/org-DptftvB6.js +12 -0
- package/dist/{orgAnalyticsConfig-Bxm8BZch.js → orgAnalyticsConfig-9TyGN3XE.js} +1 -1
- package/dist/{orgAnalyticsConfig-DU1aESDh.cjs → orgAnalyticsConfig-C-MmVJI_.cjs} +1 -1
- package/dist/{search-C4ZLnfzE.js → search-Bg9CM7Pr.js} +4 -4
- package/dist/{search-DUJiAeEo.cjs → search-dzjbiWgZ.cjs} +4 -4
- package/dist/{searchContext-Ck94DuBO.cjs → searchContext-DVDxVP6F.cjs} +5 -5
- package/dist/{searchContext-BrPSGjRo.js → searchContext-XLoz5-mf.js} +5 -5
- package/dist/{searchServiceAdapter-C3_FRUly.js → searchServiceAdapter-BSPZOg1r.js} +1 -1
- package/dist/{searchServiceAdapter-tPd0NClV.cjs → searchServiceAdapter-DrjFCiw8.cjs} +1 -1
- package/dist/{sessionStorageContext-CBwNI1Va.js → sessionStorageContext-2YcmPz4e.js} +1 -1
- package/dist/{sessionStorageContext-CmHIsV7a.cjs → sessionStorageContext-BKniJ7Gn.cjs} +1 -1
- package/dist/{shopifyUrlContext-C3gw4ZIN.js → shopifyUrlContext-CsQGH9zr.js} +1 -1
- package/dist/{shopifyUrlContext-ZJtT_0XX.cjs → shopifyUrlContext-D24p48M1.cjs} +1 -1
- package/dist/{systemSettingsContext-DzAyy0iP.js → systemSettingsContext-DY64VEFC.js} +2 -2
- package/dist/{systemSettingsContext-ru4nA9k_.cjs → systemSettingsContext-DgzDCZ3p.cjs} +2 -2
- package/dist/useAppDetails-C-V1pUwN.cjs +38 -0
- package/dist/useAppDetails-eHiX9MCB.js +30 -0
- package/dist/{useGraphQLConfig-f2MK-FPn.js → useGraphQLConfig-DxmjxBCL.js} +2 -2
- package/dist/{useGraphQLConfig-B6CiGP57.cjs → useGraphQLConfig-h1xSOrvO.cjs} +2 -2
- package/dist/userIdentityContext-5pH_mMyM.cjs +436 -0
- package/dist/userIdentityContext-DjUEecq5.js +418 -0
- package/dist/{utils-_Q_-LvZS.cjs → utils-BBICrPjW.cjs} +1 -1
- package/dist/{utils-B_cnJJAH.js → utils-w4-xONRA.js} +1 -1
- package/package.json +1 -1
- package/src/application/commerce-api.ts +2 -5
- package/src/atoms/app/index.ts +19 -2
- package/src/atoms/chat/messageQueue.ts +3 -8
- package/src/contexts/amplitudeContext/amplitudeContext.tsx +2 -2
- package/src/contexts/userIdentityContext/userIdentityContext.tsx +7 -0
- package/src/hooks/AppDetails/useAppDetails.ts +2 -15
- package/dist/amplitudeContext-Dp-Tm43M.cjs +0 -253
- package/dist/amplitudeContext-DwszOulA.js +0 -237
- package/dist/app-BCuEBoPJ.cjs +0 -36
- package/dist/app-D73Rksby.js +0 -14
- package/dist/chat-BqUkaIbS.js +0 -226
- package/dist/chat-zxjIy0qQ.cjs +0 -326
- package/dist/org-DEzeBBk6.js +0 -22
- package/dist/org-Ky10pcuq.cjs +0 -77
- package/dist/useAppDetails-Bg1yCUZi.cjs +0 -41
- package/dist/useAppDetails-Buzm9yIj.js +0 -33
- package/dist/userIdentityContext-B8XLgxMQ.cjs +0 -431
- package/dist/userIdentityContext-DgFLendI.js +0 -414
- package/dist/variant-Ben5gKtM.js +0 -93
- package/dist/variant-CvYVVCqU.cjs +0 -107
- package/src/contexts/chatContext/chatContext.tsx +0 -512
- /package/dist/{enviveConfigContext-DJLIdWAK.cjs → enviveConfigContext-BNixYqrz.cjs} +0 -0
- /package/dist/{enviveConfigContext-Qh6nF9qc.js → enviveConfigContext-ghO3oO9J.js} +0 -0
- /package/dist/{featureFlagServiceContext-C_wrr2WY.cjs → featureFlagServiceContext-lsgEUS_a.cjs} +0 -0
- /package/dist/{featureFlagServiceContext-CG3rFJov.js → featureFlagServiceContext-x0YyrABt.js} +0 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const require_exceptions = require('./exceptions-BjDgLzGi.cjs');
|
|
3
|
+
const require_dist = require('./dist-B7BErEyV.cjs');
|
|
4
|
+
const require_models = require('./models-wh2gh_Qz.cjs');
|
|
5
|
+
const require_logger = require('./logger-BqHq67zN.cjs');
|
|
6
|
+
const require_utils = require('./utils-DucG4gQ7.cjs');
|
|
7
|
+
const require_enviveConfig = require('./enviveConfig-CA2mgxjq.cjs');
|
|
8
|
+
const require_atomStore = require('./atomStore-8ppNkJ_n.cjs');
|
|
9
|
+
const require_app = require('./app-DLIfJpA6.cjs');
|
|
10
|
+
const require_graphqlConfig = require('./graphqlConfig-BxnjdY1c.cjs');
|
|
11
|
+
const require_localStorageContext = require('./localStorageContext-DZeQYK5o.cjs');
|
|
12
|
+
let __spiffy_ai_commerce_api_client = require("@spiffy-ai/commerce-api-client");
|
|
13
|
+
__spiffy_ai_commerce_api_client = require_chunk.__toESM(__spiffy_ai_commerce_api_client);
|
|
14
|
+
let uuid = require("uuid");
|
|
15
|
+
uuid = require_chunk.__toESM(uuid);
|
|
16
|
+
let react = require("react");
|
|
17
|
+
react = require_chunk.__toESM(react);
|
|
18
|
+
let jotai = require("jotai");
|
|
19
|
+
jotai = require_chunk.__toESM(jotai);
|
|
20
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
21
|
+
react_jsx_runtime = require_chunk.__toESM(react_jsx_runtime);
|
|
22
|
+
let ua_parser_js = require("ua-parser-js");
|
|
23
|
+
ua_parser_js = require_chunk.__toESM(ua_parser_js);
|
|
24
|
+
|
|
25
|
+
//#region src/application/commerce-api.ts
|
|
26
|
+
async function errorResponseBody(error) {
|
|
27
|
+
try {
|
|
28
|
+
return await error.response.json();
|
|
29
|
+
} catch {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async function throwSessionRestartRequiredIf(errorMsg, error) {
|
|
34
|
+
if (!(error instanceof __spiffy_ai_commerce_api_client.ResponseError)) {
|
|
35
|
+
require_logger.logger_default.logInfo(errorMsg, error);
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
const errorResponse = await errorResponseBody(error);
|
|
39
|
+
if (errorResponse?.message?.toLowerCase() === "unsupported product" || errorResponse?.app_code?.toUpperCase() === "PRODUCT_NOT_FOUND") throw new require_exceptions.UnsupportedProductException();
|
|
40
|
+
else if (errorResponse?.app_code?.toUpperCase() === "RESTART_SESSION" || errorResponse?.sub_code?.toUpperCase() === "NOT_FOUND") {
|
|
41
|
+
require_logger.logger_default.logInfo("Session does not exist. Re-start session", error, error.response, errorResponse);
|
|
42
|
+
throw new require_exceptions.SessionRestartRequired();
|
|
43
|
+
}
|
|
44
|
+
require_logger.logger_default.logInfo(errorMsg, error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
var CommerceApiClient = class CommerceApiClient {
|
|
48
|
+
static {
|
|
49
|
+
this.getInstance = () => {
|
|
50
|
+
if (!CommerceApiClient.instance) CommerceApiClient.instance = new CommerceApiClient();
|
|
51
|
+
return CommerceApiClient.instance;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
constructor(basePath) {
|
|
55
|
+
this.suggestionsAbortController = new AbortController();
|
|
56
|
+
this.responsesAbortController = new AbortController();
|
|
57
|
+
const baseUrl = require_atomStore.getAtomStore().get(require_enviveConfig.baseUrlAtom);
|
|
58
|
+
const config = new __spiffy_ai_commerce_api_client.Configuration({
|
|
59
|
+
basePath: basePath || baseUrl,
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": "application/json",
|
|
62
|
+
Accept: "application/json"
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
this.defaultApi = new __spiffy_ai_commerce_api_client.DefaultApi(config);
|
|
66
|
+
this.inferenceApi = new __spiffy_ai_commerce_api_client.InferenceApi(config);
|
|
67
|
+
this.customerServiceApi = new __spiffy_ai_commerce_api_client.CustomerServiceApi(config);
|
|
68
|
+
}
|
|
69
|
+
static {
|
|
70
|
+
this.resolveUrl = async (url) => {
|
|
71
|
+
const atomStore = require_atomStore.getAtomStore();
|
|
72
|
+
const orgShortName = atomStore.get(require_enviveConfig.orgShortNameAtom);
|
|
73
|
+
const orgId = atomStore.get(require_graphqlConfig.orgIdAtom);
|
|
74
|
+
const userId = atomStore.get(require_app.userIdAtom);
|
|
75
|
+
const chatId = atomStore.get(require_app.chatIdAtom);
|
|
76
|
+
const source = atomStore.get(require_enviveConfig.contextSourceAtom);
|
|
77
|
+
const env = atomStore.get(require_enviveConfig.envAtom);
|
|
78
|
+
const featureFlagService = atomStore.get(require_graphqlConfig.featureFlagServiceAtom);
|
|
79
|
+
const context = {
|
|
80
|
+
user_id: userId ?? "",
|
|
81
|
+
org_id: orgId ?? "",
|
|
82
|
+
org_short_name: orgShortName ?? "",
|
|
83
|
+
chat_id: chatId ?? "",
|
|
84
|
+
source: source ?? __spiffy_ai_commerce_api_client.ContextSourceEnum.App,
|
|
85
|
+
env: env ?? __spiffy_ai_commerce_api_client.ContextEnvEnum.Dev
|
|
86
|
+
};
|
|
87
|
+
const featureGates = featureFlagService?.featureFlagService?.getFeatureFlags() || {};
|
|
88
|
+
const urlResolvingRequest = {
|
|
89
|
+
url,
|
|
90
|
+
context,
|
|
91
|
+
feature_gates: featureGates
|
|
92
|
+
};
|
|
93
|
+
return await (await CommerceApiClient.getInstance().inferenceApi.v1UrlResolvingPostRaw({ UrlResolvingRequest: urlResolvingRequest })).raw.json();
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
static {
|
|
97
|
+
this.reportSession = async (reportRequest) => {
|
|
98
|
+
await CommerceApiClient.getInstance().defaultApi.v1ChatsReportSessionIdPost({ ReportSessionRequest: reportRequest });
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
static {
|
|
102
|
+
this.getNextResponses = async (payload) => {
|
|
103
|
+
try {
|
|
104
|
+
return (await CommerceApiClient.getInstance().inferenceApi.v1NextResponsesPost({ NextMessageRequest: require_utils.messageRequestToCommerceMessageRequest(payload) })).map((resp) => require_models.validateResponse(resp)).map((resp) => require_utils.messageFromResponse(resp)).filter((m) => m != null);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
require_logger.logger_default.logInfo("Failed to get next responses", err, {
|
|
107
|
+
payloadContext: payload?.context,
|
|
108
|
+
userEvents: payload?.userEvents
|
|
109
|
+
});
|
|
110
|
+
await throwSessionRestartRequiredIf("Failed to get next responses", err);
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
static {
|
|
116
|
+
this.getNextResponseStreaming = (payload) => {
|
|
117
|
+
async function* generate(inferenceApi, abortController) {
|
|
118
|
+
try {
|
|
119
|
+
const response = await inferenceApi.v1NextResponsesPostRaw({ NextMessageRequest: require_utils.messageRequestToCommerceMessageRequest(payload) }, { signal: abortController.signal });
|
|
120
|
+
if (!response.raw.body) {
|
|
121
|
+
require_logger.logger_default.logError("[spiffy-ai] No body in the streamed response", void 0, { response: response.raw });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const reader = response.raw.body.getReader();
|
|
125
|
+
const decoder = new TextDecoder("utf-8");
|
|
126
|
+
let partial = "";
|
|
127
|
+
const safeParse = (line) => {
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(line);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
require_logger.logger_default.logError("[spiffy-ai] Error parsing streamed line", err, {
|
|
132
|
+
line,
|
|
133
|
+
partial
|
|
134
|
+
});
|
|
135
|
+
partial = line;
|
|
136
|
+
return partial;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
const processChunk = (chunk) => {
|
|
140
|
+
return `${partial}${chunk}`.split("\n").map((line) => line.replace(/^data: /, "").trim()).filter((line) => line !== "" && line !== "[DONE]").map(safeParse).filter((v) => v);
|
|
141
|
+
};
|
|
142
|
+
while (true) {
|
|
143
|
+
const { done, value } = await reader.read();
|
|
144
|
+
if (done) break;
|
|
145
|
+
const chunk = decoder.decode(value);
|
|
146
|
+
const parsedLines = processChunk(chunk);
|
|
147
|
+
for (const parsedLine of parsedLines) {
|
|
148
|
+
const validatedResponse = require_models.validateResponse(parsedLine);
|
|
149
|
+
if (validatedResponse) yield validatedResponse;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
} catch (error) {
|
|
153
|
+
require_logger.logger_default.logError("[spiffy-ai] Failed to get next streaming responses", error, {
|
|
154
|
+
payloadContext: payload?.context,
|
|
155
|
+
userEvents: payload?.userEvents
|
|
156
|
+
});
|
|
157
|
+
await throwSessionRestartRequiredIf("Failed to get next streaming responses", error);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
CommerceApiClient.getInstance().responsesAbortController.abort();
|
|
161
|
+
CommerceApiClient.getInstance().responsesAbortController = new AbortController();
|
|
162
|
+
return generate(CommerceApiClient.getInstance().inferenceApi, CommerceApiClient.getInstance().responsesAbortController);
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
static {
|
|
166
|
+
this.getNextSuggestions = async (payload) => {
|
|
167
|
+
try {
|
|
168
|
+
CommerceApiClient.getInstance().suggestionsAbortController.abort();
|
|
169
|
+
CommerceApiClient.getInstance().suggestionsAbortController = new AbortController();
|
|
170
|
+
return (await CommerceApiClient.getInstance().inferenceApi.v1NextSuggestionsPost({ NextMessageRequest: require_utils.messageRequestToCommerceMessageRequest(payload) }, { signal: CommerceApiClient.getInstance().suggestionsAbortController.signal })).map((resp) => require_models.validateSuggestion(resp)).filter((suggestion) => suggestion != null);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
require_logger.logger_default.logInfo("Failed to get suggestions", error, {
|
|
173
|
+
payloadContext: payload?.context,
|
|
174
|
+
userEvents: payload?.userEvents
|
|
175
|
+
});
|
|
176
|
+
await throwSessionRestartRequiredIf("Failed to get suggestions", error);
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
static {
|
|
182
|
+
this.getResponses = async (orgId, chatId, userId) => {
|
|
183
|
+
let data = {
|
|
184
|
+
responses: [],
|
|
185
|
+
suggestions: [],
|
|
186
|
+
user_events: []
|
|
187
|
+
};
|
|
188
|
+
const request = {
|
|
189
|
+
org_id: orgId,
|
|
190
|
+
chat_id: chatId,
|
|
191
|
+
user_id: userId
|
|
192
|
+
};
|
|
193
|
+
try {
|
|
194
|
+
data = await CommerceApiClient.getInstance().defaultApi.v1GetSessionMessages(request);
|
|
195
|
+
} catch (error) {
|
|
196
|
+
await throwSessionRestartRequiredIf("Failed to get chat responses", error);
|
|
197
|
+
}
|
|
198
|
+
const responses = data?.responses?.map((turn) => turn.map((response) => require_models.validateResponse(response)).filter((response) => response != null));
|
|
199
|
+
const suggestions = data?.suggestions.map((suggestion) => require_models.validateSuggestion(suggestion)).filter((suggestion) => suggestion != null);
|
|
200
|
+
const userEvents = data?.user_events.map((event) => require_models.validateUserEvent(event)).filter((event) => event != null);
|
|
201
|
+
const formSubmittedUserEventsFormIds = userEvents.filter((event) => event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted).map((event) => event.attributes.formResponseId);
|
|
202
|
+
const assistantMessages = responses.map((turn) => turn.filter((response) => !(response.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form && formSubmittedUserEventsFormIds.includes(response.id))).map((response) => require_utils.messageFromResponse(response)).filter((message) => message != null)).filter((turn) => turn.length > 0);
|
|
203
|
+
const userMessages = userEvents.map((event) => {
|
|
204
|
+
if ([__spiffy_ai_commerce_api_client.UserEventCategory.QueryTyped, __spiffy_ai_commerce_api_client.UserEventCategory.Search].includes(event.category)) return [require_utils.messageFromQueryEvent(event)];
|
|
205
|
+
if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.SuggestionClicked) return [require_utils.messageFromSuggestionEvent(event, suggestions)];
|
|
206
|
+
if (event.category === __spiffy_ai_commerce_api_client.UserEventCategory.FormSubmitted) {
|
|
207
|
+
const formResponse = responses.flat().find((response) => response.id === event.attributes.formResponseId && event.attributes.formType !== __spiffy_ai_commerce_api_client.FormType.Escalation);
|
|
208
|
+
if (formResponse && formResponse.category === __spiffy_ai_commerce_api_client.ResponseCategory.Form) return [require_utils.messageFromFormSubmittedEvent(event, formResponse.attributes)];
|
|
209
|
+
}
|
|
210
|
+
return [];
|
|
211
|
+
}).filter((message) => message.length > 0);
|
|
212
|
+
const sortedMessages = [...assistantMessages, ...userMessages].sort((a, b) => new Date(a[0].createdAt).getTime() - new Date(b[0].createdAt).getTime());
|
|
213
|
+
return {
|
|
214
|
+
responses,
|
|
215
|
+
userEvents,
|
|
216
|
+
suggestions,
|
|
217
|
+
messages: sortedMessages
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
static {
|
|
222
|
+
this.isSupportedEvent = async (payload) => {
|
|
223
|
+
try {
|
|
224
|
+
const httpResponseText = await (await CommerceApiClient.getInstance().inferenceApi.v1SupportedEventPostRaw({ SupportedEventRequest: require_utils.coreSupportedEventRequestToApiRequest(payload) })).raw.text();
|
|
225
|
+
const httpResponseJson = JSON.parse(httpResponseText);
|
|
226
|
+
return {
|
|
227
|
+
...httpResponseJson,
|
|
228
|
+
numberOfReviews: httpResponseJson.num_of_reviews,
|
|
229
|
+
merchant_tags: httpResponseJson.merchant_tags || []
|
|
230
|
+
};
|
|
231
|
+
} catch (err) {
|
|
232
|
+
require_logger.logger_default.logError("Failed to get response for v1SupportedEventPost", { err });
|
|
233
|
+
return {
|
|
234
|
+
supported: false,
|
|
235
|
+
ready: false,
|
|
236
|
+
category: void 0,
|
|
237
|
+
collections: [],
|
|
238
|
+
numberOfReviews: void 0,
|
|
239
|
+
top_category: void 0,
|
|
240
|
+
merchant_tags: []
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
static {
|
|
246
|
+
this.identifyUser = async (spiffyUserId, merchantUserId, uaDetails) => {
|
|
247
|
+
try {
|
|
248
|
+
await CommerceApiClient.getInstance().defaultApi.v1AnalyticsIdentifyPost({ AnalyticsIdentifyRequest: {
|
|
249
|
+
user_id: spiffyUserId,
|
|
250
|
+
os_name: uaDetails.os,
|
|
251
|
+
os_version: uaDetails.osVersion,
|
|
252
|
+
platform: uaDetails.os,
|
|
253
|
+
device_id: uaDetails.deviceModel,
|
|
254
|
+
device_brand: uaDetails.deviceBrand,
|
|
255
|
+
device_manufacturer: uaDetails.deviceManufacturer,
|
|
256
|
+
device_model: uaDetails.deviceModel,
|
|
257
|
+
user_properties: {
|
|
258
|
+
cdp_user_id: merchantUserId,
|
|
259
|
+
browser: uaDetails.browser,
|
|
260
|
+
browser_version: uaDetails.browserVersion,
|
|
261
|
+
user_agent: uaDetails.userAgent
|
|
262
|
+
}
|
|
263
|
+
} });
|
|
264
|
+
} catch (err) {
|
|
265
|
+
require_logger.logger_default.logError("Failed to identify user", err);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
static {
|
|
270
|
+
this.mapContextSourceToV1OrgConfigGetSource = (source) => {
|
|
271
|
+
if (source === void 0) return void 0;
|
|
272
|
+
switch (source) {
|
|
273
|
+
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Fork: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Fork;
|
|
274
|
+
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Playground: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Playground;
|
|
275
|
+
case __spiffy_ai_commerce_api_client.ContextSourceEnum.App: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.App;
|
|
276
|
+
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Test: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Test;
|
|
277
|
+
case __spiffy_ai_commerce_api_client.ContextSourceEnum.Eval: return __spiffy_ai_commerce_api_client.V1OrgConfigGetSourceEnum.Test;
|
|
278
|
+
default: return source;
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
static {
|
|
283
|
+
this.getOrgConfig = async (user_id) => {
|
|
284
|
+
try {
|
|
285
|
+
const atomStore = require_atomStore.getAtomStore();
|
|
286
|
+
const reactAppName = atomStore.get(require_enviveConfig.reactAppNameAtom);
|
|
287
|
+
const contextSource = atomStore.get(require_enviveConfig.contextSourceAtom);
|
|
288
|
+
const featureFlagService = atomStore.get(require_graphqlConfig.featureFlagServiceAtom);
|
|
289
|
+
const request = {
|
|
290
|
+
namespace: reactAppName,
|
|
291
|
+
user_id,
|
|
292
|
+
source: this.mapContextSourceToV1OrgConfigGetSource(contextSource),
|
|
293
|
+
include_experiments: Object.values(require_dist.ProductExperiment),
|
|
294
|
+
include_feature_gates: Object.entries(featureFlagService?.featureFlagService?.getFeatureFlags() || {}).filter(([, isEnabled]) => isEnabled).map(([featureGateName]) => featureGateName)
|
|
295
|
+
};
|
|
296
|
+
const response = await CommerceApiClient.getInstance().defaultApi.v1OrgConfigGet(request);
|
|
297
|
+
return require_models.validateOrgConfigResults(response);
|
|
298
|
+
} catch (err) {
|
|
299
|
+
require_logger.logger_default.logError(`Failed to get org config`, err, { err });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
static {
|
|
305
|
+
this.addNoteToLatestConversation = async (spiffyUserId, email, customerServiceProvider) => {
|
|
306
|
+
require_logger.logger_default.logInfo(`addNoteToLatestConversation - user_id=${spiffyUserId} email=${email} customer_service_provider=${customerServiceProvider}`);
|
|
307
|
+
try {
|
|
308
|
+
await CommerceApiClient.getInstance().customerServiceApi.v1CustserviceAddNoteToLatestConversationPost({ AddNoteToLatestConversationRequest: {
|
|
309
|
+
spiffy_user_id: spiffyUserId,
|
|
310
|
+
email,
|
|
311
|
+
customer_service_provider: customerServiceProvider
|
|
312
|
+
} });
|
|
313
|
+
} catch (err) {
|
|
314
|
+
require_logger.logger_default.logError("Failed to add note to latest conversation", { err });
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
static {
|
|
319
|
+
this.getCustomerServiceApi = () => CommerceApiClient.getInstance().customerServiceApi;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
var commerce_api_default = CommerceApiClient;
|
|
323
|
+
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/contexts/userIdentityContext/userIdentityContext.tsx
|
|
326
|
+
const getUserAgentDetails = () => {
|
|
327
|
+
const result = new ua_parser_js.default().getResult();
|
|
328
|
+
return {
|
|
329
|
+
os: result?.os?.name,
|
|
330
|
+
osVersion: result?.os?.version,
|
|
331
|
+
deviceBrand: result?.device?.vendor,
|
|
332
|
+
deviceManufacturer: result?.device?.vendor,
|
|
333
|
+
deviceModel: result?.device?.model,
|
|
334
|
+
browser: result?.browser?.name,
|
|
335
|
+
browserVersion: result?.browser?.version,
|
|
336
|
+
userAgent: result?.ua
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
const UserIdentityContext = (0, react.createContext)(void 0);
|
|
340
|
+
const UserIdentityProvider = ({ children }) => {
|
|
341
|
+
const { getItem, setItem, isAvailable: localStorageIsReady } = require_localStorageContext.useLocalStorage();
|
|
342
|
+
const [isReady, setIsReady] = (0, react.useState)(false);
|
|
343
|
+
(0, react.useEffect)(() => {
|
|
344
|
+
setIsReady(localStorageIsReady);
|
|
345
|
+
}, [localStorageIsReady]);
|
|
346
|
+
const USER_ID_OVERRIDE_KEY = "v1-spiffy-user-id-override";
|
|
347
|
+
const USER_ID_DEFAULT_KEY = "v1-spiffy-user-id-default";
|
|
348
|
+
const getUserIdOverrideFromLocalStorage = (0, react.useCallback)(() => getItem(USER_ID_OVERRIDE_KEY) ?? void 0, [getItem]);
|
|
349
|
+
const getUserIdDefaultFromLocalStorage = (0, react.useCallback)(() => getItem(USER_ID_DEFAULT_KEY) ?? void 0, [getItem]);
|
|
350
|
+
const setUserIdDefaultInLocalStorage = (0, react.useCallback)((userId) => {
|
|
351
|
+
require_logger.logger_default.logInfo(`setUserIdDefaultInLocalStorage - Setting user_id=${userId}`);
|
|
352
|
+
setItem(USER_ID_DEFAULT_KEY, userId);
|
|
353
|
+
return userId;
|
|
354
|
+
}, [setItem, USER_ID_DEFAULT_KEY]);
|
|
355
|
+
const setUserIdOverrideInLocalStorage = (0, react.useCallback)((userId) => {
|
|
356
|
+
require_logger.logger_default.logInfo(`setUserIdOverrideInLocalStorage - Setting user_id=${userId}`);
|
|
357
|
+
setItem(USER_ID_OVERRIDE_KEY, userId);
|
|
358
|
+
return userId;
|
|
359
|
+
}, [setItem, USER_ID_OVERRIDE_KEY]);
|
|
360
|
+
const clearUserIdOverrideInLocalStorage = (0, react.useCallback)(() => {
|
|
361
|
+
require_logger.logger_default.logInfo(`clearUserIdOverrideInLocalStorage - Clearing user_id`);
|
|
362
|
+
setItem(USER_ID_OVERRIDE_KEY, "");
|
|
363
|
+
}, [setItem, USER_ID_OVERRIDE_KEY]);
|
|
364
|
+
const getUserIdOrDefault = (0, react.useCallback)(() => {
|
|
365
|
+
const userIdOverride = getUserIdOverrideFromLocalStorage();
|
|
366
|
+
if (userIdOverride) return userIdOverride;
|
|
367
|
+
const defaultUserId = getUserIdDefaultFromLocalStorage();
|
|
368
|
+
if (defaultUserId) return defaultUserId;
|
|
369
|
+
return setUserIdDefaultInLocalStorage(`spiffy-user-id-${(0, uuid.v4)()}`);
|
|
370
|
+
}, [
|
|
371
|
+
getUserIdOverrideFromLocalStorage,
|
|
372
|
+
getUserIdDefaultFromLocalStorage,
|
|
373
|
+
setUserIdDefaultInLocalStorage
|
|
374
|
+
]);
|
|
375
|
+
const identifyUser = (0, react.useCallback)(async () => {
|
|
376
|
+
if (!isReady) {
|
|
377
|
+
require_logger.logger_default.logWarn("[UserIdentityContext] Context not ready, skipping identifyUser", void 0);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
try {
|
|
381
|
+
const cdpUserId = "UNKNOWN_CDP_USER_ID";
|
|
382
|
+
const userId = getUserIdOrDefault();
|
|
383
|
+
const userAgentDetails = getUserAgentDetails();
|
|
384
|
+
await commerce_api_default.identifyUser(userId, cdpUserId, userAgentDetails);
|
|
385
|
+
} catch (error) {
|
|
386
|
+
require_logger.logger_default.logError("[spiffy-ai] Error identifying user", error);
|
|
387
|
+
}
|
|
388
|
+
}, [isReady, getUserIdOrDefault]);
|
|
389
|
+
const value = (0, react.useMemo)(() => ({
|
|
390
|
+
identifyUser,
|
|
391
|
+
getUserIdOrDefault,
|
|
392
|
+
getUserIdOverrideFromLocalStorage,
|
|
393
|
+
getUserIdDefaultFromLocalStorage,
|
|
394
|
+
setUserIdDefaultInLocalStorage,
|
|
395
|
+
setUserIdOverrideInLocalStorage,
|
|
396
|
+
clearUserIdOverrideInLocalStorage,
|
|
397
|
+
isReady
|
|
398
|
+
}), [
|
|
399
|
+
identifyUser,
|
|
400
|
+
getUserIdOrDefault,
|
|
401
|
+
getUserIdOverrideFromLocalStorage,
|
|
402
|
+
getUserIdDefaultFromLocalStorage,
|
|
403
|
+
setUserIdDefaultInLocalStorage,
|
|
404
|
+
setUserIdOverrideInLocalStorage,
|
|
405
|
+
clearUserIdOverrideInLocalStorage,
|
|
406
|
+
isReady
|
|
407
|
+
]);
|
|
408
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UserIdentityContext.Provider, {
|
|
409
|
+
value,
|
|
410
|
+
children
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
const useUserIdentity = () => {
|
|
414
|
+
const context = (0, react.useContext)(UserIdentityContext);
|
|
415
|
+
const setUserId = (0, jotai.useSetAtom)(require_app.userIdAtom);
|
|
416
|
+
(0, react.useEffect)(() => {
|
|
417
|
+
setUserId(context?.getUserIdOrDefault() ?? "");
|
|
418
|
+
}, [context, setUserId]);
|
|
419
|
+
if (!context) throw new Error("useUserIdentity must be used within a UserIdentityProvider");
|
|
420
|
+
return context;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
//#endregion
|
|
424
|
+
Object.defineProperty(exports, 'UserIdentityProvider', {
|
|
425
|
+
enumerable: true,
|
|
426
|
+
get: function () {
|
|
427
|
+
return UserIdentityProvider;
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
Object.defineProperty(exports, 'useUserIdentity', {
|
|
431
|
+
enumerable: true,
|
|
432
|
+
get: function () {
|
|
433
|
+
return useUserIdentity;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlcklkZW50aXR5Q29udGV4dC01cEhfbU15TS5janMiLCJuYW1lcyI6WyJSZXNwb25zZUVycm9yIiwiVW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uIiwiU2Vzc2lvblJlc3RhcnRSZXF1aXJlZCIsImdldEF0b21TdG9yZSIsImJhc2VVcmxBdG9tIiwiY29uZmlnOiBDb25maWd1cmF0aW9uIiwiQ29uZmlndXJhdGlvbiIsIkRlZmF1bHRBcGkiLCJJbmZlcmVuY2VBcGkiLCJDdXN0b21lclNlcnZpY2VBcGkiLCJvcmdTaG9ydE5hbWVBdG9tIiwib3JnSWRBdG9tIiwidXNlcklkQXRvbSIsImNoYXRJZEF0b20iLCJjb250ZXh0U291cmNlQXRvbSIsImVudkF0b20iLCJmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tIiwiY29udGV4dDogQ29udGV4dCIsIkNvbnRleHRTb3VyY2VFbnVtIiwiQ29udGV4dEVudkVudW0iLCJtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdCIsInZhbGlkYXRlUmVzcG9uc2UiLCJtZXNzYWdlRnJvbVJlc3BvbnNlIiwiZXJyOiB1bmtub3duIiwiZXJyb3I6IHVua25vd24iLCJ2YWxpZGF0ZVN1Z2dlc3Rpb24iLCJkYXRhOiBWMUdldFNlc3Npb25NZXNzYWdlczIwMFJlc3BvbnNlIiwicmVzcG9uc2VzOiBBcGlSZXNwb25zZVtdW10iLCJzdWdnZXN0aW9uczogU3VnZ2VzdGlvbltdIiwidXNlckV2ZW50czogVXNlckV2ZW50W10iLCJ2YWxpZGF0ZVVzZXJFdmVudCIsIlVzZXJFdmVudENhdGVnb3J5IiwiYXNzaXN0YW50TWVzc2FnZXM6IE1lc3NhZ2VbXVtdIiwiUmVzcG9uc2VDYXRlZ29yeSIsInVzZXJNZXNzYWdlczogTWVzc2FnZVtdW10iLCJtZXNzYWdlRnJvbVF1ZXJ5RXZlbnQiLCJtZXNzYWdlRnJvbVN1Z2dlc3Rpb25FdmVudCIsIkZvcm1UeXBlIiwibWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQiLCJjb3JlU3VwcG9ydGVkRXZlbnRSZXF1ZXN0VG9BcGlSZXF1ZXN0IiwiVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtIiwicmVhY3RBcHBOYW1lQXRvbSIsInJlcXVlc3Q6IFYxT3JnQ29uZmlnR2V0UmVxdWVzdCIsIlByb2R1Y3RFeHBlcmltZW50IiwidmFsaWRhdGVPcmdDb25maWdSZXN1bHRzIiwiVUFQYXJzZXIiLCJVc2VySWRlbnRpdHlQcm92aWRlcjogUmVhY3QuRkM8eyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0+IiwidXNlTG9jYWxTdG9yYWdlIiwiQ29tbWVyY2VBcGlDbGllbnQiLCJ1c2VySWRBdG9tIl0sInNvdXJjZXMiOlsiLi4vc3JjL2FwcGxpY2F0aW9uL2NvbW1lcmNlLWFwaS50cyIsIi4uL3NyYy9jb250ZXh0cy91c2VySWRlbnRpdHlDb250ZXh0L3VzZXJJZGVudGl0eUNvbnRleHQudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbnRleHQsXG4gIENvbnRleHRFbnZFbnVtLFxuICBDb25maWd1cmF0aW9uLFxuICBDdXN0b21lclNlcnZpY2VBcGksXG4gIERlZmF1bHRBcGksXG4gIEluZmVyZW5jZUFwaSxcbiAgUmVwb3J0U2Vzc2lvblJlcXVlc3QsXG4gIFJlc3BvbnNlRXJyb3IsXG4gIFVzZXJFdmVudENhdGVnb3J5LFxuICBWMUdldFNlc3Npb25NZXNzYWdlczIwMFJlc3BvbnNlLFxuICBWMU9yZ0NvbmZpZ0dldFJlcXVlc3QsXG4gIENvbnRleHRTb3VyY2VFbnVtLFxuICBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0sXG4gIEN1c3RvbWVyU2VydmljZVByb3ZpZGVyLFxuICBSZXNwb25zZUNhdGVnb3J5LFxuICBGb3JtVHlwZSxcbn0gZnJvbSBcIkBzcGlmZnktYWkvY29tbWVyY2UtYXBpLWNsaWVudFwiO1xuaW1wb3J0IHtcbiAgU3VwcG9ydGVkRXZlbnQsXG4gIFByb2R1Y3RFeHBlcmltZW50LFxuICBDbGllbnREZXRhaWxzLFxuICBVc2VyRXZlbnQsXG4gIE5leHRNZXNzYWdlUmVxdWVzdCxcbiAgU3VwcG9ydGVkRXZlbnRSZXF1ZXN0LFxuICBPcmdDb25maWcsXG59IGZyb20gXCJAZW52aXZlLWFpL3R5cGVzXCI7XG5pbXBvcnQgeyBBcGlSZXNwb25zZSwgTWVzc2FnZSwgU3VnZ2VzdGlvbiB9IGZyb20gXCJzcmMvdHlwZXNcIjtcbmltcG9ydCB7IHVzZXJJZEF0b20sIGNoYXRJZEF0b20gfSBmcm9tIFwic3JjL2F0b21zL2FwcFwiO1xuaW1wb3J0IHsgZ2V0QXRvbVN0b3JlIH0gZnJvbSBcInNyYy9hdG9tcy9hdG9tU3RvcmVcIjtcbmltcG9ydCB7XG4gIGJhc2VVcmxBdG9tLFxuICBvcmdTaG9ydE5hbWVBdG9tLFxuICBjb250ZXh0U291cmNlQXRvbSxcbiAgZW52QXRvbSxcbiAgcmVhY3RBcHBOYW1lQXRvbSxcbn0gZnJvbSBcInNyYy9hdG9tcy9lbnZpdmUvZW52aXZlQ29uZmlnXCI7XG5pbXBvcnQgeyBvcmdJZEF0b20sIGZlYXR1cmVGbGFnU2VydmljZUF0b20gfSBmcm9tIFwic3JjL2F0b21zL29yZ1wiO1xuaW1wb3J0IHtcbiAgVW5zdXBwb3J0ZWRQcm9kdWN0RXhjZXB0aW9uLFxuICBTZXNzaW9uUmVzdGFydFJlcXVpcmVkLFxufSBmcm9tIFwic3JjL2V4Y2VwdGlvbnNcIjtcbmltcG9ydCBMb2dnZXIgZnJvbSBcIi4vbG9nZ2luZy9sb2dnZXJcIjtcbmltcG9ydCB7XG4gIHZhbGlkYXRlUmVzcG9uc2UsXG4gIHZhbGlkYXRlU3VnZ2VzdGlvbixcbiAgdmFsaWRhdGVVc2VyRXZlbnQsXG4gIHZhbGlkYXRlT3JnQ29uZmlnUmVzdWx0cyxcbn0gZnJvbSBcIi4vbW9kZWxzXCI7XG5pbXBvcnQge1xuICBtZXNzYWdlUmVxdWVzdFRvQ29tbWVyY2VNZXNzYWdlUmVxdWVzdCxcbiAgbWVzc2FnZUZyb21SZXNwb25zZSxcbiAgbWVzc2FnZUZyb21RdWVyeUV2ZW50LFxuICBtZXNzYWdlRnJvbVN1Z2dlc3Rpb25FdmVudCxcbiAgbWVzc2FnZUZyb21Gb3JtU3VibWl0dGVkRXZlbnQsXG4gIGNvcmVTdXBwb3J0ZWRFdmVudFJlcXVlc3RUb0FwaVJlcXVlc3QsXG59IGZyb20gXCIuL3V0aWxzXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGVycm9yUmVzcG9uc2VCb2R5KGVycm9yOiBSZXNwb25zZUVycm9yKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yLnJlc3BvbnNlLmpzb24oKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRocm93U2Vzc2lvblJlc3RhcnRSZXF1aXJlZElmKGVycm9yTXNnOiBzdHJpbmcsIGVycm9yOiB1bmtub3duKSB7XG4gIGlmICghKGVycm9yIGluc3RhbmNlb2YgUmVzcG9uc2VFcnJvcikpIHtcbiAgICBMb2dnZXIubG9nSW5mbyhlcnJvck1zZywgZXJyb3IpO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgY29uc3QgZXJyb3JSZXNwb25zZSA9IGF3YWl0IGVycm9yUmVzcG9uc2VCb2R5KGVycm9yKTtcbiAgaWYgKFxuICAgIGVycm9yUmVzcG9uc2U/Lm1lc3NhZ2U/LnRvTG93ZXJDYXNlKCkgPT09IFwidW5zdXBwb3J0ZWQgcHJvZHVjdFwiIHx8IC8vIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LiBuZXdlciB2ZXJzaW9ucyBvZiB0aGUgQVBJIHJldHVybiBzdWJfY29kZSBpbnN0ZWFkIG9mIG1lc3NhZ2VcbiAgICBlcnJvclJlc3BvbnNlPy5hcHBfY29kZT8udG9VcHBlckNhc2UoKSA9PT0gXCJQUk9EVUNUX05PVF9GT1VORFwiXG4gICkge1xuICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZFByb2R1Y3RFeGNlcHRpb24oKTtcbiAgfSBlbHNlIGlmIChcbiAgICBlcnJvclJlc3BvbnNlPy5hcHBfY29kZT8udG9VcHBlckNhc2UoKSA9PT0gXCJSRVNUQVJUX1NFU1NJT05cIiB8fFxuICAgIGVycm9yUmVzcG9uc2U/LnN1Yl9jb2RlPy50b1VwcGVyQ2FzZSgpID09PSBcIk5PVF9GT1VORFwiIC8vIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LiBuZXcgQVBJIHJlc3BvbnNlcyB3aWxsIGNvbnRhaW4gXCJhcHBfY29kZVwiXG4gICkge1xuICAgIExvZ2dlci5sb2dJbmZvKFxuICAgICAgXCJTZXNzaW9uIGRvZXMgbm90IGV4aXN0LiBSZS1zdGFydCBzZXNzaW9uXCIsXG4gICAgICBlcnJvcixcbiAgICAgIGVycm9yLnJlc3BvbnNlLFxuICAgICAgZXJyb3JSZXNwb25zZVxuICAgICk7XG4gICAgdGhyb3cgbmV3IFNlc3Npb25SZXN0YXJ0UmVxdWlyZWQoKTtcbiAgfVxuXG4gIExvZ2dlci5sb2dJbmZvKGVycm9yTXNnLCBlcnJvcik7XG4gIHRocm93IGVycm9yO1xufVxuXG5jbGFzcyBDb21tZXJjZUFwaUNsaWVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdEFwaTogRGVmYXVsdEFwaTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGN1c3RvbWVyU2VydmljZUFwaTogQ3VzdG9tZXJTZXJ2aWNlQXBpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5mZXJlbmNlQXBpOiBJbmZlcmVuY2VBcGk7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgaW5zdGFuY2U6IENvbW1lcmNlQXBpQ2xpZW50IHwgdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgc3VnZ2VzdGlvbnNBYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgcHJpdmF0ZSByZXNwb25zZXNBYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0SW5zdGFuY2UgPSAoKTogQ29tbWVyY2VBcGlDbGllbnQgPT4ge1xuICAgIGlmICghQ29tbWVyY2VBcGlDbGllbnQuaW5zdGFuY2UpIHtcbiAgICAgIENvbW1lcmNlQXBpQ2xpZW50Lmluc3RhbmNlID0gbmV3IENvbW1lcmNlQXBpQ2xpZW50KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIENvbW1lcmNlQXBpQ2xpZW50Lmluc3RhbmNlO1xuICB9O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoYmFzZVBhdGg/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBhdG9tU3RvcmUgPSBnZXRBdG9tU3RvcmUoKTtcbiAgICBjb25zdCBiYXNlVXJsID0gYXRvbVN0b3JlLmdldChiYXNlVXJsQXRvbSk7XG4gICAgY29uc3QgcGF0aCA9IGJhc2VQYXRoIHx8IGJhc2VVcmw7XG4gICAgLy8gQVBJIEtleSBpcyBub3cgaGFuZGxlZCBhdCB0aGUgRW52aXZlQ29uZmlnUHJvdmlkZXIgbGV2ZWxcbiAgICBjb25zdCBjb25maWc6IENvbmZpZ3VyYXRpb24gPSBuZXcgQ29uZmlndXJhdGlvbih7XG4gICAgICBiYXNlUGF0aDogcGF0aCxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgIEFjY2VwdDogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRoaXMuZGVmYXVsdEFwaSA9IG5ldyBEZWZhdWx0QXBpKGNvbmZpZyk7XG4gICAgdGhpcy5pbmZlcmVuY2VBcGkgPSBuZXcgSW5mZXJlbmNlQXBpKGNvbmZpZyk7XG4gICAgdGhpcy5jdXN0b21lclNlcnZpY2VBcGkgPSBuZXcgQ3VzdG9tZXJTZXJ2aWNlQXBpKGNvbmZpZyk7XG4gIH1cblxuICBzdGF0aWMgcmVzb2x2ZVVybCA9IGFzeW5jICh1cmw6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IGF0b21TdG9yZSA9IGdldEF0b21TdG9yZSgpO1xuICAgIGNvbnN0IG9yZ1Nob3J0TmFtZSA9IGF0b21TdG9yZS5nZXQob3JnU2hvcnROYW1lQXRvbSk7XG4gICAgY29uc3Qgb3JnSWQgPSBhdG9tU3RvcmUuZ2V0KG9yZ0lkQXRvbSk7XG4gICAgY29uc3QgdXNlcklkID0gYXRvbVN0b3JlLmdldCh1c2VySWRBdG9tKTtcbiAgICBjb25zdCBjaGF0SWQgPSBhdG9tU3RvcmUuZ2V0KGNoYXRJZEF0b20pO1xuICAgIGNvbnN0IHNvdXJjZSA9IGF0b21TdG9yZS5nZXQoY29udGV4dFNvdXJjZUF0b20pO1xuICAgIGNvbnN0IGVudiA9IGF0b21TdG9yZS5nZXQoZW52QXRvbSk7XG5cbiAgICBjb25zdCBmZWF0dXJlRmxhZ1NlcnZpY2UgPSBhdG9tU3RvcmUuZ2V0KGZlYXR1cmVGbGFnU2VydmljZUF0b20pO1xuXG4gICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IHtcbiAgICAgIHVzZXJfaWQ6IHVzZXJJZCA/PyBcIlwiLFxuICAgICAgb3JnX2lkOiBvcmdJZCA/PyBcIlwiLFxuICAgICAgb3JnX3Nob3J0X25hbWU6IG9yZ1Nob3J0TmFtZSA/PyBcIlwiLFxuICAgICAgY2hhdF9pZDogY2hhdElkID8/IFwiXCIsXG4gICAgICBzb3VyY2U6IHNvdXJjZSA/PyBDb250ZXh0U291cmNlRW51bS5BcHAsXG4gICAgICBlbnY6IChlbnYgYXMgQ29udGV4dEVudkVudW0pID8/IENvbnRleHRFbnZFbnVtLkRldiwgLy8gQ2FzdCBlbnYgdG8gQ29udGV4dEVudkVudW1cbiAgICB9O1xuXG4gICAgY29uc3QgZmVhdHVyZUdhdGVzID1cbiAgICAgIGZlYXR1cmVGbGFnU2VydmljZT8uZmVhdHVyZUZsYWdTZXJ2aWNlPy5nZXRGZWF0dXJlRmxhZ3MoKSB8fCB7fTtcbiAgICBjb25zdCB1cmxSZXNvbHZpbmdSZXF1ZXN0ID0ge1xuICAgICAgdXJsLFxuICAgICAgY29udGV4dCxcbiAgICAgIGZlYXR1cmVfZ2F0ZXM6IGZlYXR1cmVHYXRlcyxcbiAgICB9O1xuXG4gICAgY29uc3QgcmF3UmVzcG9uc2UgPVxuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGkudjFVcmxSZXNvbHZpbmdQb3N0UmF3KHtcbiAgICAgICAgVXJsUmVzb2x2aW5nUmVxdWVzdDogdXJsUmVzb2x2aW5nUmVxdWVzdCxcbiAgICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2VCb2R5ID0gYXdhaXQgcmF3UmVzcG9uc2UucmF3Lmpzb24oKTtcblxuICAgIHJldHVybiByZXNwb25zZUJvZHk7XG4gIH07XG5cbiAgc3RhdGljIHJlcG9ydFNlc3Npb24gPSBhc3luYyAoXG4gICAgcmVwb3J0UmVxdWVzdDogUmVwb3J0U2Vzc2lvblJlcXVlc3RcbiAgKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxQ2hhdHNSZXBvcnRTZXNzaW9uSWRQb3N0KFxuICAgICAge1xuICAgICAgICBSZXBvcnRTZXNzaW9uUmVxdWVzdDogcmVwb3J0UmVxdWVzdCxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIHN0YXRpYyBnZXROZXh0UmVzcG9uc2VzID0gYXN5bmMgKFxuICAgIHBheWxvYWQ6IE5leHRNZXNzYWdlUmVxdWVzdFxuICApOiBQcm9taXNlPE1lc3NhZ2VbXT4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9XG4gICAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLnYxTmV4dFJlc3BvbnNlc1Bvc3Qoe1xuICAgICAgICAgIE5leHRNZXNzYWdlUmVxdWVzdDogbWVzc2FnZVJlcXVlc3RUb0NvbW1lcmNlTWVzc2FnZVJlcXVlc3QocGF5bG9hZCksXG4gICAgICAgIH0pO1xuICAgICAgY29uc3QgbWVzc2FnZXMgPSByZXNwb25zZVxuICAgICAgICAubWFwKChyZXNwKSA9PiB2YWxpZGF0ZVJlc3BvbnNlKHJlc3ApKVxuICAgICAgICAubWFwKChyZXNwKSA9PiBtZXNzYWdlRnJvbVJlc3BvbnNlKHJlc3ApKTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2VzLmZpbHRlcigobSk6IG0gaXMgTWVzc2FnZSA9PiBtICE9IG51bGwpO1xuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oXCJGYWlsZWQgdG8gZ2V0IG5leHQgcmVzcG9uc2VzXCIsIGVyciwge1xuICAgICAgICBwYXlsb2FkQ29udGV4dDogcGF5bG9hZD8uY29udGV4dCxcbiAgICAgICAgdXNlckV2ZW50czogcGF5bG9hZD8udXNlckV2ZW50cyxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoXCJGYWlsZWQgdG8gZ2V0IG5leHQgcmVzcG9uc2VzXCIsIGVycik7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBnZXROZXh0UmVzcG9uc2VTdHJlYW1pbmcgPSAoXG4gICAgcGF5bG9hZDogTmV4dE1lc3NhZ2VSZXF1ZXN0XG4gICk6IEFzeW5jR2VuZXJhdG9yPEFwaVJlc3BvbnNlLCB2b2lkLCB1bmtub3duPiA9PiB7XG4gICAgYXN5bmMgZnVuY3Rpb24qIGdlbmVyYXRlKFxuICAgICAgaW5mZXJlbmNlQXBpOiBJbmZlcmVuY2VBcGksXG4gICAgICBhYm9ydENvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlclxuICAgICkge1xuICAgICAgLy8gbWFrZSBzdXJlIHN0cmVhbWluZyBpcyBlbmFibGVkXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGluZmVyZW5jZUFwaS52MU5leHRSZXNwb25zZXNQb3N0UmF3KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIE5leHRNZXNzYWdlUmVxdWVzdDogbWVzc2FnZVJlcXVlc3RUb0NvbW1lcmNlTWVzc2FnZVJlcXVlc3QocGF5bG9hZCksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCB9XG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gUmVhZCB0aGUgcmVzcG9uc2UgYXMgYSBzdHJlYW0gb2YgZGF0YVxuICAgICAgICBpZiAoIXJlc3BvbnNlLnJhdy5ib2R5KSB7XG4gICAgICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFxuICAgICAgICAgICAgXCJbc3BpZmZ5LWFpXSBObyBib2R5IGluIHRoZSBzdHJlYW1lZCByZXNwb25zZVwiLFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2UucmF3LFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVhZGVyID0gcmVzcG9uc2UucmF3LmJvZHkuZ2V0UmVhZGVyKCk7XG4gICAgICAgIGNvbnN0IGRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoXCJ1dGYtOFwiKTtcblxuICAgICAgICBsZXQgcGFydGlhbCA9IFwiXCI7XG4gICAgICAgIC8vIFRPRE8gdGhpcyBmdW5jdGlvbiBpcyByZWNyZWF0ZWQgZXZlcnkgdGltZSBuZXcgZGF0YSBjb21lcyBmcm9tIHRoZSBzdHJlYW0gLSBkZWZpbmUgaXQgb3V0c2lkZSBvZiB0aGUgZ2VuZXJhdG9yXG4gICAgICAgIGNvbnN0IHNhZmVQYXJzZSA9IChsaW5lOiBzdHJpbmcpOiB1bmtub3duID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UobGluZSk7IC8vIFBhcnNlIHRoZSBKU09OIHN0cmluZ1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiW3NwaWZmeS1haV0gRXJyb3IgcGFyc2luZyBzdHJlYW1lZCBsaW5lXCIsIGVyciwge1xuICAgICAgICAgICAgICBsaW5lLFxuICAgICAgICAgICAgICBwYXJ0aWFsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBzd2FsbG93IHRoZSBlcnJvciBhbmQgc2V0IHRoZSBwYXJ0aWFsIHRvIG91ciBjdXJyZW50IGNodW5rXG4gICAgICAgICAgICBwYXJ0aWFsID0gbGluZTtcbiAgICAgICAgICAgIHJldHVybiBwYXJ0aWFsO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBUT0RPIHRoaXMgZnVuY3Rpb24gaXMgcmVjcmVhdGVkIGV2ZXJ5IHRpbWUgbmV3IGRhdGEgY29tZXMgZnJvbSB0aGUgc3RyZWFtIC0gZGVmaW5lIGl0IG91dHNpZGUgb2YgdGhlIGdlbmVyYXRvclxuICAgICAgICBjb25zdCBwcm9jZXNzQ2h1bmsgPSAoY2h1bms6IHN0cmluZyk6IHVua25vd25bXSA9PiB7XG4gICAgICAgICAgLy8gbWVyZ2UgdGhlIHBhcnRpYWwgd2l0aCB0aGUgaW5jb21pbmcgY2h1bmtcbiAgICAgICAgICBjb25zdCBsaW5lcyA9IGAke3BhcnRpYWx9JHtjaHVua31gLnNwbGl0KFwiXFxuXCIpO1xuXG4gICAgICAgICAgY29uc3QgcGFyc2VkTGluZXMgPSBsaW5lc1xuICAgICAgICAgICAgLm1hcCgobGluZSkgPT4gbGluZS5yZXBsYWNlKC9eZGF0YTogLywgXCJcIikudHJpbSgpKSAvLyBSZW1vdmUgdGhlIFwiZGF0YTogXCIgcHJlZml4XG4gICAgICAgICAgICAuZmlsdGVyKChsaW5lKSA9PiBsaW5lICE9PSBcIlwiICYmIGxpbmUgIT09IFwiW0RPTkVdXCIpIC8vIFJlbW92ZSBlbXB0eSBsaW5lcyBhbmQgXCJbRE9ORV1cIlxuICAgICAgICAgICAgLm1hcChzYWZlUGFyc2UpXG4gICAgICAgICAgICAuZmlsdGVyKCh2KSA9PiB2KTsgLy8gYW5kIGZpbHRlciBvdXQgdGhlIHVuZGVmaW5lZCB2YWx1ZXNcbiAgICAgICAgICByZXR1cm4gcGFyc2VkTGluZXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG5cbiAgICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTWFzc2FnZSBhbmQgcGFyc2UgdGhlIGNodW5rIG9mIGRhdGFcbiAgICAgICAgICBjb25zdCBjaHVuayA9IGRlY29kZXIuZGVjb2RlKHZhbHVlKTtcbiAgICAgICAgICBjb25zdCBwYXJzZWRMaW5lcyA9IHByb2Nlc3NDaHVuayhjaHVuayk7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHBhcnNlZExpbmUgb2YgcGFyc2VkTGluZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRlZFJlc3BvbnNlID0gdmFsaWRhdGVSZXNwb25zZShwYXJzZWRMaW5lKTtcblxuICAgICAgICAgICAgaWYgKHZhbGlkYXRlZFJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgIHlpZWxkIHZhbGlkYXRlZFJlc3BvbnNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFxuICAgICAgICAgIFwiW3NwaWZmeS1haV0gRmFpbGVkIHRvIGdldCBuZXh0IHN0cmVhbWluZyByZXNwb25zZXNcIixcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwYXlsb2FkQ29udGV4dDogcGF5bG9hZD8uY29udGV4dCxcbiAgICAgICAgICAgIHVzZXJFdmVudHM6IHBheWxvYWQ/LnVzZXJFdmVudHMsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcbiAgICAgICAgICBcIkZhaWxlZCB0byBnZXQgbmV4dCBzdHJlYW1pbmcgcmVzcG9uc2VzXCIsXG4gICAgICAgICAgZXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLnJlc3BvbnNlc0Fib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkucmVzcG9uc2VzQWJvcnRDb250cm9sbGVyID1cbiAgICAgIG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgIHJldHVybiBnZW5lcmF0ZShcbiAgICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLFxuICAgICAgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5yZXNwb25zZXNBYm9ydENvbnRyb2xsZXJcbiAgICApO1xuICB9O1xuXG4gIHN0YXRpYyBnZXROZXh0U3VnZ2VzdGlvbnMgPSBhc3luYyAoXG4gICAgcGF5bG9hZDogTmV4dE1lc3NhZ2VSZXF1ZXN0XG4gICk6IFByb21pc2U8U3VnZ2VzdGlvbltdPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuc3VnZ2VzdGlvbnNBYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuc3VnZ2VzdGlvbnNBYm9ydENvbnRyb2xsZXIgPVxuICAgICAgICBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5pbmZlcmVuY2VBcGkudjFOZXh0U3VnZ2VzdGlvbnNQb3N0KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIE5leHRNZXNzYWdlUmVxdWVzdDogbWVzc2FnZVJlcXVlc3RUb0NvbW1lcmNlTWVzc2FnZVJlcXVlc3QocGF5bG9hZCksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzaWduYWw6XG4gICAgICAgICAgICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuc3VnZ2VzdGlvbnNBYm9ydENvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgICAgY29uc3Qgc3VnZ2VzdGlvbnMgPSByZXNwb25zZVxuICAgICAgICAubWFwKChyZXNwKSA9PiB2YWxpZGF0ZVN1Z2dlc3Rpb24ocmVzcCkpXG4gICAgICAgIC5maWx0ZXIoKHN1Z2dlc3Rpb24pOiBzdWdnZXN0aW9uIGlzIFN1Z2dlc3Rpb24gPT4gc3VnZ2VzdGlvbiAhPSBudWxsKTtcblxuICAgICAgcmV0dXJuIHN1Z2dlc3Rpb25zO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBMb2dnZXIubG9nSW5mbyhcIkZhaWxlZCB0byBnZXQgc3VnZ2VzdGlvbnNcIiwgZXJyb3IsIHtcbiAgICAgICAgcGF5bG9hZENvbnRleHQ6IHBheWxvYWQ/LmNvbnRleHQsXG4gICAgICAgIHVzZXJFdmVudHM6IHBheWxvYWQ/LnVzZXJFdmVudHMsXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgdGhyb3dTZXNzaW9uUmVzdGFydFJlcXVpcmVkSWYoXCJGYWlsZWQgdG8gZ2V0IHN1Z2dlc3Rpb25zXCIsIGVycm9yKTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIGV4aXN0aW5nIGNoYXQgZGF0YSBmb3IgYSBnaXZlbiBzZXNzaW9uIGFuZCB0cmFuc2Zvcm1zIHRoZW0gdG8gcmVjb25zdHJ1Y3QgdGhlIGNoYXQgaGlzdG9yeS5cbiAgICpcbiAgICogQHBhcmFtIG9yZ0lkIFRoZSBvcmdhbml6YXRpb24gSWRcbiAgICogQHBhcmFtIGNoYXRJZCBUaGUgZXhpc3RpbmcgY2hhdCBJZFxuICAgKiBAcGFyYW0gdXNlcklkIFRoZSB1c2VyIElkXG4gICAqXG4gICAqIEByZXR1cm5zIEEgbGlzdCBvZiBtZXNzYWdlcyB0aGF0IHdlcmUgZXhjaGFuZ2VkIGluIHRoZSBjaGF0LCB0aHJvd3MgYW4gZXJyb3IgaWYgdGhlIGNoYXQgc2Vzc2lvbiBoYXMgZXhwaXJlZC5cbiAgICovXG4gIHN0YXRpYyBnZXRSZXNwb25zZXMgPSBhc3luYyAoXG4gICAgb3JnSWQ6IHN0cmluZyxcbiAgICBjaGF0SWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPHtcbiAgICByZXNwb25zZXM6IEFwaVJlc3BvbnNlW11bXTtcbiAgICB1c2VyRXZlbnRzOiBVc2VyRXZlbnRbXTtcbiAgICBzdWdnZXN0aW9uczogU3VnZ2VzdGlvbltdO1xuICAgIG1lc3NhZ2VzOiBNZXNzYWdlW11bXTtcbiAgfT4gPT4ge1xuICAgIGxldCBkYXRhOiBWMUdldFNlc3Npb25NZXNzYWdlczIwMFJlc3BvbnNlID0ge1xuICAgICAgcmVzcG9uc2VzOiBbXSxcbiAgICAgIHN1Z2dlc3Rpb25zOiBbXSxcbiAgICAgIHVzZXJfZXZlbnRzOiBbXSxcbiAgICB9O1xuICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICBvcmdfaWQ6IG9yZ0lkLFxuICAgICAgY2hhdF9pZDogY2hhdElkLFxuICAgICAgdXNlcl9pZDogdXNlcklkLFxuICAgIH07XG4gICAgdHJ5IHtcbiAgICAgIGRhdGEgPVxuICAgICAgICBhd2FpdCBDb21tZXJjZUFwaUNsaWVudC5nZXRJbnN0YW5jZSgpLmRlZmF1bHRBcGkudjFHZXRTZXNzaW9uTWVzc2FnZXMoXG4gICAgICAgICAgcmVxdWVzdFxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBhd2FpdCB0aHJvd1Nlc3Npb25SZXN0YXJ0UmVxdWlyZWRJZihcbiAgICAgICAgXCJGYWlsZWQgdG8gZ2V0IGNoYXQgcmVzcG9uc2VzXCIsXG4gICAgICAgIGVycm9yXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlczogQXBpUmVzcG9uc2VbXVtdID0gZGF0YT8ucmVzcG9uc2VzPy5tYXAoKHR1cm4pID0+XG4gICAgICB0dXJuXG4gICAgICAgIC5tYXAoKHJlc3BvbnNlKSA9PiB2YWxpZGF0ZVJlc3BvbnNlKHJlc3BvbnNlKSlcbiAgICAgICAgLmZpbHRlcigocmVzcG9uc2UpOiByZXNwb25zZSBpcyBBcGlSZXNwb25zZSA9PiByZXNwb25zZSAhPSBudWxsKVxuICAgICk7XG5cbiAgICBjb25zdCBzdWdnZXN0aW9uczogU3VnZ2VzdGlvbltdID0gZGF0YT8uc3VnZ2VzdGlvbnNcbiAgICAgIC5tYXAoKHN1Z2dlc3Rpb24pID0+IHZhbGlkYXRlU3VnZ2VzdGlvbihzdWdnZXN0aW9uKSlcbiAgICAgIC5maWx0ZXIoKHN1Z2dlc3Rpb24pOiBzdWdnZXN0aW9uIGlzIFN1Z2dlc3Rpb24gPT4gc3VnZ2VzdGlvbiAhPSBudWxsKTtcblxuICAgIGNvbnN0IHVzZXJFdmVudHM6IFVzZXJFdmVudFtdID0gZGF0YT8udXNlcl9ldmVudHNcbiAgICAgIC5tYXAoKGV2ZW50KSA9PiB2YWxpZGF0ZVVzZXJFdmVudChldmVudCkpXG4gICAgICAuZmlsdGVyKChldmVudCk6IGV2ZW50IGlzIFVzZXJFdmVudCA9PiBldmVudCAhPSBudWxsKTtcblxuICAgIC8vIGlmIGEgZm9ybSBoYXMgYWxyZWFkeSBiZWVuIHN1Ym1pdHRlZCwgZG9uJ3Qgc2hvdyBpdCBpbiB0aGUgY2hhdCBoaXN0b3J5XG4gICAgY29uc3QgZm9ybVN1Ym1pdHRlZFVzZXJFdmVudHNGb3JtSWRzID0gdXNlckV2ZW50c1xuICAgICAgLmZpbHRlcigoZXZlbnQpID0+IGV2ZW50LmNhdGVnb3J5ID09PSBVc2VyRXZlbnRDYXRlZ29yeS5Gb3JtU3VibWl0dGVkKVxuICAgICAgLm1hcCgoZXZlbnQpID0+IGV2ZW50LmF0dHJpYnV0ZXMuZm9ybVJlc3BvbnNlSWQpO1xuXG4gICAgY29uc3QgYXNzaXN0YW50TWVzc2FnZXM6IE1lc3NhZ2VbXVtdID0gcmVzcG9uc2VzXG4gICAgICAubWFwKCh0dXJuKSA9PlxuICAgICAgICB0dXJuXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChyZXNwb25zZSkgPT5cbiAgICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgICByZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5Gb3JtICYmXG4gICAgICAgICAgICAgICAgZm9ybVN1Ym1pdHRlZFVzZXJFdmVudHNGb3JtSWRzLmluY2x1ZGVzKHJlc3BvbnNlLmlkKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5tYXAoKHJlc3BvbnNlKSA9PiBtZXNzYWdlRnJvbVJlc3BvbnNlKHJlc3BvbnNlKSlcbiAgICAgICAgICAuZmlsdGVyKChtZXNzYWdlKTogbWVzc2FnZSBpcyBNZXNzYWdlID0+IG1lc3NhZ2UgIT0gbnVsbClcbiAgICAgIClcbiAgICAgIC5maWx0ZXIoKHR1cm4pID0+IHR1cm4ubGVuZ3RoID4gMCk7XG5cbiAgICBjb25zdCB1c2VyTWVzc2FnZXM6IE1lc3NhZ2VbXVtdID0gdXNlckV2ZW50c1xuICAgICAgLm1hcCgoZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIFtVc2VyRXZlbnRDYXRlZ29yeS5RdWVyeVR5cGVkLCBVc2VyRXZlbnRDYXRlZ29yeS5TZWFyY2hdLmluY2x1ZGVzKFxuICAgICAgICAgICAgZXZlbnQuY2F0ZWdvcnlcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBbbWVzc2FnZUZyb21RdWVyeUV2ZW50KGV2ZW50KV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuY2F0ZWdvcnkgPT09IFVzZXJFdmVudENhdGVnb3J5LlN1Z2dlc3Rpb25DbGlja2VkKSB7XG4gICAgICAgICAgcmV0dXJuIFttZXNzYWdlRnJvbVN1Z2dlc3Rpb25FdmVudChldmVudCwgc3VnZ2VzdGlvbnMpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC5jYXRlZ29yeSA9PT0gVXNlckV2ZW50Q2F0ZWdvcnkuRm9ybVN1Ym1pdHRlZCkge1xuICAgICAgICAgIGNvbnN0IGZvcm1SZXNwb25zZSA9IHJlc3BvbnNlc1xuICAgICAgICAgICAgLmZsYXQoKVxuICAgICAgICAgICAgLmZpbmQoXG4gICAgICAgICAgICAgIChyZXNwb25zZSkgPT5cbiAgICAgICAgICAgICAgICByZXNwb25zZS5pZCA9PT0gZXZlbnQuYXR0cmlidXRlcy5mb3JtUmVzcG9uc2VJZCAmJlxuICAgICAgICAgICAgICAgIGV2ZW50LmF0dHJpYnV0ZXMuZm9ybVR5cGUgIT09IEZvcm1UeXBlLkVzY2FsYXRpb25cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAoZm9ybVJlc3BvbnNlICYmIGZvcm1SZXNwb25zZS5jYXRlZ29yeSA9PT0gUmVzcG9uc2VDYXRlZ29yeS5Gb3JtKSB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICBtZXNzYWdlRnJvbUZvcm1TdWJtaXR0ZWRFdmVudChldmVudCwgZm9ybVJlc3BvbnNlLmF0dHJpYnV0ZXMpLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW107XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigobWVzc2FnZSk6IG1lc3NhZ2UgaXMgTWVzc2FnZVtdID0+IG1lc3NhZ2UubGVuZ3RoID4gMCk7XG5cbiAgICAvLyBTb3J0IHRoZSBtZXNzYWdlcyBjaHJvbm9sb2dpY2FsbHkgdG8gcmVjb25zdHJ1Y3QgdGhlIGNoYXQgaGlzdG9yeVxuICAgIGNvbnN0IHNvcnRlZE1lc3NhZ2VzID0gWy4uLmFzc2lzdGFudE1lc3NhZ2VzLCAuLi51c2VyTWVzc2FnZXNdLnNvcnQoXG4gICAgICAoYSwgYikgPT5cbiAgICAgICAgbmV3IERhdGUoYVswXS5jcmVhdGVkQXQpLmdldFRpbWUoKSAtIG5ldyBEYXRlKGJbMF0uY3JlYXRlZEF0KS5nZXRUaW1lKClcbiAgICApO1xuXG4gICAgcmV0dXJuIHsgcmVzcG9uc2VzLCB1c2VyRXZlbnRzLCBzdWdnZXN0aW9ucywgbWVzc2FnZXM6IHNvcnRlZE1lc3NhZ2VzIH07XG4gIH07XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBwYXlsb2FkXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBzdGF0aWMgaXNTdXBwb3J0ZWRFdmVudCA9IGFzeW5jIChcbiAgICBwYXlsb2FkOiBTdXBwb3J0ZWRFdmVudFJlcXVlc3RcbiAgKTogUHJvbWlzZTxTdXBwb3J0ZWRFdmVudD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByYXdSZXNwb25zZSA9XG4gICAgICAgIGF3YWl0IENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuaW5mZXJlbmNlQXBpLnYxU3VwcG9ydGVkRXZlbnRQb3N0UmF3KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIFN1cHBvcnRlZEV2ZW50UmVxdWVzdDpcbiAgICAgICAgICAgICAgY29yZVN1cHBvcnRlZEV2ZW50UmVxdWVzdFRvQXBpUmVxdWVzdChwYXlsb2FkKSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG5cbiAgICAgIC8vIEdldCB0aGUgYWN0dWFsIEhUVFAgcmVzcG9uc2UgSlNPTlxuICAgICAgY29uc3QgaHR0cFJlc3BvbnNlVGV4dCA9IGF3YWl0IHJhd1Jlc3BvbnNlLnJhdy50ZXh0KCk7XG4gICAgICBjb25zdCBodHRwUmVzcG9uc2VKc29uID0gSlNPTi5wYXJzZShodHRwUmVzcG9uc2VUZXh0KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaHR0cFJlc3BvbnNlSnNvbixcbiAgICAgICAgbnVtYmVyT2ZSZXZpZXdzOiBodHRwUmVzcG9uc2VKc29uLm51bV9vZl9yZXZpZXdzLFxuICAgICAgICBtZXJjaGFudF90YWdzOiBodHRwUmVzcG9uc2VKc29uLm1lcmNoYW50X3RhZ3MgfHwgW10sXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiRmFpbGVkIHRvIGdldCByZXNwb25zZSBmb3IgdjFTdXBwb3J0ZWRFdmVudFBvc3RcIiwge1xuICAgICAgICBlcnIsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN1cHBvcnRlZDogZmFsc2UsXG4gICAgICAgIHJlYWR5OiBmYWxzZSxcbiAgICAgICAgY2F0ZWdvcnk6IHVuZGVmaW5lZCxcbiAgICAgICAgY29sbGVjdGlvbnM6IFtdLFxuICAgICAgICBudW1iZXJPZlJldmlld3M6IHVuZGVmaW5lZCxcbiAgICAgICAgdG9wX2NhdGVnb3J5OiB1bmRlZmluZWQsXG4gICAgICAgIG1lcmNoYW50X3RhZ3M6IFtdLFxuICAgICAgfTtcbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGlkZW50aWZ5VXNlciA9IGFzeW5jIChcbiAgICBzcGlmZnlVc2VySWQ6IHN0cmluZyxcbiAgICBtZXJjaGFudFVzZXJJZDogc3RyaW5nLFxuICAgIHVhRGV0YWlsczogQ2xpZW50RGV0YWlsc1xuICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxQW5hbHl0aWNzSWRlbnRpZnlQb3N0KHtcbiAgICAgICAgQW5hbHl0aWNzSWRlbnRpZnlSZXF1ZXN0OiB7XG4gICAgICAgICAgdXNlcl9pZDogc3BpZmZ5VXNlcklkLFxuICAgICAgICAgIG9zX25hbWU6IHVhRGV0YWlscy5vcyxcbiAgICAgICAgICBvc192ZXJzaW9uOiB1YURldGFpbHMub3NWZXJzaW9uLFxuICAgICAgICAgIHBsYXRmb3JtOiB1YURldGFpbHMub3MsXG4gICAgICAgICAgZGV2aWNlX2lkOiB1YURldGFpbHMuZGV2aWNlTW9kZWwsXG4gICAgICAgICAgZGV2aWNlX2JyYW5kOiB1YURldGFpbHMuZGV2aWNlQnJhbmQsXG4gICAgICAgICAgZGV2aWNlX21hbnVmYWN0dXJlcjogdWFEZXRhaWxzLmRldmljZU1hbnVmYWN0dXJlcixcbiAgICAgICAgICBkZXZpY2VfbW9kZWw6IHVhRGV0YWlscy5kZXZpY2VNb2RlbCxcbiAgICAgICAgICB1c2VyX3Byb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIGNkcF91c2VyX2lkOiBtZXJjaGFudFVzZXJJZCxcbiAgICAgICAgICAgIGJyb3dzZXI6IHVhRGV0YWlscy5icm93c2VyLFxuICAgICAgICAgICAgYnJvd3Nlcl92ZXJzaW9uOiB1YURldGFpbHMuYnJvd3NlclZlcnNpb24sXG4gICAgICAgICAgICB1c2VyX2FnZW50OiB1YURldGFpbHMudXNlckFnZW50LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIExvZ2dlci5sb2dFcnJvcihcIkZhaWxlZCB0byBpZGVudGlmeSB1c2VyXCIsIGVycik7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgc3RhdGljIG1hcENvbnRleHRTb3VyY2VUb1YxT3JnQ29uZmlnR2V0U291cmNlID0gKFxuICAgIHNvdXJjZTogQ29udGV4dFNvdXJjZUVudW0gfCB1bmRlZmluZWRcbiAgKTogVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtIHwgdW5kZWZpbmVkID0+IHtcbiAgICBpZiAoc291cmNlID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgc3dpdGNoIChzb3VyY2UpIHtcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uRm9yazpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5Gb3JrO1xuICAgICAgY2FzZSBDb250ZXh0U291cmNlRW51bS5QbGF5Z3JvdW5kOlxuICAgICAgICByZXR1cm4gVjFPcmdDb25maWdHZXRTb3VyY2VFbnVtLlBsYXlncm91bmQ7XG4gICAgICBjYXNlIENvbnRleHRTb3VyY2VFbnVtLkFwcDpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5BcHA7XG4gICAgICBjYXNlIENvbnRleHRTb3VyY2VFbnVtLlRlc3Q6XG4gICAgICAgIHJldHVybiBWMU9yZ0NvbmZpZ0dldFNvdXJjZUVudW0uVGVzdDtcbiAgICAgIGNhc2UgQ29udGV4dFNvdXJjZUVudW0uRXZhbDpcbiAgICAgICAgcmV0dXJuIFYxT3JnQ29uZmlnR2V0U291cmNlRW51bS5UZXN0O1xuICAgICAgZGVmYXVsdDoge1xuICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhhdCBpZiBuZXcgdmFsdWVzIGFyZSBhZGRlZCB0byBDb250ZXh0U291cmNlRW51bSwgd2UgY2F0Y2ggaXRcbiAgICAgICAgY29uc3QgZXhoYXVzdGl2ZUNoZWNrOiBuZXZlciA9IHNvdXJjZTtcbiAgICAgICAgcmV0dXJuIGV4aGF1c3RpdmVDaGVjaztcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgc3RhdGljIGdldE9yZ0NvbmZpZyA9IGFzeW5jIChcbiAgICB1c2VyX2lkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxPcmdDb25maWcgfCB1bmRlZmluZWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYXRvbVN0b3JlID0gZ2V0QXRvbVN0b3JlKCk7XG4gICAgICBjb25zdCByZWFjdEFwcE5hbWUgPSBhdG9tU3RvcmUuZ2V0KHJlYWN0QXBwTmFtZUF0b20pO1xuICAgICAgY29uc3QgY29udGV4dFNvdXJjZSA9IGF0b21TdG9yZS5nZXQoY29udGV4dFNvdXJjZUF0b20pO1xuICAgICAgY29uc3QgZmVhdHVyZUZsYWdTZXJ2aWNlID0gYXRvbVN0b3JlLmdldChmZWF0dXJlRmxhZ1NlcnZpY2VBdG9tKTsgLy8gR2V0IGZlYXR1cmVGbGFnU2VydmljZVxuICAgICAgY29uc3QgcmVxdWVzdDogVjFPcmdDb25maWdHZXRSZXF1ZXN0ID0ge1xuICAgICAgICBuYW1lc3BhY2U6IHJlYWN0QXBwTmFtZSxcbiAgICAgICAgdXNlcl9pZCxcbiAgICAgICAgc291cmNlOiB0aGlzLm1hcENvbnRleHRTb3VyY2VUb1YxT3JnQ29uZmlnR2V0U291cmNlKGNvbnRleHRTb3VyY2UpLFxuICAgICAgICBpbmNsdWRlX2V4cGVyaW1lbnRzOiBPYmplY3QudmFsdWVzKFByb2R1Y3RFeHBlcmltZW50KSxcbiAgICAgICAgaW5jbHVkZV9mZWF0dXJlX2dhdGVzOiBPYmplY3QuZW50cmllcyhcbiAgICAgICAgICBmZWF0dXJlRmxhZ1NlcnZpY2U/LmZlYXR1cmVGbGFnU2VydmljZT8uZ2V0RmVhdHVyZUZsYWdzKCkgfHwge31cbiAgICAgICAgKVxuICAgICAgICAgIC5maWx0ZXIoKFssIGlzRW5hYmxlZF0pID0+IGlzRW5hYmxlZClcbiAgICAgICAgICAubWFwKChbZmVhdHVyZUdhdGVOYW1lXSkgPT4gZmVhdHVyZUdhdGVOYW1lKSwgLy8gVXNlIGZlYXR1cmVGbGFnU2VydmljZVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID1cbiAgICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5kZWZhdWx0QXBpLnYxT3JnQ29uZmlnR2V0KFxuICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgKTtcblxuICAgICAgcmV0dXJuIHZhbGlkYXRlT3JnQ29uZmlnUmVzdWx0cyhyZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBMb2dnZXIubG9nRXJyb3IoYEZhaWxlZCB0byBnZXQgb3JnIGNvbmZpZ2AsIGVyciwgeyBlcnIgfSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfTtcblxuICBzdGF0aWMgYWRkTm90ZVRvTGF0ZXN0Q29udmVyc2F0aW9uID0gYXN5bmMgKFxuICAgIHNwaWZmeVVzZXJJZDogc3RyaW5nLFxuICAgIGVtYWlsOiBzdHJpbmcsXG4gICAgY3VzdG9tZXJTZXJ2aWNlUHJvdmlkZXI6IEN1c3RvbWVyU2VydmljZVByb3ZpZGVyXG4gICkgPT4ge1xuICAgIExvZ2dlci5sb2dJbmZvKFxuICAgICAgYGFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvbiAtIHVzZXJfaWQ9JHtzcGlmZnlVc2VySWR9IGVtYWlsPSR7ZW1haWx9IGN1c3RvbWVyX3NlcnZpY2VfcHJvdmlkZXI9JHtjdXN0b21lclNlcnZpY2VQcm92aWRlcn1gXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuZ2V0SW5zdGFuY2UoKS5jdXN0b21lclNlcnZpY2VBcGkudjFDdXN0c2VydmljZUFkZE5vdGVUb0xhdGVzdENvbnZlcnNhdGlvblBvc3QoXG4gICAgICAgIHtcbiAgICAgICAgICBBZGROb3RlVG9MYXRlc3RDb252ZXJzYXRpb25SZXF1ZXN0OiB7XG4gICAgICAgICAgICBzcGlmZnlfdXNlcl9pZDogc3BpZmZ5VXNlcklkLFxuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgICBjdXN0b21lcl9zZXJ2aWNlX3Byb3ZpZGVyOiBjdXN0b21lclNlcnZpY2VQcm92aWRlcixcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKFwiRmFpbGVkIHRvIGFkZCBub3RlIHRvIGxhdGVzdCBjb252ZXJzYXRpb25cIiwgeyBlcnIgfSk7XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBnZXRDdXN0b21lclNlcnZpY2VBcGkgPSAoKSA9PlxuICAgIENvbW1lcmNlQXBpQ2xpZW50LmdldEluc3RhbmNlKCkuY3VzdG9tZXJTZXJ2aWNlQXBpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDb21tZXJjZUFwaUNsaWVudDtcbiIsImltcG9ydCBSZWFjdCwgeyBjcmVhdGVDb250ZXh0LCB1c2VDYWxsYmFjaywgdXNlQ29udGV4dCwgdXNlTWVtbywgdXNlU3RhdGUsIHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBVQVBhcnNlciBmcm9tICd1YS1wYXJzZXItanMnO1xuaW1wb3J0IHsgQ2xpZW50RGV0YWlscywgVXNlcklkZW50aXR5Q29udGV4dFR5cGUgfSBmcm9tICdAZW52aXZlLWFpL3R5cGVzJztcbmltcG9ydCBMb2dnZXIgZnJvbSAnLi4vLi4vYXBwbGljYXRpb24vbG9nZ2luZy9sb2dnZXInO1xuaW1wb3J0IENvbW1lcmNlQXBpQ2xpZW50IGZyb20gJy4uLy4uL2FwcGxpY2F0aW9uL2NvbW1lcmNlLWFwaSc7XG5pbXBvcnQgeyB1c2VMb2NhbFN0b3JhZ2UgfSBmcm9tICcuLi9sb2NhbFN0b3JhZ2VDb250ZXh0JztcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tICd1dWlkJztcblxuaW1wb3J0IHsgdXNlU2V0QXRvbSB9IGZyb20gXCJqb3RhaVwiO1xuaW1wb3J0IHsgdXNlcklkQXRvbSB9IGZyb20gXCJzcmMvYXRvbXMvYXBwXCI7XG5cbi8vIEhlbHBlciBmdW5jdGlvbiBmcm9tIHRoZSBvcmlnaW5hbCBzZXJ2aWNlXG5jb25zdCBnZXRVc2VyQWdlbnREZXRhaWxzID0gKCk6IENsaWVudERldGFpbHMgPT4ge1xuICBjb25zdCB1YVBhcnNlciA9IG5ldyBVQVBhcnNlcigpO1xuICBjb25zdCByZXN1bHQgPSB1YVBhcnNlci5nZXRSZXN1bHQoKTtcblxuICByZXR1cm4ge1xuICAgIG9zOiByZXN1bHQ/Lm9zPy5uYW1lLFxuICAgIG9zVmVyc2lvbjogcmVzdWx0Py5vcz8udmVyc2lvbixcbiAgICBkZXZpY2VCcmFuZDogcmVzdWx0Py5kZXZpY2U/LnZlbmRvcixcbiAgICBkZXZpY2VNYW51ZmFjdHVyZXI6IHJlc3VsdD8uZGV2aWNlPy52ZW5kb3IsXG4gICAgZGV2aWNlTW9kZWw6IHJlc3VsdD8uZGV2aWNlPy5tb2RlbCxcbiAgICBicm93c2VyOiByZXN1bHQ/LmJyb3dzZXI/Lm5hbWUsXG4gICAgYnJvd3NlclZlcnNpb246IHJlc3VsdD8uYnJvd3Nlcj8udmVyc2lvbixcbiAgICB1c2VyQWdlbnQ6IHJlc3VsdD8udWEsXG4gIH07XG59O1xuXG5jb25zdCBVc2VySWRlbnRpdHlDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxVc2VySWRlbnRpdHlDb250ZXh0VHlwZSB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuZXhwb3J0IGNvbnN0IFVzZXJJZGVudGl0eVByb3ZpZGVyOiBSZWFjdC5GQzx7IGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGUgfT4gPSAoeyBjaGlsZHJlbiB9KSA9PiB7XG4gIGNvbnN0IHsgZ2V0SXRlbSwgc2V0SXRlbSwgaXNBdmFpbGFibGU6IGxvY2FsU3RvcmFnZUlzUmVhZHkgfSA9IHVzZUxvY2FsU3RvcmFnZSgpO1xuXG4gIGNvbnN0IFtpc1JlYWR5LCBzZXRJc1JlYWR5XSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIC8vIEFzc3VtaW5nIENvbW1lcmNlQXBpQ2xpZW50IGFuZCBvdGhlciBkZXBlbmRlbmNpZXMgYXJlIHJlYWR5IGlmIGxvY2FsU3RvcmFnZSBpcy5cbiAgICAvLyBJbiBhIG1vcmUgY29tcGxleCBzY2VuYXJpbywgeW91IG1pZ2h0IGhhdmUgbW9yZSBjaGVja3MgaGVyZS5cbiAgICBzZXRJc1JlYWR5KGxvY2FsU3RvcmFnZUlzUmVhZHkpO1xuICB9LCBbbG9jYWxTdG9yYWdlSXNSZWFkeV0pO1xuXG4gIGNvbnN0IFVTRVJfSURfT1ZFUlJJREVfS0VZID0gJ3YxLXNwaWZmeS11c2VyLWlkLW92ZXJyaWRlJztcbiAgY29uc3QgVVNFUl9JRF9ERUZBVUxUX0tFWSA9ICd2MS1zcGlmZnktdXNlci1pZC1kZWZhdWx0JztcblxuICBjb25zdCBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAoKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IGdldEl0ZW0oVVNFUl9JRF9PVkVSUklERV9LRVkpID8/IHVuZGVmaW5lZCxcbiAgICBbZ2V0SXRlbV0sXG4gICk7XG5cbiAgY29uc3QgZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAoKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IGdldEl0ZW0oVVNFUl9JRF9ERUZBVUxUX0tFWSkgPz8gdW5kZWZpbmVkLFxuICAgIFtnZXRJdGVtXSxcbiAgKTtcblxuICBjb25zdCBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgTG9nZ2VyLmxvZ0luZm8oYHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSAtIFNldHRpbmcgdXNlcl9pZD0ke3VzZXJJZH1gKTtcbiAgICAgIHNldEl0ZW0oVVNFUl9JRF9ERUZBVUxUX0tFWSwgdXNlcklkKTtcbiAgICAgIC8vIHdpbmRvdy5kaXNwYXRjaEV2ZW50IGlzIGhhbmRsZWQgYnkgdXNlTG9jYWxTdG9yYWdlIG5vd1xuICAgICAgcmV0dXJuIHVzZXJJZDtcbiAgICB9LFxuICAgIFtzZXRJdGVtLCBVU0VSX0lEX0RFRkFVTFRfS0VZXSxcbiAgKTtcblxuICBjb25zdCBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKHVzZXJJZDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgIExvZ2dlci5sb2dJbmZvKGBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlIC0gU2V0dGluZyB1c2VyX2lkPSR7dXNlcklkfWApO1xuICAgICAgc2V0SXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSwgdXNlcklkKTtcbiAgICAgIC8vIHdpbmRvdy5kaXNwYXRjaEV2ZW50IGlzIGhhbmRsZWQgYnkgdXNlTG9jYWxTdG9yYWdlIG5vd1xuICAgICAgcmV0dXJuIHVzZXJJZDtcbiAgICB9LFxuICAgIFtzZXRJdGVtLCBVU0VSX0lEX09WRVJSSURFX0tFWV0sXG4gICk7XG5cbiAgY29uc3QgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIExvZ2dlci5sb2dJbmZvKGBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UgLSBDbGVhcmluZyB1c2VyX2lkYCk7XG4gICAgLy8gTG9jYWxTdG9yYWdlU2VydmljZS5nZXRMb2NhbFN0b3JhZ2UoKT8ucmVtb3ZlSXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSk7XG4gICAgLy8gd2luZG93LmRpc3BhdGNoRXZlbnQgaXMgaGFuZGxlZCBieSB1c2VMb2NhbFN0b3JhZ2Ugbm93XG4gICAgc2V0SXRlbShVU0VSX0lEX09WRVJSSURFX0tFWSwgJycpOyAvLyBTZXQgdG8gZW1wdHkgc3RyaW5nIHRvIGNsZWFyXG4gIH0sIFtzZXRJdGVtLCBVU0VSX0lEX09WRVJSSURFX0tFWV0pO1xuXG4gIGNvbnN0IGdldFVzZXJJZE9yRGVmYXVsdCA9IHVzZUNhbGxiYWNrKCgpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IHVzZXJJZE92ZXJyaWRlID0gZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlKCk7XG4gICAgaWYgKHVzZXJJZE92ZXJyaWRlKSB7XG4gICAgICByZXR1cm4gdXNlcklkT3ZlcnJpZGU7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdFVzZXJJZCA9IGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlKCk7XG4gICAgaWYgKGRlZmF1bHRVc2VySWQpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0VXNlcklkO1xuICAgIH1cblxuICAgIHJldHVybiBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UoYHNwaWZmeS11c2VyLWlkLSR7dXVpZCgpfWApO1xuICB9LCBbXG4gICAgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlLFxuICAgIGdldFVzZXJJZERlZmF1bHRGcm9tTG9jYWxTdG9yYWdlLFxuICAgIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSxcbiAgXSk7XG5cbiAgY29uc3QgaWRlbnRpZnlVc2VyID0gdXNlQ2FsbGJhY2soYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmICghaXNSZWFkeSkge1xuICAgICAgTG9nZ2VyLmxvZ1dhcm4oJ1tVc2VySWRlbnRpdHlDb250ZXh0XSBDb250ZXh0IG5vdCByZWFkeSwgc2tpcHBpbmcgaWRlbnRpZnlVc2VyJywgdW5kZWZpbmVkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8gVGVtcG9yYXJpbHkgY29tbWVudGVkIG91dCB1bnRpbCBXaW5kb3dEYXRhTGF5ZXJTZXJ2aWNlIGlzIHJlc29sdmVkXG4gICAgICAvLyBjb25zdCBjZHBVc2VySWQgPSBXaW5kb3dEYXRhTGF5ZXJTZXJ2aWNlLmdldEdvb2dsZUFuYWx5dGljc0NsaWVudElkKCk7XG4gICAgICBjb25zdCBjZHBVc2VySWQgPSAnVU5LTk9XTl9DRFBfVVNFUl9JRCc7IC8vIFBsYWNlaG9sZGVyXG4gICAgICBjb25zdCB1c2VySWQgPSBnZXRVc2VySWRPckRlZmF1bHQoKTtcbiAgICAgIGNvbnN0IHVzZXJBZ2VudERldGFpbHMgPSBnZXRVc2VyQWdlbnREZXRhaWxzKCk7XG5cbiAgICAgIGlmICghY2RwVXNlcklkKSB7XG4gICAgICAgIExvZ2dlci5sb2dXYXJuKCdbc3BpZmZ5LWFpXSBObyBHQSBDbGllbnQgSUQgZm91bmQsIHNraXBwaW5nIGlkZW50aWZ5VXNlcicsIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgQ29tbWVyY2VBcGlDbGllbnQuaWRlbnRpZnlVc2VyKHVzZXJJZCwgY2RwVXNlcklkLCB1c2VyQWdlbnREZXRhaWxzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgTG9nZ2VyLmxvZ0Vycm9yKCdbc3BpZmZ5LWFpXSBFcnJvciBpZGVudGlmeWluZyB1c2VyJywgZXJyb3IpO1xuICAgIH1cbiAgfSwgW2lzUmVhZHksIGdldFVzZXJJZE9yRGVmYXVsdF0pO1xuXG4gIGNvbnN0IHZhbHVlID0gdXNlTWVtbyhcbiAgICAoKSA9PiAoe1xuICAgICAgaWRlbnRpZnlVc2VyLFxuICAgICAgZ2V0VXNlcklkT3JEZWZhdWx0LFxuICAgICAgZ2V0VXNlcklkT3ZlcnJpZGVGcm9tTG9jYWxTdG9yYWdlLFxuICAgICAgZ2V0VXNlcklkRGVmYXVsdEZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgICBzZXRVc2VySWREZWZhdWx0SW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBzZXRVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlLFxuICAgICAgY2xlYXJVc2VySWRPdmVycmlkZUluTG9jYWxTdG9yYWdlLFxuICAgICAgaXNSZWFkeSxcbiAgICB9KSxcbiAgICBbXG4gICAgICBpZGVudGlmeVVzZXIsXG4gICAgICBnZXRVc2VySWRPckRlZmF1bHQsXG4gICAgICBnZXRVc2VySWRPdmVycmlkZUZyb21Mb2NhbFN0b3JhZ2UsXG4gICAgICBnZXRVc2VySWREZWZhdWx0RnJvbUxvY2FsU3RvcmFnZSxcbiAgICAgIHNldFVzZXJJZERlZmF1bHRJbkxvY2FsU3RvcmFnZSxcbiAgICAgIHNldFVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBjbGVhclVzZXJJZE92ZXJyaWRlSW5Mb2NhbFN0b3JhZ2UsXG4gICAgICBpc1JlYWR5LFxuICAgIF0sXG4gICk7XG5cbiAgcmV0dXJuIDxVc2VySWRlbnRpdHlDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt2YWx1ZX0+e2NoaWxkcmVufTwvVXNlcklkZW50aXR5Q29udGV4dC5Qcm92aWRlcj47XG59O1xuXG5leHBvcnQgY29uc3QgdXNlVXNlcklkZW50aXR5ID0gKCkgPT4ge1xuICBjb25zdCBjb250ZXh0ID0gdXNlQ29udGV4dChVc2VySWRlbnRpdHlDb250ZXh0KTtcbiAgY29uc3Qgc2V0VXNlcklkID0gdXNlU2V0QXRvbSh1c2VySWRBdG9tKTtcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBzZXRVc2VySWQoY29udGV4dD8uZ2V0VXNlcklkT3JEZWZhdWx0KCkgPz8gXCJcIik7XG4gIH0sIFtjb250ZXh0LCBzZXRVc2VySWRdKTtcbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2VVc2VySWRlbnRpdHkgbXVzdCBiZSB1c2VkIHdpdGhpbiBhIFVzZXJJZGVudGl0eVByb3ZpZGVyJyk7XG4gIH1cbiAgcmV0dXJuIGNvbnRleHQ7XG59O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMERBLGVBQWUsa0JBQWtCLE9BQXNCO0FBQ3JELEtBQUk7QUFD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
|