536 lines
62 KiB
Plaintext
536 lines
62 KiB
Plaintext
import {
|
|
SeatTypes,
|
|
waitForever
|
|
} from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/index.js";
|
|
import {
|
|
useApolloClient,
|
|
useMutation,
|
|
useSubscription,
|
|
useQuery
|
|
} from "/_nuxt/node_modules/@vue/apollo-composable/dist/index.mjs?v=e4f18c29";
|
|
import { graphql } from "/_nuxt/lib/common/generated/gql/index.ts";
|
|
import {
|
|
evictObjectFields,
|
|
getCacheId,
|
|
getFirstErrorMessage,
|
|
getObjectReference,
|
|
modifyObjectField,
|
|
modifyObjectFields,
|
|
ROOT_QUERY
|
|
} from "/_nuxt/lib/common/helpers/graphql.ts";
|
|
import { useNavigateToHome, workspaceRoute } from "/_nuxt/lib/common/helpers/route.ts";
|
|
import { useMixpanel } from "/_nuxt/lib/core/composables/mp.ts";
|
|
import {
|
|
createWorkspaceMutation,
|
|
inviteToWorkspaceMutation,
|
|
processWorkspaceInviteMutation,
|
|
setDefaultRegionMutation,
|
|
workspaceUpdateRoleMutation,
|
|
workspacesUpdateSeatTypeMutation
|
|
} from "/_nuxt/lib/workspaces/graphql/mutations.ts";
|
|
import { isFunction } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
|
|
import { onWorkspaceUpdatedSubscription } from "/_nuxt/lib/workspaces/graphql/subscriptions.ts";
|
|
import { useLock } from "/_nuxt/lib/common/composables/singleton.ts";
|
|
import { workspaceLastAdminCheckQuery } from "/_nuxt/lib/workspaces/graphql/queries.ts";
|
|
|
|
import { useActiveUser, useGlobalToast, useIsWorkspacesEnabled } from "/_nuxt/composables/globals.ts";
|
|
import { convertThrowIntoFetchResult, ToastNotificationType } from "/_nuxt/utils/globals.ts";
|
|
import { useRoute, navigateTo, useRouter } from "/_nuxt/node_modules/nuxt/dist/app/composables/router.js?v=e4f18c29";
|
|
import { ref, computed, unref } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
|
|
import { useClipboard } from "/_nuxt/composables/browser.ts";
|
|
export const useInviteUserToWorkspace = () => {
|
|
const { activeUser } = useActiveUser();
|
|
const { triggerNotification } = useGlobalToast();
|
|
const { mutate } = useMutation(inviteToWorkspaceMutation);
|
|
const isWorkspacesEnabled = useIsWorkspacesEnabled();
|
|
return async (args) => {
|
|
const { workspaceId, inputs, hideNotifications } = args;
|
|
const userId = activeUser.value?.id;
|
|
if (!userId) return;
|
|
if (!isWorkspacesEnabled.value) return;
|
|
const { data, errors } = await mutate(
|
|
{ workspaceId, input: inputs },
|
|
{
|
|
update: (cache, { data: data2 }) => {
|
|
if (!data2?.workspaceMutations.invites.batchCreate.id) return;
|
|
const invitedTeam = data2.workspaceMutations.invites.batchCreate.invitedTeam;
|
|
if (!invitedTeam) return;
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Workspace", workspaceId),
|
|
(_fieldName, vars) => {
|
|
if (vars.filter?.search?.length) return;
|
|
return invitedTeam.map(
|
|
(i) => getObjectReference("PendingWorkspaceCollaborator", i.id)
|
|
);
|
|
},
|
|
{
|
|
fieldNameWhitelist: ["invitedTeam"]
|
|
}
|
|
);
|
|
evictObjectFields(
|
|
cache,
|
|
getCacheId("Workspace", workspaceId),
|
|
(fieldName, vars) => {
|
|
if (fieldName !== "invitedTeam") return false;
|
|
return vars.filter?.search?.length !== 0;
|
|
}
|
|
);
|
|
}
|
|
}
|
|
).catch(convertThrowIntoFetchResult) || {};
|
|
if (!data?.workspaceMutations.invites.batchCreate.id && !hideNotifications) {
|
|
const err = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Invitation failed",
|
|
description: err
|
|
});
|
|
} else {
|
|
if (!hideNotifications) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "Invite successfully sent"
|
|
});
|
|
}
|
|
}
|
|
return data?.workspaceMutations.invites.batchCreate;
|
|
};
|
|
};
|
|
export const useProcessWorkspaceInvite = () => {
|
|
const { mutate } = useMutation(processWorkspaceInviteMutation);
|
|
const { activeUser } = useActiveUser();
|
|
const { triggerNotification } = useGlobalToast();
|
|
const mp = useMixpanel();
|
|
const isWorkspacesEnabled = useIsWorkspacesEnabled();
|
|
return async (params, options) => {
|
|
if (!isWorkspacesEnabled.value) return;
|
|
const userId = activeUser.value?.id;
|
|
if (!userId) return;
|
|
const { input, workspaceId, inviteId } = params;
|
|
const { data, errors } = await mutate(
|
|
{ input },
|
|
{
|
|
update: async (cache, { data: data2, errors: errors2 }) => {
|
|
if (errors2?.length) return;
|
|
const accepted = data2?.workspaceMutations.invites.use;
|
|
if (accepted) {
|
|
modifyObjectField(
|
|
cache,
|
|
ROOT_QUERY,
|
|
"workspace",
|
|
({ variables, helpers: { evict } }) => {
|
|
if (variables.id === workspaceId) return evict();
|
|
}
|
|
);
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("User", userId),
|
|
"workspaces",
|
|
({ helpers: { evict } }) => evict()
|
|
);
|
|
}
|
|
modifyObjectField(
|
|
cache,
|
|
ROOT_QUERY,
|
|
"workspaceInvite",
|
|
({ value, variables, helpers: { readField } }) => {
|
|
if (value) {
|
|
const workspaceRef = readField(value, "workspace");
|
|
if (workspaceRef) {
|
|
const workspaceId2 = readField(workspaceRef, "id");
|
|
const inviteWorkspaceId = workspaceId2;
|
|
if (inviteWorkspaceId === workspaceId2) return null;
|
|
}
|
|
} else {
|
|
if (variables.workspaceId === workspaceId) return null;
|
|
}
|
|
}
|
|
);
|
|
cache.evict({
|
|
id: getCacheId("PendingWorkspaceCollaborator", inviteId)
|
|
});
|
|
cache.evict({
|
|
id: getCacheId("PendingStreamCollaborator", inviteId)
|
|
});
|
|
if (options?.callback) await options.callback();
|
|
}
|
|
}
|
|
).catch(convertThrowIntoFetchResult) || {};
|
|
if (data?.workspaceMutations.invites.use) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: input.accept ? "Workspace invite accepted" : "Workspace invite dismissed"
|
|
});
|
|
mp.track("Workspace Joined", {
|
|
// eslint-disable-next-line camelcase
|
|
workspace_id: workspaceId
|
|
});
|
|
mp.track("Invite Action", {
|
|
type: "workspace invite",
|
|
accepted: input.accept,
|
|
// eslint-disable-next-line camelcase
|
|
workspace_id: workspaceId
|
|
});
|
|
} else {
|
|
const err = getFirstErrorMessage(errors);
|
|
const preventErrorToasts = isFunction(options?.preventErrorToasts) ? options?.preventErrorToasts(errors?.slice() || [], err) : options?.preventErrorToasts;
|
|
if (!preventErrorToasts) {
|
|
const err2 = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Failed to process invite",
|
|
description: err2
|
|
});
|
|
}
|
|
}
|
|
return !!data?.workspaceMutations.invites.use;
|
|
};
|
|
};
|
|
graphql(`
|
|
fragment UseWorkspaceInviteManager_PendingWorkspaceCollaborator on PendingWorkspaceCollaborator {
|
|
id
|
|
token
|
|
workspace {
|
|
...WorkspaceInviteCard_LimitedWorkspace
|
|
}
|
|
user {
|
|
id
|
|
}
|
|
}
|
|
`);
|
|
export const useWorkspaceInviteManager = (params, options) => {
|
|
const isWorkspacesEnabled = useIsWorkspacesEnabled();
|
|
const { invite } = params;
|
|
const { preventRedirect, preventErrorToasts } = options || {};
|
|
const useInvite = useProcessWorkspaceInvite();
|
|
const route = options?.route || useRoute();
|
|
const goHome = useNavigateToHome();
|
|
const { activeUser } = useActiveUser();
|
|
const loading = ref(false);
|
|
const token = computed(
|
|
() => route.query.token || invite.value?.token
|
|
);
|
|
const isCurrentUserTarget = computed(
|
|
() => activeUser.value && invite.value?.user && activeUser.value.id === invite.value.user.id
|
|
);
|
|
const targetUser = computed(() => invite.value?.user);
|
|
const needsToAddNewEmail = computed(
|
|
() => !isCurrentUserTarget.value && !targetUser.value
|
|
);
|
|
const canAddNewEmail = computed(() => needsToAddNewEmail.value && token.value);
|
|
const processInvite = async (accept, options2) => {
|
|
const { addNewEmail } = options2 || {};
|
|
if (!isWorkspacesEnabled.value) return false;
|
|
if (!token.value || !invite.value) return false;
|
|
const workspaceId = invite.value.workspace.id;
|
|
const workspaceSlug = invite.value.workspace.slug;
|
|
const shouldAddNewEmail = canAddNewEmail.value && addNewEmail;
|
|
loading.value = true;
|
|
const success = await useInvite(
|
|
{
|
|
workspaceId,
|
|
input: {
|
|
accept,
|
|
token: token.value,
|
|
...shouldAddNewEmail ? { addNewEmail: shouldAddNewEmail } : {}
|
|
},
|
|
inviteId: invite.value.id
|
|
},
|
|
{
|
|
callback: async () => {
|
|
if (!preventRedirect) {
|
|
if (accept) {
|
|
if (workspaceSlug) {
|
|
navigateTo(workspaceRoute(workspaceSlug));
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
await waitForever();
|
|
} else {
|
|
await goHome();
|
|
}
|
|
}
|
|
},
|
|
preventErrorToasts
|
|
}
|
|
);
|
|
loading.value = false;
|
|
return !!success;
|
|
};
|
|
return {
|
|
loading: computed(() => loading.value),
|
|
token,
|
|
isCurrentUserTarget,
|
|
targetUser,
|
|
accept: (options2) => processInvite(true, options2),
|
|
decline: (options2) => processInvite(false, options2)
|
|
};
|
|
};
|
|
export function useCreateWorkspace() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const { activeUser } = useActiveUser();
|
|
const router = useRouter();
|
|
return async (input, options) => {
|
|
const userId = activeUser.value?.id;
|
|
if (!userId) return;
|
|
const res = await apollo.mutate({
|
|
mutation: createWorkspaceMutation,
|
|
variables: { input },
|
|
update: (cache, { data }) => {
|
|
const workspaceId = data?.workspaceMutations.create.id;
|
|
if (!workspaceId) return;
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("User", userId),
|
|
"workspaces",
|
|
({ helpers: { createUpdatedValue, ref: ref2 } }) => {
|
|
return createUpdatedValue(({ update }) => {
|
|
update("totalCount", (totalCount) => totalCount + 1);
|
|
update("items", (items) => [...items, ref2("Workspace", workspaceId)]);
|
|
});
|
|
},
|
|
{
|
|
autoEvictFiltered: true
|
|
}
|
|
);
|
|
}
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (res.data?.workspaceMutations.create.id) {
|
|
if (!options?.hideNotifications) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "Workspace successfully created"
|
|
});
|
|
}
|
|
if (options?.navigateOnSuccess === true) {
|
|
router.push(workspaceRoute(res.data?.workspaceMutations.create.slug));
|
|
}
|
|
} else {
|
|
const err = getFirstErrorMessage(res.errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Workspace creation failed",
|
|
description: err
|
|
});
|
|
}
|
|
return res;
|
|
};
|
|
}
|
|
export const useWorkspaceUpdateRole = () => {
|
|
const { mutate } = useMutation(workspaceUpdateRoleMutation);
|
|
const { triggerNotification } = useGlobalToast();
|
|
const mixpanel = useMixpanel();
|
|
return async (input) => {
|
|
const result = await mutate(
|
|
{ input },
|
|
{
|
|
update: (cache) => {
|
|
if (!input.role) {
|
|
cache.evict({
|
|
id: getCacheId("WorkspaceCollaborator", input.userId)
|
|
});
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("Workspace", input.workspaceId),
|
|
"team",
|
|
({ helpers: { createUpdatedValue } }) => {
|
|
return createUpdatedValue(({ update }) => {
|
|
update("totalCount", (totalCount) => totalCount - 1);
|
|
});
|
|
},
|
|
{
|
|
autoEvictFiltered: true
|
|
}
|
|
);
|
|
}
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("Workspace", input.workspaceId),
|
|
"teamByRole",
|
|
({ helpers: { evict } }) => {
|
|
return evict();
|
|
}
|
|
);
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("Workspace", input.workspaceId),
|
|
"team",
|
|
({ helpers: { evict } }) => {
|
|
return evict();
|
|
}
|
|
);
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("WorkspaceCollaborator", input.userId),
|
|
"seatType",
|
|
() => SeatTypes.Editor
|
|
);
|
|
if (input.role) {
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("WorkspaceCollaborator", input.userId),
|
|
"role",
|
|
() => input.role
|
|
);
|
|
}
|
|
}
|
|
}
|
|
).catch(convertThrowIntoFetchResult);
|
|
if (result?.data) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: input.role ? "User role updated" : "User removed",
|
|
description: input.role ? "The user role has been updated" : "The user has been removed from the workspace"
|
|
});
|
|
if (input.role) {
|
|
mixpanel.track("Workspace User Role Updated", {
|
|
newRole: input.role,
|
|
// eslint-disable-next-line camelcase
|
|
workspace_id: input.workspaceId
|
|
});
|
|
} else {
|
|
mixpanel.track("Workspace User Removed", {
|
|
// eslint-disable-next-line camelcase
|
|
workspace_id: input.workspaceId
|
|
});
|
|
}
|
|
} else {
|
|
const errorMessage = getFirstErrorMessage(result?.errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: input.role ? "Failed to update role" : "Failed to remove user",
|
|
description: errorMessage
|
|
});
|
|
}
|
|
};
|
|
};
|
|
export const useWorkspaceUpdateSeatType = () => {
|
|
const { mutate } = useMutation(workspacesUpdateSeatTypeMutation);
|
|
const { triggerNotification } = useGlobalToast();
|
|
const mixpanel = useMixpanel();
|
|
return async (input, options) => {
|
|
const { hideNotifications } = options ?? {};
|
|
const result = await mutate(
|
|
{ input },
|
|
{
|
|
update: (cache) => {
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("WorkspaceCollaborator", input.userId),
|
|
"seatType",
|
|
() => input.seatType
|
|
);
|
|
modifyObjectField(
|
|
cache,
|
|
getCacheId("Workspace", input.workspaceId),
|
|
"team",
|
|
({ helpers: { evict } }) => {
|
|
return evict();
|
|
}
|
|
);
|
|
}
|
|
}
|
|
).catch(convertThrowIntoFetchResult);
|
|
if (result?.data) {
|
|
if (!hideNotifications) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "Seat updated",
|
|
description: `The user's seat has been updated to ${input.seatType}`
|
|
});
|
|
}
|
|
mixpanel.track("Workspace User Seat Type Updated", {
|
|
newSeatType: input.seatType,
|
|
// eslint-disable-next-line camelcase
|
|
workspace_id: input.workspaceId
|
|
});
|
|
} else {
|
|
const errorMessage = getFirstErrorMessage(result?.errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Failed to update seat type",
|
|
description: errorMessage
|
|
});
|
|
}
|
|
};
|
|
};
|
|
export const copyWorkspaceLink = async (slug) => {
|
|
const { copy } = useClipboard();
|
|
const url = new URL(workspaceRoute(slug), window.location.toString()).toString();
|
|
await copy(url, {
|
|
successMessage: "Copied workspace link to clipboard"
|
|
});
|
|
};
|
|
export const useSetDefaultWorkspaceRegion = () => {
|
|
const { mutate } = useMutation(setDefaultRegionMutation);
|
|
const { triggerNotification } = useGlobalToast();
|
|
return async (params) => {
|
|
const { workspaceId, regionKey } = params;
|
|
const res = await mutate({ workspaceId, regionKey }).catch(
|
|
convertThrowIntoFetchResult
|
|
);
|
|
if (res?.data?.workspaceMutations.setDefaultRegion) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: "Default region set successfully"
|
|
});
|
|
} else {
|
|
const err = getFirstErrorMessage(res?.errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Failed to set default region",
|
|
description: err
|
|
});
|
|
}
|
|
return res?.data?.workspaceMutations.setDefaultRegion;
|
|
};
|
|
};
|
|
export const useOnWorkspaceUpdated = (params) => {
|
|
const { workspaceSlug, handler } = params;
|
|
const apollo = useApolloClient().client;
|
|
const { hasLock } = useLock(
|
|
computed(() => `useOnWorkspaceUpdated-${unref(workspaceSlug.value)}`)
|
|
);
|
|
const enabled = computed(() => !!(hasLock.value || handler));
|
|
const { onResult } = useSubscription(
|
|
onWorkspaceUpdatedSubscription,
|
|
() => ({
|
|
workspaceSlug: params.workspaceSlug.value
|
|
}),
|
|
() => ({
|
|
enabled: enabled.value,
|
|
errorPolicy: "all"
|
|
})
|
|
);
|
|
onResult((result) => {
|
|
if (!result.data?.workspaceUpdated || !hasLock.value) return;
|
|
});
|
|
if (handler) {
|
|
onResult((result) => {
|
|
if (!result.data?.workspaceUpdated) return;
|
|
handler(result.data.workspaceUpdated, apollo.cache);
|
|
});
|
|
}
|
|
};
|
|
export const useWorkspaceLastAdminCheck = (params) => {
|
|
const { workspaceSlug } = params;
|
|
const { result } = useQuery(
|
|
workspaceLastAdminCheckQuery,
|
|
() => ({
|
|
slug: workspaceSlug.value || ""
|
|
}),
|
|
() => ({
|
|
enabled: !!workspaceSlug.value
|
|
})
|
|
);
|
|
const isLastAdmin = computed(
|
|
() => result.value?.workspaceBySlug?.teamByRole?.admins?.totalCount === 1
|
|
);
|
|
return {
|
|
isLastAdmin
|
|
};
|
|
};
|
|
|
|
//# sourceMappingURL=data:application/json;base64,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T0FBTztBQUFBLE1BQ0wsU0FBUyxRQUFRO0FBQUEsTUFDakIsYUFBYTtBQUFBLElBQ2Y7QUFBQSxFQUNGO0FBR0EsV0FBUyxDQUFDLFdBQVc7QUFDbkIsUUFBSSxDQUFDLE9BQU8sTUFBTSxvQkFBb0IsQ0FBQyxRQUFRLE1BQU87QUFBQSxFQUN4RCxDQUFDO0FBR0QsTUFBSSxTQUFTO0FBQ1gsYUFBUyxDQUFDLFdBQVc7QUFDbkIsVUFBSSxDQUFDLE9BQU8sTUFBTSxpQkFBa0I7QUFDcEMsY0FBUSxPQUFPLEtBQUssa0JBQWtCLE9BQU8sS0FBSztBQUFBLElBQ3BELENBQUM7QUFBQSxFQUNIO0FBQ0Y7QUFFTyxhQUFNLDZCQUE2QixDQUFDLFdBRXJDO0FBQ0osUUFBTSxFQUFFLGNBQWMsSUFBSTtBQUUxQixRQUFNLEVBQUUsT0FBTyxJQUFJO0FBQUEsSUFDakI7QUFBQSxJQUNBLE9BQU87QUFBQSxNQUNMLE1BQU0sY0FBYyxTQUFTO0FBQUEsSUFDL0I7QUFBQSxJQUNBLE9BQU87QUFBQSxNQUNMLFNBQVMsQ0FBQyxDQUFDLGNBQWM7QUFBQSxJQUMzQjtBQUFBLEVBQ0Y7QUFFQSxRQUFNLGNBQWM7QUFBQSxJQUNsQixNQUFNLE9BQU8sT0FBTyxpQkFBaUIsWUFBWSxRQUFRLGVBQWU7QUFBQSxFQUMxRTtBQUVBLFNBQU87QUFBQSxJQUNMO0FBQUEsRUFDRjtBQUNGIiwibmFtZXMiOlsiZGF0YSIsImVycm9ycyIsIndvcmtzcGFjZUlkIiwiZXJyIiwib3B0aW9ucyIsInJlZiJdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJtYW5hZ2VtZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUm91dGVMb2NhdGlvbk5vcm1hbGl6ZWQgfSBmcm9tICd2dWUtcm91dGVyJ1xyXG5pbXBvcnQge1xyXG4gIFNlYXRUeXBlcyxcclxuICB3YWl0Rm9yZXZlcixcclxuICB0eXBlIE1heWJlQXN5bmMsXHJcbiAgdHlwZSBNYXliZU51bGxPclVuZGVmaW5lZCxcclxuICB0eXBlIE9wdGlvbmFsLFxyXG4gIHR5cGUgV29ya3NwYWNlU2VhdFR5cGVcclxufSBmcm9tICdAc3BlY2tsZS9zaGFyZWQnXHJcbmltcG9ydCB7XHJcbiAgdXNlQXBvbGxvQ2xpZW50LFxyXG4gIHVzZU11dGF0aW9uLFxyXG4gIHVzZVN1YnNjcmlwdGlvbixcclxuICB1c2VRdWVyeVxyXG59IGZyb20gJ0B2dWUvYXBvbGxvLWNvbXBvc2FibGUnXHJcbmltcG9ydCB7IGdyYXBocWwgfSBmcm9tICd+L2xpYi9jb21tb24vZ2VuZXJhdGVkL2dxbCdcclxuaW1wb3J0IHR5cGUge1xyXG4gIE9uV29ya3NwYWNlVXBkYXRlZFN1YnNjcmlwdGlvbixcclxuICBVc2VXb3Jrc3BhY2VJbnZpdGVNYW5hZ2VyX1BlbmRpbmdXb3Jrc3BhY2VDb2xsYWJvcmF0b3JGcmFnbWVudCxcclxuICBXb3Jrc3BhY2UsXHJcbiAgV29ya3NwYWNlQ3JlYXRlSW5wdXQsXHJcbiAgV29ya3NwYWNlSW52aXRlQ3JlYXRlSW5wdXQsXHJcbiAgV29ya3NwYWNlSW52aXRlZFRlYW1BcmdzLFxyXG4gIFdvcmtzcGFjZUludml0ZVVzZUlucHV0LFxyXG4gIFdvcmtzcGFjZVJvbGVVcGRhdGVJbnB1dFxyXG59IGZyb20gJ34vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcbmltcG9ydCB7XHJcbiAgZXZpY3RPYmplY3RGaWVsZHMsXHJcbiAgZ2V0Q2FjaGVJZCxcclxuICBnZXRGaXJzdEVycm9yTWVzc2FnZSxcclxuICBnZXRPYmplY3RSZWZlcmVuY2UsXHJcbiAgbW9kaWZ5T2JqZWN0RmllbGQsXHJcbiAgbW9kaWZ5T2JqZWN0RmllbGRzLFxyXG4gIFJPT1RfUVVFUllcclxufSBmcm9tICd+L2xpYi9jb21tb24vaGVscGVycy9ncmFwaHFsJ1xyXG5pbXBvcnQgeyB1c2VOYXZpZ2F0ZVRvSG9tZSwgd29ya3NwYWNlUm91dGUgfSBmcm9tICd+L2xpYi9jb21tb24vaGVscGVycy9yb3V0ZSdcclxuaW1wb3J0IHsgdXNlTWl4cGFuZWwgfSBmcm9tICd+L2xpYi9jb3JlL2NvbXBvc2FibGVzL21wJ1xyXG5pbXBvcnQge1xyXG4gIGNyZWF0ZVdvcmtzcGFjZU11dGF0aW9uLFxyXG4gIGludml0ZVRvV29ya3NwYWNlTXV0YXRpb24sXHJcbiAgcHJvY2Vzc1dvcmtzcGFjZUludml0ZU11dGF0aW9uLFxyXG4gIHNldERlZmF1bHRSZWdpb25NdXRhdGlvbixcclxuICB3b3Jrc3BhY2VVcGRhdGVSb2xlTXV0YXRpb24sXHJcbiAgd29ya3NwYWNlc1VwZGF0ZVNlYXRUeXBlTXV0YXRpb25cclxufSBmcm9tICd+L2xpYi93b3Jrc3BhY2VzL2dyYXBocWwvbXV0YXRpb25zJ1xyXG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnbG9kYXNoLWVzJ1xyXG5pbXBvcnQgdHlwZSB7IEdyYXBoUUxFcnJvciwgR3JhcGhRTEZvcm1hdHRlZEVycm9yIH0gZnJvbSAnZ3JhcGhxbCdcclxuaW1wb3J0IHsgb25Xb3Jrc3BhY2VVcGRhdGVkU3Vic2NyaXB0aW9uIH0gZnJvbSAnfi9saWIvd29ya3NwYWNlcy9ncmFwaHFsL3N1YnNjcmlwdGlvbnMnXHJcbmltcG9ydCB7IHVzZUxvY2sgfSBmcm9tICd+L2xpYi9jb21tb24vY29tcG9zYWJsZXMvc2luZ2xldG9uJ1xyXG5pbXBvcnQgdHlwZSB7IEdldCB9IGZyb20gJ3R5cGUtZmVzdCdcclxuaW1wb3J0IHR5cGUgeyBBcG9sbG9DYWNoZSB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2NvcmUnXHJcbmltcG9ydCB7IHdvcmtzcGFjZUxhc3RBZG1pbkNoZWNrUXVlcnkgfSBmcm9tICcuLi9ncmFwaHFsL3F1ZXJpZXMnXHJcblxyXG5leHBvcnQgY29uc3QgdXNlSW52aXRlVXNlclRvV29ya3NwYWNlID0gKCkgPT4ge1xyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgeyBtdXRhdGUgfSA9IHVzZU11dGF0aW9uKGludml0ZVRvV29ya3NwYWNlTXV0YXRpb24pXHJcbiAgY29uc3QgaXNXb3Jrc3BhY2VzRW5hYmxlZCA9IHVzZUlzV29ya3NwYWNlc0VuYWJsZWQoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKGFyZ3M6IHtcclxuICAgIHdvcmtzcGFjZUlkOiBzdHJpbmdcclxuICAgIGlucHV0czogV29ya3NwYWNlSW52aXRlQ3JlYXRlSW5wdXRbXVxyXG4gICAgaGlkZU5vdGlmaWNhdGlvbnM/OiBib29sZWFuXHJcbiAgfSkgPT4ge1xyXG4gICAgY29uc3QgeyB3b3Jrc3BhY2VJZCwgaW5wdXRzLCBoaWRlTm90aWZpY2F0aW9ucyB9ID0gYXJnc1xyXG5cclxuICAgIGNvbnN0IHVzZXJJZCA9IGFjdGl2ZVVzZXIudmFsdWU/LmlkXHJcbiAgICBpZiAoIXVzZXJJZCkgcmV0dXJuXHJcbiAgICBpZiAoIWlzV29ya3NwYWNlc0VuYWJsZWQudmFsdWUpIHJldHVyblxyXG5cclxuICAgIGNvbnN0IHsgZGF0YSwgZXJyb3JzIH0gPVxyXG4gICAgICAoYXdhaXQgbXV0YXRlKFxyXG4gICAgICAgIHsgd29ya3NwYWNlSWQsIGlucHV0OiBpbnB1dHMgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICB1cGRhdGU6IChjYWNoZSwgeyBkYXRhIH0pID0+IHtcclxuICAgICAgICAgICAgaWYgKCFkYXRhPy53b3Jrc3BhY2VNdXRhdGlvbnMuaW52aXRlcy5iYXRjaENyZWF0ZS5pZCkgcmV0dXJuXHJcblxyXG4gICAgICAgICAgICBjb25zdCBpbnZpdGVkVGVhbSA9IGRhdGEud29ya3NwYWNlTXV0YXRpb25zLmludml0ZXMuYmF0Y2hDcmVhdGUuaW52aXRlZFRlYW1cclxuICAgICAgICAgICAgaWYgKCFpbnZpdGVkVGVhbSkgcmV0dXJuXHJcblxyXG4gICAgICAgICAgICBtb2RpZnlPYmplY3RGaWVsZHM8V29ya3NwYWNlSW52aXRlZFRlYW1BcmdzLCBXb3Jrc3BhY2VbJ2ludml0ZWRUZWFtJ10+KFxyXG4gICAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICAgIGdldENhY2hlSWQoJ1dvcmtzcGFjZScsIHdvcmtzcGFjZUlkKSxcclxuICAgICAgICAgICAgICAoX2ZpZWxkTmFtZSwgdmFycykgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhcnMuZmlsdGVyPy5zZWFyY2g/Lmxlbmd0aCkgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaW52aXRlZFRlYW0ubWFwKChpKSA9PlxyXG4gICAgICAgICAgICAgICAgICBnZXRPYmplY3RSZWZlcmVuY2UoJ1BlbmRpbmdXb3Jrc3BhY2VDb2xsYWJvcmF0b3InLCBpLmlkKVxyXG4gICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgZmllbGROYW1lV2hpdGVsaXN0OiBbJ2ludml0ZWRUZWFtJ11cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAgIC8vIEV2aWN0IHRoZSBjYWNoZSBmb3IgdGhlIGludml0ZWQgdGVhbSBpZiB0aGUgc2VhcmNoIGZpbHRlciBpcyBhY3RpdmVcclxuICAgICAgICAgICAgZXZpY3RPYmplY3RGaWVsZHM8V29ya3NwYWNlSW52aXRlZFRlYW1BcmdzLCBXb3Jrc3BhY2VbJ2ludml0ZWRUZWFtJ10+KFxyXG4gICAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICAgIGdldENhY2hlSWQoJ1dvcmtzcGFjZScsIHdvcmtzcGFjZUlkKSxcclxuICAgICAgICAgICAgICAoZmllbGROYW1lLCB2YXJzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZmllbGROYW1lICE9PSAnaW52aXRlZFRlYW0nKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiB2YXJzLmZpbHRlcj8uc2VhcmNoPy5sZW5ndGggIT09IDBcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICkuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KSkgfHwge31cclxuXHJcbiAgICBpZiAoIWRhdGE/LndvcmtzcGFjZU11dGF0aW9ucy5pbnZpdGVzLmJhdGNoQ3JlYXRlLmlkICYmICFoaWRlTm90aWZpY2F0aW9ucykge1xyXG4gICAgICBjb25zdCBlcnIgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6ICdJbnZpdGF0aW9uIGZhaWxlZCcsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGVyclxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKCFoaWRlTm90aWZpY2F0aW9ucykge1xyXG4gICAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgICB0aXRsZTogJ0ludml0ZSBzdWNjZXNzZnVsbHkgc2VudCdcclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRhdGE/LndvcmtzcGFjZU11dGF0aW9ucy5pbnZpdGVzLmJhdGNoQ3JlYXRlXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgdXNlUHJvY2Vzc1dvcmtzcGFjZUludml0ZSA9ICgpID0+IHtcclxuICBjb25zdCB7IG11dGF0ZSB9ID0gdXNlTXV0YXRpb24ocHJvY2Vzc1dvcmtzcGFjZUludml0ZU11dGF0aW9uKVxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgbXAgPSB1c2VNaXhwYW5lbCgpXHJcbiAgY29uc3QgaXNXb3Jrc3BhY2VzRW5hYmxlZCA9IHVzZUlzV29ya3NwYWNlc0VuYWJsZWQoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKFxyXG4gICAgcGFyYW1zOiB7XHJcbiAgICAgIGlucHV0OiBXb3Jrc3BhY2VJbnZpdGVVc2VJbnB1dFxyXG4gICAgICB3b3Jrc3BhY2VJZDogc3RyaW5nXHJcbiAgICAgIGludml0ZUlkOiBzdHJpbmdcclxuICAgIH0sXHJcbiAgICBvcHRpb25zPzogUGFydGlhbDx7XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBEbyBzb21ldGhpbmcgb25jZSBtdXRhdGlvbiBoYXMgZmluaXNoZWQsIGJlZm9yZSBhbGwgY2FjaGUgdXBkYXRlc1xyXG4gICAgICAgKi9cclxuICAgICAgY2FsbGJhY2s6ICgpID0+IE1heWJlQXN5bmM8dm9pZD5cclxuICAgICAgcHJldmVudEVycm9yVG9hc3RzPzpcclxuICAgICAgICB8IGJvb2xlYW5cclxuICAgICAgICB8ICgoXHJcbiAgICAgICAgICAgIGVycm9yczogR3JhcGhRTEVycm9yW10gfCBHcmFwaFFMRm9ybWF0dGVkRXJyb3JbXSxcclxuICAgICAgICAgICAgZXJyTXNnOiBzdHJpbmdcclxuICAgICAgICAgICkgPT4gYm9vbGVhbilcclxuICAgIH0+XHJcbiAgKSA9PiB7XHJcbiAgICBpZiAoIWlzV29ya3NwYWNlc0VuYWJsZWQudmFsdWUpIHJldHVyblxyXG4gICAgY29uc3QgdXNlcklkID0gYWN0aXZlVXNlci52YWx1ZT8uaWRcclxuICAgIGlmICghdXNlcklkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGlucHV0LCB3b3Jrc3BhY2VJZCwgaW52aXRlSWQgfSA9IHBhcmFtc1xyXG4gICAgY29uc3QgeyBkYXRhLCBlcnJvcnMgfSA9XHJcbiAgICAgIChhd2FpdCBtdXRhdGUoXHJcbiAgICAgICAgeyBpbnB1dCB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHVwZGF0ZTogYXN5bmMgKGNhY2hlLCB7IGRhdGEsIGVycm9ycyB9KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChlcnJvcnM/Lmxlbmd0aCkgcmV0dXJuXHJcblxyXG4gICAgICAgICAgICBjb25zdCBhY2NlcHRlZCA9IGRhdGE/LndvcmtzcGFjZU11dGF0aW9ucy5pbnZpdGVzLnVzZVxyXG5cclxuICAgICAgICAgICAgaWYgKGFjY2VwdGVkKSB7XHJcbiAgICAgICAgICAgICAgLy8gRXZpY3QgUXVlcnkud29ya3NwYWNlXHJcbiAgICAgICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGQoXHJcbiAgICAgICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgICAgIFJPT1RfUVVFUlksXHJcbiAgICAgICAgICAgICAgICAnd29ya3NwYWNlJyxcclxuICAgICAgICAgICAgICAgICh7IHZhcmlhYmxlcywgaGVscGVyczogeyBldmljdCB9IH0pID0+IHtcclxuICAgICAgICAgICAgICAgICAgaWYgKHZhcmlhYmxlcy5pZCA9PT0gd29ya3NwYWNlSWQpIHJldHVybiBldmljdCgpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgKVxyXG5cclxuICAgICAgICAgICAgICAvLyBFdmljdCBhbGwgVXNlci53b3Jrc3BhY2VzXHJcbiAgICAgICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGQoXHJcbiAgICAgICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgICAgIGdldENhY2hlSWQoJ1VzZXInLCB1c2VySWQpLFxyXG4gICAgICAgICAgICAgICAgJ3dvcmtzcGFjZXMnLFxyXG4gICAgICAgICAgICAgICAgKHsgaGVscGVyczogeyBldmljdCB9IH0pID0+IGV2aWN0KClcclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFNldCBRdWVyeS53b3Jrc3BhY2VJbnZpdGUoaWQpID0gbnVsbCAobm8gaW52aXRlKVxyXG4gICAgICAgICAgICBtb2RpZnlPYmplY3RGaWVsZChcclxuICAgICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgICBST09UX1FVRVJZLFxyXG4gICAgICAgICAgICAgICd3b3Jrc3BhY2VJbnZpdGUnLFxyXG4gICAgICAgICAgICAgICh7IHZhbHVlLCB2YXJpYWJsZXMsIGhlbHBlcnM6IHsgcmVhZEZpZWxkIH0gfSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHdvcmtzcGFjZVJlZiA9IHJlYWRGaWVsZCh2YWx1ZSwgJ3dvcmtzcGFjZScpXHJcblxyXG4gICAgICAgICAgICAgICAgICBpZiAod29ya3NwYWNlUmVmKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd29ya3NwYWNlSWQgPSByZWFkRmllbGQod29ya3NwYWNlUmVmLCAnaWQnKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludml0ZVdvcmtzcGFjZUlkID0gd29ya3NwYWNlSWRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaW52aXRlV29ya3NwYWNlSWQgPT09IHdvcmtzcGFjZUlkKSByZXR1cm4gbnVsbFxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICBpZiAodmFyaWFibGVzLndvcmtzcGFjZUlkID09PSB3b3Jrc3BhY2VJZCkgcmV0dXJuIG51bGxcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAgIC8vIEV2aWN0IGludml0ZSBpdHNlbGYgKGJlY2F1c2Ugb2YgaW1wbGljaXQgd29ya3NwYWNlIGludml0ZXMsIHdlIG5lZWQgdG8gYWxzbyBldmljdCBlcXVpdmFsZW50IHByb2plY3QgaW52aXRlKVxyXG4gICAgICAgICAgICBjYWNoZS5ldmljdCh7XHJcbiAgICAgICAgICAgICAgaWQ6IGdldENhY2hlSWQoJ1BlbmRpbmdXb3Jrc3BhY2VDb2xsYWJvcmF0b3InLCBpbnZpdGVJZClcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgY2FjaGUuZXZpY3Qoe1xyXG4gICAgICAgICAgICAgIGlkOiBnZXRDYWNoZUlkKCdQZW5kaW5nU3RyZWFtQ29sbGFib3JhdG9yJywgaW52aXRlSWQpXHJcbiAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICBpZiAob3B0aW9ucz8uY2FsbGJhY2spIGF3YWl0IG9wdGlvbnMuY2FsbGJhY2soKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgKS5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpKSB8fCB7fVxyXG5cclxuICAgIGlmIChkYXRhPy53b3Jrc3BhY2VNdXRhdGlvbnMuaW52aXRlcy51c2UpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6IGlucHV0LmFjY2VwdCA/ICdXb3Jrc3BhY2UgaW52aXRlIGFjY2VwdGVkJyA6ICdXb3Jrc3BhY2UgaW52aXRlIGRpc21pc3NlZCdcclxuICAgICAgfSlcclxuXHJcbiAgICAgIG1wLnRyYWNrKCdXb3Jrc3BhY2UgSm9pbmVkJywge1xyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcclxuICAgICAgICB3b3Jrc3BhY2VfaWQ6IHdvcmtzcGFjZUlkXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICBtcC50cmFjaygnSW52aXRlIEFjdGlvbicsIHtcclxuICAgICAgICB0eXBlOiAnd29ya3NwYWNlIGludml0ZScsXHJcbiAgICAgICAgYWNjZXB0ZWQ6IGlucHV0LmFjY2VwdCxcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXHJcbiAgICAgICAgd29ya3NwYWNlX2lkOiB3b3Jrc3BhY2VJZFxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICBjb25zdCBwcmV2ZW50RXJyb3JUb2FzdHMgPSBpc0Z1bmN0aW9uKG9wdGlvbnM/LnByZXZlbnRFcnJvclRvYXN0cylcclxuICAgICAgICA/IG9wdGlvbnM/LnByZXZlbnRFcnJvclRvYXN0cyhlcnJvcnM/LnNsaWNlKCkgfHwgW10sIGVycilcclxuICAgICAgICA6IG9wdGlvbnM/LnByZXZlbnRFcnJvclRvYXN0c1xyXG5cclxuICAgICAgaWYgKCFwcmV2ZW50RXJyb3JUb2FzdHMpIHtcclxuICAgICAgICBjb25zdCBlcnIgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgICAgdGl0bGU6ICdGYWlsZWQgdG8gcHJvY2VzcyBpbnZpdGUnLFxyXG4gICAgICAgICAgZGVzY3JpcHRpb246IGVyclxyXG4gICAgICAgIH0pXHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gISFkYXRhPy53b3Jrc3BhY2VNdXRhdGlvbnMuaW52aXRlcy51c2VcclxuICB9XHJcbn1cclxuXHJcbmdyYXBocWwoYFxyXG4gIGZyYWdtZW50IFVzZVdvcmtzcGFjZUludml0ZU1hbmFnZXJfUGVuZGluZ1dvcmtzcGFjZUNvbGxhYm9yYXRvciBvbiBQZW5kaW5nV29ya3NwYWNlQ29sbGFib3JhdG9yIHtcclxuICAgIGlkXHJcbiAgICB0b2tlblxyXG4gICAgd29ya3NwYWNlIHtcclxuICAgICAgLi4uV29ya3NwYWNlSW52aXRlQ2FyZF9MaW1pdGVkV29ya3NwYWNlXHJcbiAgICB9XHJcbiAgICB1c2VyIHtcclxuICAgICAgaWRcclxuICAgIH1cclxuICB9XHJcbmApXHJcblxyXG5leHBvcnQgY29uc3QgdXNlV29ya3NwYWNlSW52aXRlTWFuYWdlciA9IDxcclxuICBJbnZpdGUgZXh0ZW5kcyBVc2VXb3Jrc3BhY2VJbnZpdGVNYW5hZ2VyX1BlbmRpbmdXb3Jrc3BhY2VDb2xsYWJvcmF0b3JGcmFnbWVudCA9IFVzZVdvcmtzcGFjZUludml0ZU1hbmFnZXJfUGVuZGluZ1dvcmtzcGFjZUNvbGxhYm9yYXRvckZyYWdtZW50XHJcbj4oXHJcbiAgcGFyYW1zOiB7XHJcbiAgICBpbnZpdGU6IFJlZjxPcHRpb25hbDxJbnZpdGU+PlxyXG4gIH0sXHJcbiAgb3B0aW9ucz86IFBhcnRpYWw8e1xyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHRvIHByZXZlbnQgYW55IHJlbG9hZHMvcmVkaXJlY3RzIG9uIHN1Y2Nlc3NmdWwgcHJvY2Vzc2luZyBvZiB0aGUgaW52aXRlXHJcbiAgICAgKi9cclxuICAgIHByZXZlbnRSZWRpcmVjdDogYm9vbGVhblxyXG4gICAgcm91dGU6IFJvdXRlTG9jYXRpb25Ob3JtYWxpemVkXHJcbiAgICBwcmV2ZW50RXJyb3JUb2FzdHM6XHJcbiAgICAgIHwgYm9vbGVhblxyXG4gICAgICB8ICgoZXJyb3JzOiBHcmFwaFFMRXJyb3JbXSB8IEdyYXBoUUxGb3JtYXR0ZWRFcnJvcltdLCBlcnJNc2c6IHN0cmluZykgPT4gYm9vbGVhbilcclxuICB9PlxyXG4pID0+IHtcclxuICBjb25zdCBpc1dvcmtzcGFjZXNFbmFibGVkID0gdXNlSXNXb3Jrc3BhY2VzRW5hYmxlZCgpXHJcbiAgY29uc3QgeyBpbnZpdGUgfSA9IHBhcmFtc1xyXG4gIGNvbnN0IHsgcHJldmVudFJlZGlyZWN0LCBwcmV2ZW50RXJyb3JUb2FzdHMgfSA9IG9wdGlvbnMgfHwge31cclxuXHJcbiAgY29uc3QgdXNlSW52aXRlID0gdXNlUHJvY2Vzc1dvcmtzcGFjZUludml0ZSgpXHJcbiAgY29uc3Qgcm91dGUgPSBvcHRpb25zPy5yb3V0ZSB8fCB1c2VSb3V0ZSgpXHJcbiAgY29uc3QgZ29Ib21lID0gdXNlTmF2aWdhdGVUb0hvbWUoKVxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcblxyXG4gIGNvbnN0IGxvYWRpbmcgPSByZWYoZmFsc2UpXHJcblxyXG4gIGNvbnN0IHRva2VuID0gY29tcHV0ZWQoXHJcbiAgICAoKSA9PiAocm91dGUucXVlcnkudG9rZW4gYXMgT3B0aW9uYWw8c3RyaW5nPikgfHwgaW52aXRlLnZhbHVlPy50b2tlblxyXG4gIClcclxuICBjb25zdCBpc0N1cnJlbnRVc2VyVGFyZ2V0ID0gY29tcHV0ZWQoXHJcbiAgICAoKSA9PlxyXG4gICAgICBhY3RpdmVVc2VyLnZhbHVlICYmXHJcbiAgICAgIGludml0ZS52YWx1ZT8udXNlciAmJlxyXG4gICAgICBhY3RpdmVVc2VyLnZhbHVlLmlkID09PSBpbnZpdGUudmFsdWUudXNlci5pZFxyXG4gIClcclxuICBjb25zdCB0YXJnZXRVc2VyID0gY29tcHV0ZWQoKCk6IEludml0ZVsndXNlciddID0+IGludml0ZS52YWx1ZT8udXNlcilcclxuICBjb25zdCBuZWVkc1RvQWRkTmV3RW1haWwgPSBjb21wdXRlZChcclxuICAgICgpID0+ICFpc0N1cnJlbnRVc2VyVGFyZ2V0LnZhbHVlICYmICF0YXJnZXRVc2VyLnZhbHVlXHJcbiAgKVxyXG4gIGNvbnN0IGNhbkFkZE5ld0VtYWlsID0gY29tcHV0ZWQoKCkgPT4gbmVlZHNUb0FkZE5ld0VtYWlsLnZhbHVlICYmIHRva2VuLnZhbHVlKVxyXG5cclxuICBjb25zdCBwcm9jZXNzSW52aXRlID0gYXN5bmMgKFxyXG4gICAgYWNjZXB0OiBib29sZWFuLFxyXG4gICAgb3B0aW9ucz86IFBhcnRpYWw8e1xyXG4gICAgICAvKipcclxuICAgICAgICogSWYgaW52aXRlIGlzIGF0dGFjaGVkIHRvIGFuIHVucmVnaXN0ZXJlZCBlbWFpbCwgdGhlIGludml0ZSBjYW4gb25seSBiZSB1c2VkIGlmIHRoaXMgaXMgc2V0IHRvIHRydWUuXHJcbiAgICAgICAqIFVwb24gYWNjZXB0aW5nIHN1Y2ggYW4gaW52aXRlLCB0aGUgdW5yZWdpc3RlcmVkIGVtYWlsIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHVzZXIncyBhY2NvdW50IGFzIHdlbGwuXHJcbiAgICAgICAqL1xyXG4gICAgICBhZGROZXdFbWFpbDogYm9vbGVhblxyXG4gICAgfT5cclxuICApID0+IHtcclxuICAgIGNvbnN0IHsgYWRkTmV3RW1haWwgfSA9IG9wdGlvbnMgfHwge31cclxuICAgIGlmICghaXNXb3Jrc3BhY2VzRW5hYmxlZC52YWx1ZSkgcmV0dXJuIGZhbHNlXHJcbiAgICBpZiAoIXRva2VuLnZhbHVlIHx8ICFpbnZpdGUudmFsdWUpIHJldHVybiBmYWxzZVxyXG5cclxuICAgIGNvbnN0IHdvcmtzcGFjZUlkID0gaW52aXRlLnZhbHVlLndvcmtzcGFjZS5pZFxyXG4gICAgY29uc3Qgd29ya3NwYWNlU2x1ZyA9IGludml0ZS52YWx1ZS53b3Jrc3BhY2Uuc2x1Z1xyXG4gICAgY29uc3Qgc2hvdWxkQWRkTmV3RW1haWwgPSBjYW5BZGROZXdFbWFpbC52YWx1ZSAmJiBhZGROZXdFbWFpbFxyXG5cclxuICAgIGxvYWRpbmcudmFsdWUgPSB0cnVlXHJcbiAgICBjb25zdCBzdWNjZXNzID0gYXdhaXQgdXNlSW52aXRlKFxyXG4gICAgICB7XHJcbiAgICAgICAgd29ya3NwYWNlSWQsXHJcbiAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgIGFjY2VwdCxcclxuICAgICAgICAgIHRva2VuOiB0b2tlbi52YWx1ZSxcclxuICAgICAgICAgIC4uLihzaG91bGRBZGROZXdFbWFpbCA/IHsgYWRkTmV3RW1haWw6IHNob3VsZEFkZE5ld0VtYWlsIH0gOiB7fSlcclxuICAgICAgICB9LFxyXG4gICAgICAgIGludml0ZUlkOiBpbnZpdGUudmFsdWUuaWRcclxuICAgICAgfSxcclxuICAgICAge1xyXG4gICAgICAgIGNhbGxiYWNrOiBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICBpZiAoIXByZXZlbnRSZWRpcmVjdCkge1xyXG4gICAgICAgICAgICAvLyBSZWRpcmVjdFxyXG4gICAgICAgICAgICBpZiAoYWNjZXB0KSB7XHJcbiAgICAgICAgICAgICAgaWYgKHdvcmtzcGFjZVNsdWcpIHtcclxuICAgICAgICAgICAgICAgIG5hdmlnYXRlVG8od29ya3NwYWNlUm91dGUod29ya3NwYWNlU2x1ZykpXHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBhd2FpdCB3YWl0Rm9yZXZlcigpIC8vIHRvIHByZXZlbnQgVUkgY2hhbmdlcyB3aGlsZSByZWxvYWQgaXMgaGFwcGVuaW5nXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgYXdhaXQgZ29Ib21lKClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcHJldmVudEVycm9yVG9hc3RzXHJcbiAgICAgIH1cclxuICAgIClcclxuICAgIGxvYWRpbmcudmFsdWUgPSBmYWxzZVxyXG5cclxuICAgIHJldHVybiAhIXN1Y2Nlc3NcclxuICB9XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBsb2FkaW5nOiBjb21wdXRlZCgoKSA9PiBsb2FkaW5nLnZhbHVlKSxcclxuICAgIHRva2VuLFxyXG4gICAgaXNDdXJyZW50VXNlclRhcmdldCxcclxuICAgIHRhcmdldFVzZXIsXHJcbiAgICBhY2NlcHQ6IChvcHRpb25zPzogUGFyYW1ldGVyczx0eXBlb2YgcHJvY2Vzc0ludml0ZT5bMV0pID0+XHJcbiAgICAgIHByb2Nlc3NJbnZpdGUodHJ1ZSwgb3B0aW9ucyksXHJcbiAgICBkZWNsaW5lOiAob3B0aW9ucz86IFBhcmFtZXRlcnM8dHlwZW9mIHByb2Nlc3NJbnZpdGU+WzFdKSA9PlxyXG4gICAgICBwcm9jZXNzSW52aXRlKGZhbHNlLCBvcHRpb25zKVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZUNyZWF0ZVdvcmtzcGFjZSgpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuICBjb25zdCB7IGFjdGl2ZVVzZXIgfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IHJvdXRlciA9IHVzZVJvdXRlcigpXHJcblxyXG4gIHJldHVybiBhc3luYyAoXHJcbiAgICBpbnB1dDogV29ya3NwYWNlQ3JlYXRlSW5wdXQsXHJcbiAgICBvcHRpb25zPzogUGFydGlhbDx7XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgdG8gbmF2aWdhdGUgdG8gdGhlIG5ldyB3b3Jrc3BhY2UgdXBvbiBjcmVhdGlvbi5cclxuICAgICAgICogRGVmYXVsdHMgdG8gZmFsc2UuXHJcbiAgICAgICAqL1xyXG4gICAgICBuYXZpZ2F0ZU9uU3VjY2VzczogYm9vbGVhblxyXG4gICAgICBoaWRlTm90aWZpY2F0aW9uczogYm9vbGVhblxyXG4gICAgfT5cclxuICApID0+IHtcclxuICAgIGNvbnN0IHVzZXJJZCA9IGFjdGl2ZVVzZXIudmFsdWU/LmlkXHJcbiAgICBpZiAoIXVzZXJJZCkgcmV0dXJuXHJcblxyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBjcmVhdGVXb3Jrc3BhY2VNdXRhdGlvbixcclxuICAgICAgICB2YXJpYWJsZXM6IHsgaW5wdXQgfSxcclxuICAgICAgICB1cGRhdGU6IChjYWNoZSwgeyBkYXRhIH0pID0+IHtcclxuICAgICAgICAgIGNvbnN0IHdvcmtzcGFjZUlkID0gZGF0YT8ud29ya3NwYWNlTXV0YXRpb25zLmNyZWF0ZS5pZFxyXG4gICAgICAgICAgaWYgKCF3b3Jrc3BhY2VJZCkgcmV0dXJuXHJcbiAgICAgICAgICAvLyBOYXZpZ2F0aW9uIHRvIHdvcmtzcGFjZSBpcyBnb25uYSBmZXRjaCBldmVyeXRoaW5nIG5lZWRlZCBmb3IgdGhlIHBhZ2UsIHNvIHdlIG9ubHlcclxuICAgICAgICAgIC8vIHJlYWxseSBuZWVkIHRvIHVwZGF0ZSB3b3Jrc3BhY2UgZmllbGRzIHVzZWQgaW4gc2lkZWJhciAmIHNldHRpbmdzOiBVc2VyLndvcmtzcGFjZXNcclxuICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnVXNlcicsIHVzZXJJZCksXHJcbiAgICAgICAgICAgICd3b3Jrc3BhY2VzJyxcclxuICAgICAgICAgICAgKHsgaGVscGVyczogeyBjcmVhdGVVcGRhdGVkVmFsdWUsIHJlZiB9IH0pID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlVXBkYXRlZFZhbHVlKCh7IHVwZGF0ZSB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgICB1cGRhdGUoJ3RvdGFsQ291bnQnLCAodG90YWxDb3VudCkgPT4gdG90YWxDb3VudCArIDEpXHJcbiAgICAgICAgICAgICAgICB1cGRhdGUoJ2l0ZW1zJywgKGl0ZW1zKSA9PiBbLi4uaXRlbXMsIHJlZignV29ya3NwYWNlJywgd29ya3NwYWNlSWQpXSlcclxuICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgYXV0b0V2aWN0RmlsdGVyZWQ6IHRydWVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAocmVzLmRhdGE/LndvcmtzcGFjZU11dGF0aW9ucy5jcmVhdGUuaWQpIHtcclxuICAgICAgaWYgKCFvcHRpb25zPy5oaWRlTm90aWZpY2F0aW9ucykge1xyXG4gICAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgICB0aXRsZTogJ1dvcmtzcGFjZSBzdWNjZXNzZnVsbHkgY3JlYXRlZCdcclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAob3B0aW9ucz8ubmF2aWdhdGVPblN1Y2Nlc3MgPT09IHRydWUpIHtcclxuICAgICAgICByb3V0ZXIucHVzaCh3b3Jrc3BhY2VSb3V0ZShyZXMuZGF0YT8ud29ya3NwYWNlTXV0YXRpb25zLmNyZWF0ZS5zbHVnKSlcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UocmVzLmVycm9ycylcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgICB0aXRsZTogJ1dvcmtzcGFjZSBjcmVhdGlvbiBmYWlsZWQnLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBlcnJcclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcmVzXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgdXNlV29ya3NwYWNlVXBkYXRlUm9sZSA9ICgpID0+IHtcclxuICBjb25zdCB7IG11dGF0ZSB9ID0gdXNlTXV0YXRpb24od29ya3NwYWNlVXBkYXRlUm9sZU11dGF0aW9uKVxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG4gIGNvbnN0IG1peHBhbmVsID0gdXNlTWl4cGFuZWwoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKGlucHV0OiBXb3Jrc3BhY2VSb2xlVXBkYXRlSW5wdXQpID0+IHtcclxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG11dGF0ZShcclxuICAgICAgeyBpbnB1dCB9LFxyXG4gICAgICB7XHJcbiAgICAgICAgdXBkYXRlOiAoY2FjaGUpID0+IHtcclxuICAgICAgICAgIGlmICghaW5wdXQucm9sZSkge1xyXG4gICAgICAgICAgICBjYWNoZS5ldmljdCh7XHJcbiAgICAgICAgICAgICAgaWQ6IGdldENhY2hlSWQoJ1dvcmtzcGFjZUNvbGxhYm9yYXRvcicsIGlucHV0LnVzZXJJZClcclxuICAgICAgICAgICAgfSlcclxuXHJcbiAgICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICAgIGdldENhY2hlSWQoJ1dvcmtzcGFjZScsIGlucHV0LndvcmtzcGFjZUlkKSxcclxuICAgICAgICAgICAgICAndGVhbScsXHJcbiAgICAgICAgICAgICAgKHsgaGVscGVyczogeyBjcmVhdGVVcGRhdGVkVmFsdWUgfSB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlVXBkYXRlZFZhbHVlKCh7IHVwZGF0ZSB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZSgndG90YWxDb3VudCcsICh0b3RhbENvdW50KSA9PiB0b3RhbENvdW50IC0gMSlcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBhdXRvRXZpY3RGaWx0ZXJlZDogdHJ1ZVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnV29ya3NwYWNlJywgaW5wdXQud29ya3NwYWNlSWQpLFxyXG4gICAgICAgICAgICAndGVhbUJ5Um9sZScsXHJcbiAgICAgICAgICAgICh7IGhlbHBlcnM6IHsgZXZpY3QgfSB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGV2aWN0KClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGQoXHJcbiAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICBnZXRDYWNoZUlkKCdXb3Jrc3BhY2UnLCBpbnB1dC53b3Jrc3BhY2VJZCksXHJcbiAgICAgICAgICAgICd0ZWFtJyxcclxuICAgICAgICAgICAgKHsgaGVscGVyczogeyBldmljdCB9IH0pID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gZXZpY3QoKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICApXHJcbiAgICAgICAgICBtb2RpZnlPYmplY3RGaWVsZChcclxuICAgICAgICAgICAgY2FjaGUsXHJcbiAgICAgICAgICAgIGdldENhY2hlSWQoJ1dvcmtzcGFjZUNvbGxhYm9yYXRvcicsIGlucHV0LnVzZXJJZCksXHJcbiAgICAgICAgICAgICdzZWF0VHlwZScsXHJcbiAgICAgICAgICAgICgpID0+IFNlYXRUeXBlcy5FZGl0b3JcclxuICAgICAgICAgIClcclxuICAgICAgICAgIGlmIChpbnB1dC5yb2xlKSB7XHJcbiAgICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICAgIGdldENhY2hlSWQoJ1dvcmtzcGFjZUNvbGxhYm9yYXRvcicsIGlucHV0LnVzZXJJZCksXHJcbiAgICAgICAgICAgICAgJ3JvbGUnLFxyXG4gICAgICAgICAgICAgICgpID0+IGlucHV0LnJvbGUhXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICkuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChyZXN1bHQ/LmRhdGEpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6IGlucHV0LnJvbGUgPyAnVXNlciByb2xlIHVwZGF0ZWQnIDogJ1VzZXIgcmVtb3ZlZCcsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGlucHV0LnJvbGVcclxuICAgICAgICAgID8gJ1RoZSB1c2VyIHJvbGUgaGFzIGJlZW4gdXBkYXRlZCdcclxuICAgICAgICAgIDogJ1RoZSB1c2VyIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgd29ya3NwYWNlJ1xyXG4gICAgICB9KVxyXG5cclxuICAgICAgaWYgKGlucHV0LnJvbGUpIHtcclxuICAgICAgICBtaXhwYW5lbC50cmFjaygnV29ya3NwYWNlIFVzZXIgUm9sZSBVcGRhdGVkJywge1xyXG4gICAgICAgICAgbmV3Um9sZTogaW5wdXQucm9sZSxcclxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcclxuICAgICAgICAgIHdvcmtzcGFjZV9pZDogaW5wdXQud29ya3NwYWNlSWRcclxuICAgICAgICB9KVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG1peHBhbmVsLnRyYWNrKCdXb3Jrc3BhY2UgVXNlciBSZW1vdmVkJywge1xyXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxyXG4gICAgICAgICAgd29ya3NwYWNlX2lkOiBpbnB1dC53b3Jrc3BhY2VJZFxyXG4gICAgICAgIH0pXHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGdldEZpcnN0RXJyb3JNZXNzYWdlKHJlc3VsdD8uZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiBpbnB1dC5yb2xlID8gJ0ZhaWxlZCB0byB1cGRhdGUgcm9sZScgOiAnRmFpbGVkIHRvIHJlbW92ZSB1c2VyJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyb3JNZXNzYWdlXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgdXNlV29ya3NwYWNlVXBkYXRlU2VhdFR5cGUgPSAoKSA9PiB7XHJcbiAgY29uc3QgeyBtdXRhdGUgfSA9IHVzZU11dGF0aW9uKHdvcmtzcGFjZXNVcGRhdGVTZWF0VHlwZU11dGF0aW9uKVxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG4gIGNvbnN0IG1peHBhbmVsID0gdXNlTWl4cGFuZWwoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKFxyXG4gICAgaW5wdXQ6IHtcclxuICAgICAgdXNlcklkOiBzdHJpbmdcclxuICAgICAgd29ya3NwYWNlSWQ6IHN0cmluZ1xyXG4gICAgICBzZWF0VHlwZTogV29ya3NwYWNlU2VhdFR5cGVcclxuICAgIH0sXHJcbiAgICBvcHRpb25zPzogeyBoaWRlTm90aWZpY2F0aW9uczogYm9vbGVhbiB9XHJcbiAgKSA9PiB7XHJcbiAgICBjb25zdCB7IGhpZGVOb3RpZmljYXRpb25zIH0gPSBvcHRpb25zID8/IHt9XHJcblxyXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbXV0YXRlKFxyXG4gICAgICB7IGlucHV0IH0sXHJcbiAgICAgIHtcclxuICAgICAgICB1cGRhdGU6IChjYWNoZSkgPT4ge1xyXG4gICAgICAgICAgLy8gVXBkYXRlIHRoZSB0ZWFtIG1lbWJlcidzIHNlYXQgdHlwZSBpbiB0aGUgY2FjaGVcclxuICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnV29ya3NwYWNlQ29sbGFib3JhdG9yJywgaW5wdXQudXNlcklkKSxcclxuICAgICAgICAgICAgJ3NlYXRUeXBlJyxcclxuICAgICAgICAgICAgKCkgPT4gaW5wdXQuc2VhdFR5cGVcclxuICAgICAgICAgIClcclxuICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnV29ya3NwYWNlJywgaW5wdXQud29ya3NwYWNlSWQpLFxyXG4gICAgICAgICAgICAndGVhbScsXHJcbiAgICAgICAgICAgICh7IGhlbHBlcnM6IHsgZXZpY3QgfSB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGV2aWN0KClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgKS5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgaWYgKHJlc3VsdD8uZGF0YSkge1xyXG4gICAgICBpZiAoIWhpZGVOb3RpZmljYXRpb25zKSB7XHJcbiAgICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuU3VjY2VzcyxcclxuICAgICAgICAgIHRpdGxlOiAnU2VhdCB1cGRhdGVkJyxcclxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhlIHVzZXIncyBzZWF0IGhhcyBiZWVuIHVwZGF0ZWQgdG8gJHtpbnB1dC5zZWF0VHlwZX1gXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG5cclxuICAgICAgbWl4cGFuZWwudHJhY2soJ1dvcmtzcGFjZSBVc2VyIFNlYXQgVHlwZSBVcGRhdGVkJywge1xyXG4gICAgICAgIG5ld1NlYXRUeXBlOiBpbnB1dC5zZWF0VHlwZSxcclxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXHJcbiAgICAgICAgd29ya3NwYWNlX2lkOiBpbnB1dC53b3Jrc3BhY2VJZFxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UocmVzdWx0Py5lcnJvcnMpXHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6ICdGYWlsZWQgdG8gdXBkYXRlIHNlYXQgdHlwZScsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGVycm9yTWVzc2FnZVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGNvcHlXb3Jrc3BhY2VMaW5rID0gYXN5bmMgKHNsdWc6IHN0cmluZykgPT4ge1xyXG4gIGNvbnN0IHsgY29weSB9ID0gdXNlQ2xpcGJvYXJkKClcclxuXHJcbiAgY29uc3QgdXJsID0gbmV3IFVSTCh3b3Jrc3BhY2VSb3V0ZShzbHVnKSwgd2luZG93LmxvY2F0aW9uLnRvU3RyaW5nKCkpLnRvU3RyaW5nKClcclxuXHJcbiAgYXdhaXQgY29weSh1cmwsIHtcclxuICAgIHN1Y2Nlc3NNZXNzYWdlOiAnQ29waWVkIHdvcmtzcGFjZSBsaW5rIHRvIGNsaXBib2FyZCdcclxuICB9KVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgdXNlU2V0RGVmYXVsdFdvcmtzcGFjZVJlZ2lvbiA9ICgpID0+IHtcclxuICBjb25zdCB7IG11dGF0ZSB9ID0gdXNlTXV0YXRpb24oc2V0RGVmYXVsdFJlZ2lvbk11dGF0aW9uKVxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKHBhcmFtczogeyB3b3Jrc3BhY2VJZDogc3RyaW5nOyByZWdpb25LZXk6IHN0cmluZyB9KSA9PiB7XHJcbiAgICBjb25zdCB7IHdvcmtzcGFjZUlkLCByZWdpb25LZXkgfSA9IHBhcmFtc1xyXG4gICAgY29uc3QgcmVzID0gYXdhaXQgbXV0YXRlKHsgd29ya3NwYWNlSWQsIHJlZ2lvbktleSB9KS5jYXRjaChcclxuICAgICAgY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0XHJcbiAgICApXHJcblxyXG4gICAgaWYgKHJlcz8uZGF0YT8ud29ya3NwYWNlTXV0YXRpb25zLnNldERlZmF1bHRSZWdpb24pIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6ICdEZWZhdWx0IHJlZ2lvbiBzZXQgc3VjY2Vzc2Z1bGx5J1xyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UocmVzPy5lcnJvcnMpXHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6ICdGYWlsZWQgdG8gc2V0IGRlZmF1bHQgcmVnaW9uJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlcz8uZGF0YT8ud29ya3NwYWNlTXV0YXRpb25zLnNldERlZmF1bHRSZWdpb25cclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCB1c2VPbldvcmtzcGFjZVVwZGF0ZWQgPSAocGFyYW1zOiB7XHJcbiAgd29ya3NwYWNlU2x1ZzogUmVmPHN0cmluZz5cclxuICAvKipcclxuICAgKiBPcHRpb25hbGx5IGRvIGV4dHJhIHdvcmsgb24gZWFjaCBtZXNzYWdlLCBiZXNpZGVzIHRoZSBtYWluIGNhY2hlIHVwZGF0ZVxyXG4gICAqL1xyXG4gIGhhbmRsZXI/OiAoXHJcbiAgICBkYXRhOiBOb25OdWxsYWJsZTxHZXQ8T25Xb3Jrc3BhY2VVcGRhdGVkU3Vic2NyaXB0aW9uLCAnd29ya3NwYWNlVXBkYXRlZCc+PixcclxuICAgIGNhY2hlOiBBcG9sbG9DYWNoZTx1bmtub3duPlxyXG4gICkgPT4gdm9pZFxyXG59KSA9PiB7XHJcbiAgY29uc3QgeyB3b3Jrc3BhY2VTbHVnLCBoYW5kbGVyIH0gPSBwYXJhbXNcclxuXHJcbiAgY29uc3QgYXBvbGxvID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgeyBoYXNMb2NrIH0gPSB1c2VMb2NrKFxyXG4gICAgY29tcHV0ZWQoKCkgPT4gYHVzZU9uV29ya3NwYWNlVXBkYXRlZC0ke3VucmVmKHdvcmtzcGFjZVNsdWcudmFsdWUpfWApXHJcbiAgKVxyXG4gIGNvbnN0IGVuYWJsZWQgPSBjb21wdXRlZCgoKSA9PiAhIShoYXNMb2NrLnZhbHVlIHx8IGhhbmRsZXIpKVxyXG4gIGNvbnN0IHsgb25SZXN1bHQgfSA9IHVzZVN1YnNjcmlwdGlvbihcclxuICAgIG9uV29ya3NwYWNlVXBkYXRlZFN1YnNjcmlwdGlvbixcclxuICAgICgpID0+ICh7XHJcbiAgICAgIHdvcmtzcGFjZVNsdWc6IHBhcmFtcy53b3Jrc3BhY2VTbHVnLnZhbHVlXHJcbiAgICB9KSxcclxuICAgICgpID0+ICh7XHJcbiAgICAgIGVuYWJsZWQ6IGVuYWJsZWQudmFsdWUsXHJcbiAgICAgIGVycm9yUG9saWN5OiAnYWxsJ1xyXG4gICAgfSlcclxuICApXHJcblxyXG4gIC8vIE1haW4sIGxvY2tlZCBjYWNoZSB1cGRhdGVcclxuICBvblJlc3VsdCgocmVzdWx0KSA9PiB7XHJcbiAgICBpZiAoIXJlc3VsdC5kYXRhPy53b3Jrc3BhY2VVcGRhdGVkIHx8ICFoYXNMb2NrLnZhbHVlKSByZXR1cm5cclxuICB9KVxyXG5cclxuICAvLyBPcHRpb25hbCBoYW5kbGVyXHJcbiAgaWYgKGhhbmRsZXIpIHtcclxuICAgIG9uUmVzdWx0KChyZXN1bHQpID0+IHtcclxuICAgICAgaWYgKCFyZXN1bHQuZGF0YT8ud29ya3NwYWNlVXBkYXRlZCkgcmV0dXJuXHJcbiAgICAgIGhhbmRsZXIocmVzdWx0LmRhdGEud29ya3NwYWNlVXBkYXRlZCwgYXBvbGxvLmNhY2hlKVxyXG4gICAgfSlcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCB1c2VXb3Jrc3BhY2VMYXN0QWRtaW5DaGVjayA9IChwYXJhbXM6IHtcclxuICB3b3Jrc3BhY2VTbHVnOiBSZWY8TWF5YmVOdWxsT3JVbmRlZmluZWQ8c3RyaW5nPj5cclxufSkgPT4ge1xyXG4gIGNvbnN0IHsgd29ya3NwYWNlU2x1ZyB9ID0gcGFyYW1zXHJcblxyXG4gIGNvbnN0IHsgcmVzdWx0IH0gPSB1c2VRdWVyeShcclxuICAgIHdvcmtzcGFjZUxhc3RBZG1pbkNoZWNrUXVlcnksXHJcbiAgICAoKSA9PiAoe1xyXG4gICAgICBzbHVnOiB3b3Jrc3BhY2VTbHVnLnZhbHVlIHx8ICcnXHJcbiAgICB9KSxcclxuICAgICgpID0+ICh7XHJcbiAgICAgIGVuYWJsZWQ6ICEhd29ya3NwYWNlU2x1Zy52YWx1ZVxyXG4gICAgfSlcclxuICApXHJcblxyXG4gIGNvbnN0IGlzTGFzdEFkbWluID0gY29tcHV0ZWQoXHJcbiAgICAoKSA9PiByZXN1bHQudmFsdWU/LndvcmtzcGFjZUJ5U2x1Zz8udGVhbUJ5Um9sZT8uYWRtaW5zPy50b3RhbENvdW50ID09PSAxXHJcbiAgKVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgaXNMYXN0QWRtaW5cclxuICB9XHJcbn1cclxuIl0sImZpbGUiOiJEOi9zcGVja2xlLXNlcnZlci9wYWNrYWdlcy9mcm9udGVuZC0yL2xpYi93b3Jrc3BhY2VzL2NvbXBvc2FibGVzL21hbmFnZW1lbnQudHMifQ== |