import { useApolloClient, useMutation, useSubscription } from "/_nuxt/node_modules/@vue/apollo-composable/dist/index.mjs?v=e4f18c29"; import { useActiveUser } from "/_nuxt/lib/auth/composables/activeUser.ts"; import { useLock } from "/_nuxt/lib/common/composables/singleton.ts"; import { ToastNotificationType, useGlobalToast } from "/_nuxt/lib/common/composables/toast.ts"; import { ProjectUpdatedMessageType } from "/_nuxt/lib/common/generated/gql/graphql.ts"; import { convertThrowIntoFetchResult, getCacheId, getFirstErrorMessage, modifyObjectField, modifyObjectFields } from "/_nuxt/lib/common/helpers/graphql.ts"; import { useNavigateToHome, workspaceRoute, projectRoute } from "/_nuxt/lib/common/helpers/route.ts"; import { cancelProjectInviteMutation, createProjectMutation, deleteProjectMutation, inviteProjectUserMutation, inviteWorkspaceProjectUserMutation, leaveProjectMutation, updateProjectMetadataMutation, updateProjectRoleMutation, updateWorkspaceProjectRoleMutation, useProjectInviteMutation, useMoveProjectToWorkspaceMutation, createWorkspaceProjectMutation } from "/_nuxt/lib/projects/graphql/mutations.ts"; import { onProjectUpdatedSubscription } from "/_nuxt/lib/projects/graphql/subscriptions.ts"; import { useMixpanel } from "/_nuxt/lib/core/composables/mp.ts"; import { useRouter } from "/_nuxt/node_modules/vue-router/dist/vue-router.mjs?v=e4f18c29"; import { computed, unref, ref } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; import { ROOT_QUERY } from "/_nuxt/utils/globals.ts"; import { useIsWorkspacesEnabled } from "/_nuxt/composables/globals.ts"; import { useClipboard } from "/_nuxt/composables/browser.ts"; export function useProjectUpdateTracking(projectId, handler, options) { const { redirectOnDeletion, notifyOnUpdate } = options || {}; const goHome = useNavigateToHome(); const { triggerNotification } = useGlobalToast(); const apollo = useApolloClient().client; const { hasLock } = useLock( computed(() => `useProjectUpdateTracking-${unref(projectId)}`) ); const isEnabled = computed(() => !!(hasLock.value || handler)); const { onResult: onProjectUpdated } = useSubscription( onProjectUpdatedSubscription, () => ({ id: unref(projectId) }), { enabled: isEnabled, errorPolicy: "all" } ); onProjectUpdated((res) => { if (!res.data?.projectUpdated || !hasLock.value) return; const event = res.data.projectUpdated; const cache = apollo.cache; const isDeleted = event.type === ProjectUpdatedMessageType.Deleted; if (isDeleted) { cache.evict({ id: getCacheId("Project", event.id) }); if (redirectOnDeletion) { goHome(); } if (redirectOnDeletion || notifyOnUpdate) { triggerNotification({ type: ToastNotificationType.Info, title: isDeleted ? "Project deleted" : "Project updated" }); } } }); onProjectUpdated((res) => { if (!res.data?.projectUpdated) return; const event = res.data.projectUpdated; handler?.(event, apollo.cache); }); } export function useCreateProject() { const apollo = useApolloClient().client; const { triggerNotification } = useGlobalToast(); const { activeUser } = useActiveUser(); return async (input) => { const userId = activeUser.value?.id; if (!userId) return; const res = await apollo.mutate({ ..."workspaceId" in input ? { mutation: createWorkspaceProjectMutation, variables: { input } } : { mutation: createProjectMutation, variables: { input } }, update: (cache, { data }) => { const typedData2 = data; if (!typedData2) return; modifyObjectFields( cache, ROOT_QUERY, (_fieldName, _variables, value, details) => { const projectListFields = Object.keys(value).filter( (k) => details.revolveFieldNameAndVariables(k).fieldName === "projectList" ); const newVal = { ...value }; for (const field of projectListFields) { delete newVal[field]; } return newVal; }, { fieldNameWhitelist: ["admin"] } ); } }).catch(convertThrowIntoFetchResult); const typedData = res.data; const newProject = typedData ? "projectMutations" in typedData ? typedData.projectMutations.create : typedData.workspaceMutations.projects.create : void 0; if (!newProject?.id) { const err = getFirstErrorMessage(res.errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Project creation failed", description: err }); } return newProject; }; } export function useUpdateUserRole(project) { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); const isWorkspacesEnabled = useIsWorkspacesEnabled(); const updateProjectRole = async (input) => { const userId = activeUser.value?.id; if (!userId) return; const { data, errors } = await apollo.mutate({ mutation: updateProjectRoleMutation, variables: { input } }).catch(convertThrowIntoFetchResult); if (!data?.projectMutations.updateRole.id) { const err = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Permission update failed", description: err }); } else { triggerNotification({ type: ToastNotificationType.Success, title: input.role ? "Project role updated" : "User removed from project" }); } return data?.projectMutations.updateRole; }; const updateWorkspaceProjectRole = async (input) => { const userId = activeUser.value?.id; if (!userId) return; const { data, errors } = await apollo.mutate({ mutation: updateWorkspaceProjectRoleMutation, variables: { input }, update: (cache) => { cache.evict({ id: getCacheId("Project", input.projectId) }); cache.evict({ id: getCacheId("WorkspaceCollaborator", input.userId) }); } }).catch(convertThrowIntoFetchResult); if (!data?.workspaceMutations.projects.updateRole.id) { const err = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Permission update failed", description: err }); } else { triggerNotification({ type: ToastNotificationType.Success, title: input.role ? "Project role updated" : "User removed from project" }); } return data?.workspaceMutations.projects; }; const isWorkspaceProject = isWorkspacesEnabled.value && project?.value?.workspaceId?.length; return isWorkspaceProject ? updateWorkspaceProjectRole : updateProjectRole; } export function useInviteUserToProject() { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); return async (projectId, input, options) => { const userId = activeUser.value?.id; const { hideToasts } = options || {}; if (!userId) return; const isWorkspaceInput = (input2) => { return input2.some((i) => "workspaceRole" in i); }; let res = void 0; let err = void 0; if (isWorkspaceInput(input)) { const { data, errors } = await apollo.mutate({ mutation: inviteWorkspaceProjectUserMutation, variables: { inputs: input, projectId } }).catch(convertThrowIntoFetchResult); res = data?.projectMutations.invites.createForWorkspace; err = !res?.id ? getFirstErrorMessage(errors) : void 0; } else { const { data, errors } = await apollo.mutate({ mutation: inviteProjectUserMutation, variables: { input, projectId } }).catch(convertThrowIntoFetchResult); res = data?.projectMutations.invites.batchCreate; err = !res?.id ? getFirstErrorMessage(errors) : void 0; } if (err && !hideToasts) { triggerNotification({ type: ToastNotificationType.Danger, title: input.length > 1 ? "Couldn't send project invites" : "Couldn't send project invite", description: err }); } else { if (!hideToasts) { triggerNotification({ type: ToastNotificationType.Success, title: input.length > 1 ? "Project invites successfully sent" : "Project invite successfully sent" }); } } if (hideToasts && err) { throw new Error(err); } return res; }; } export function useCancelProjectInvite() { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); return async (input) => { const userId = activeUser.value?.id; if (!userId) return; const { data, errors } = await apollo.mutate({ mutation: cancelProjectInviteMutation, variables: input }).catch(convertThrowIntoFetchResult); if (!data?.projectMutations.invites.cancel) { const err = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Invitation cancelation failed", description: err }); } else { triggerNotification({ type: ToastNotificationType.Info, title: "Invitation canceled" }); } return data?.projectMutations.invites.cancel; }; } export function useUpdateProject() { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); return async (update, options) => { if (!activeUser.value) return; const successMessage = options?.customSuccessMessage || "Project updated"; const result = await apollo.mutate({ mutation: updateProjectMetadataMutation, variables: { update }, optimisticResponse: options?.optimisticResponse }).catch(convertThrowIntoFetchResult); if (result?.data?.projectMutations.update?.id) { triggerNotification({ type: ToastNotificationType.Success, title: successMessage }); } else { const errMsg = getFirstErrorMessage(result.errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Project update failed", description: errMsg }); } return result.data?.projectMutations.update; }; } export function useDeleteProject() { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); const navigateHome = useNavigateToHome(); const router = useRouter(); return async (id, options) => { if (!activeUser.value) return; const { goHome, workspaceSlug } = options || {}; const result = await apollo.mutate({ mutation: deleteProjectMutation, variables: { id } }).catch(convertThrowIntoFetchResult); if (result?.data?.projectMutations.delete) { if (goHome) { if (workspaceSlug) { router.push(workspaceRoute(workspaceSlug)); } else { navigateHome(); } } apollo.cache.evict({ id: getCacheId("Project", id) }); } else { const errMsg = getFirstErrorMessage(result.errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Project deletion failed", description: errMsg }); } return !!result.data?.projectMutations.delete; }; } export function useProcessProjectInvite() { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); return async (input, options) => { if (!activeUser.value) return; const { data, errors } = await apollo.mutate({ mutation: useProjectInviteMutation, variables: { input }, update: (cache, { data: data2 }) => { if (!data2?.projectMutations.invites.use) return; if (options?.inviteId) { cache.evict({ id: getCacheId("PendingStreamCollaborator", options.inviteId) }); cache.evict({ id: getCacheId("PendingWorkspaceCollaborator", options.inviteId) }); } } }).catch(convertThrowIntoFetchResult); if (!options?.skipToast) { if (data?.projectMutations.invites.use) { triggerNotification({ type: input.accept ? ToastNotificationType.Success : ToastNotificationType.Info, title: input.accept ? "Project invite accepted" : "Project invite dismissed" }); } else { const errMsg = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Couldn't process project invite", description: errMsg }); } } return data?.projectMutations.invites.use; }; } export function useLeaveProject() { const apollo = useApolloClient().client; const { activeUser } = useActiveUser(); const { triggerNotification } = useGlobalToast(); const navigateHome = useNavigateToHome(); return async (projectId, options) => { if (!activeUser.value) return; const { data, errors } = await apollo.mutate({ mutation: leaveProjectMutation, variables: { projectId }, update: (cache, { data: data2 }) => { if (!data2?.projectMutations.leave) return; cache.evict({ id: getCacheId("Project", projectId) }); } }).catch(convertThrowIntoFetchResult); if (data?.projectMutations.leave) { triggerNotification({ type: ToastNotificationType.Info, title: "You've left the project" }); if (options?.goHome) navigateHome(); } else { const errMsg = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Couldn't leave project", description: errMsg }); } }; } export function useMoveProjectToWorkspace() { const { triggerNotification } = useGlobalToast(); const mixpanel = useMixpanel(); const { mutate } = useMutation(useMoveProjectToWorkspaceMutation); const { activeUser } = useActiveUser(); return async (params) => { const userId = activeUser.value?.id; if (!userId) return; const { projectId, workspaceId, workspaceName, eventSource } = params; const res = await mutate( { projectId, workspaceId }, { update: (cache, { data }) => { if (!data?.workspaceMutations.projects.moveToWorkspace) return; if (!workspaceId) return; modifyObjectField( cache, getCacheId("Workspace", workspaceId), "projects", ({ helpers: { createUpdatedValue, ref } }) => { return createUpdatedValue(({ update }) => { update("items", (items) => [ref("Project", projectId), ...items]); }); } ); modifyObjectField( cache, getCacheId("User", userId), "projects", ({ variables, helpers: { createUpdatedValue, ref } }) => { if (!variables.filter?.personalOnly) return; return createUpdatedValue(({ update }) => { update( "items", (items) => items.filter((item) => item.__ref !== ref("Project", projectId).__ref) ); }); } ); } } ).catch(convertThrowIntoFetchResult); if (res?.data?.workspaceMutations.projects.moveToWorkspace.id) { triggerNotification({ type: ToastNotificationType.Success, title: `Moved project to ${workspaceName}` }); mixpanel.track("Project Moved To Workspace", { projectId, // eslint-disable-next-line camelcase workspace_id: workspaceId, source: eventSource }); } else { const errMsg = getFirstErrorMessage(res?.errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Couldn't move project", description: errMsg }); } return res?.data?.workspaceMutations.projects.moveToWorkspace; }; } export function useCopyProjectLink() { const { copy } = useClipboard(); const { triggerNotification } = useGlobalToast(); return async (projectId) => { if (false) { throw new Error("Not supported in SSR"); } const path = projectRoute(projectId); const url = new URL(path, window.location.toString()).toString(); await copy(url); triggerNotification({ type: ToastNotificationType.Success, title: "Project link copied to clipboard" }); }; } //# sourceMappingURL=data:application/json;base64,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bUJBQW1CLFNBQVM7QUFBQSxFQUNoRDtBQUNGO0FBRU8sZ0JBQVMscUJBQXFCO0FBQ25DLFFBQU0sRUFBRSxLQUFLLElBQUksYUFBYTtBQUM5QixRQUFNLEVBQUUsb0JBQW9CLElBQUksZUFBZTtBQUUvQyxTQUFPLE9BQU8sY0FBc0I7QUFDbEMsUUFBSSxLQUFZLEVBQVE7QUFDdEIsWUFBTSxJQUFJLE1BQU0sc0JBQXNCO0FBQUEsSUFDeEM7QUFFQSxVQUFNLE9BQU8sYUFBYSxTQUFTO0FBQ25DLFVBQU0sTUFBTSxJQUFJLElBQUksTUFBTSxPQUFPLFNBQVMsU0FBUyxDQUFDLEVBQUUsU0FBUztBQUUvRCxVQUFNLEtBQUssR0FBRztBQUNkLHdCQUFvQjtBQUFBLE1BQ2xCLE1BQU0sc0JBQXNCO0FBQUEsTUFDNUIsT0FBTztBQUFBLElBQ1QsQ0FBQztBQUFBLEVBQ0g7QUFDRiIsIm5hbWVzIjpbInR5cGVkRGF0YSIsImlucHV0IiwiZGF0YSJdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJwcm9qZWN0TWFuYWdlbWVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEFwb2xsb0NhY2hlIH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY29yZSdcclxuaW1wb3J0IHR5cGUgeyBPcHRpb25hbCB9IGZyb20gJ0BzcGVja2xlL3NoYXJlZCdcclxuaW1wb3J0IHsgdXNlQXBvbGxvQ2xpZW50LCB1c2VNdXRhdGlvbiwgdXNlU3Vic2NyaXB0aW9uIH0gZnJvbSAnQHZ1ZS9hcG9sbG8tY29tcG9zYWJsZSdcclxuaW1wb3J0IHR5cGUgeyBNYXliZVJlZiB9IGZyb20gJ0B2dWV1c2UvY29yZSdcclxuaW1wb3J0IHR5cGUgeyBHZXQgfSBmcm9tICd0eXBlLWZlc3QnXHJcbmltcG9ydCB7IHVzZUFjdGl2ZVVzZXIgfSBmcm9tICd+fi9saWIvYXV0aC9jb21wb3NhYmxlcy9hY3RpdmVVc2VyJ1xyXG5pbXBvcnQgeyB1c2VMb2NrIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9jb21wb3NhYmxlcy9zaW5nbGV0b24nXHJcbmltcG9ydCB7IFRvYXN0Tm90aWZpY2F0aW9uVHlwZSwgdXNlR2xvYmFsVG9hc3QgfSBmcm9tICd+fi9saWIvY29tbW9uL2NvbXBvc2FibGVzL3RvYXN0J1xyXG5pbXBvcnQgeyBQcm9qZWN0VXBkYXRlZE1lc3NhZ2VUeXBlIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcbmltcG9ydCB0eXBlIHtcclxuICBPblByb2plY3RVcGRhdGVkU3Vic2NyaXB0aW9uLFxyXG4gIFByb2plY3RDcmVhdGVJbnB1dCxcclxuICBQcm9qZWN0SW52aXRlQ3JlYXRlSW5wdXQsXHJcbiAgUHJvamVjdEludml0ZVVzZUlucHV0LFxyXG4gIFByb2plY3RVcGRhdGVJbnB1dCxcclxuICBQcm9qZWN0VXBkYXRlUm9sZUlucHV0LFxyXG4gIFVwZGF0ZVByb2plY3RNZXRhZGF0YU11dGF0aW9uLFxyXG4gIFdvcmtzcGFjZVByb2plY3RJbnZpdGVDcmVhdGVJbnB1dCxcclxuICBJbnZpdGVQcm9qZWN0VXNlck11dGF0aW9uLFxyXG4gIFByb2plY3QsXHJcbiAgV29ya3NwYWNlUHJvamVjdENyZWF0ZUlucHV0LFxyXG4gIENyZWF0ZVdvcmtzcGFjZVByb2plY3RNdXRhdGlvbixcclxuICBDcmVhdGVQcm9qZWN0TXV0YXRpb24sXHJcbiAgQWRtaW5QYW5lbFByb2plY3RzTGlzdFF1ZXJ5XHJcbn0gZnJvbSAnfn4vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcbmltcG9ydCB7XHJcbiAgY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0LFxyXG4gIGdldENhY2hlSWQsXHJcbiAgZ2V0Rmlyc3RFcnJvck1lc3NhZ2UsXHJcbiAgbW9kaWZ5T2JqZWN0RmllbGQsXHJcbiAgbW9kaWZ5T2JqZWN0RmllbGRzXHJcbn0gZnJvbSAnfn4vbGliL2NvbW1vbi9oZWxwZXJzL2dyYXBocWwnXHJcbmltcG9ydCB7XHJcbiAgdXNlTmF2aWdhdGVUb0hvbWUsXHJcbiAgd29ya3NwYWNlUm91dGUsXHJcbiAgcHJvamVjdFJvdXRlXHJcbn0gZnJvbSAnfn4vbGliL2NvbW1vbi9oZWxwZXJzL3JvdXRlJ1xyXG5pbXBvcnQge1xyXG4gIGNhbmNlbFByb2plY3RJbnZpdGVNdXRhdGlvbixcclxuICBjcmVhdGVQcm9qZWN0TXV0YXRpb24sXHJcbiAgZGVsZXRlUHJvamVjdE11dGF0aW9uLFxyXG4gIGludml0ZVByb2plY3RVc2VyTXV0YXRpb24sXHJcbiAgaW52aXRlV29ya3NwYWNlUHJvamVjdFVzZXJNdXRhdGlvbixcclxuICBsZWF2ZVByb2plY3RNdXRhdGlvbixcclxuICB1cGRhdGVQcm9qZWN0TWV0YWRhdGFNdXRhdGlvbixcclxuICB1cGRhdGVQcm9qZWN0Um9sZU11dGF0aW9uLFxyXG4gIHVwZGF0ZVdvcmtzcGFjZVByb2plY3RSb2xlTXV0YXRpb24sXHJcbiAgdXNlUHJvamVjdEludml0ZU11dGF0aW9uLFxyXG4gIHVzZU1vdmVQcm9qZWN0VG9Xb3Jrc3BhY2VNdXRhdGlvbixcclxuICBjcmVhdGVXb3Jrc3BhY2VQcm9qZWN0TXV0YXRpb25cclxufSBmcm9tICd+fi9saWIvcHJvamVjdHMvZ3JhcGhxbC9tdXRhdGlvbnMnXHJcbmltcG9ydCB7IG9uUHJvamVjdFVwZGF0ZWRTdWJzY3JpcHRpb24gfSBmcm9tICd+fi9saWIvcHJvamVjdHMvZ3JhcGhxbC9zdWJzY3JpcHRpb25zJ1xyXG5pbXBvcnQgeyB1c2VNaXhwYW5lbCB9IGZyb20gJ34vbGliL2NvcmUvY29tcG9zYWJsZXMvbXAnXHJcbmltcG9ydCB7IHVzZVJvdXRlciB9IGZyb20gJ3Z1ZS1yb3V0ZXInXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlUHJvamVjdFVwZGF0ZVRyYWNraW5nKFxyXG4gIHByb2plY3RJZDogTWF5YmVSZWY8c3RyaW5nPixcclxuICBoYW5kbGVyPzogKFxyXG4gICAgZGF0YTogTm9uTnVsbGFibGU8R2V0PE9uUHJvamVjdFVwZGF0ZWRTdWJzY3JpcHRpb24sICdwcm9qZWN0VXBkYXRlZCc+PixcclxuICAgIGNhY2hlOiBBcG9sbG9DYWNoZTx1bmtub3duPlxyXG4gICkgPT4gdm9pZCxcclxuICBvcHRpb25zPzogUGFydGlhbDx7XHJcbiAgICByZWRpcmVjdE9uRGVsZXRpb246IGJvb2xlYW5cclxuICAgIG5vdGlmeU9uVXBkYXRlPzogYm9vbGVhblxyXG4gIH0+XHJcbikge1xyXG4gIGNvbnN0IHsgcmVkaXJlY3RPbkRlbGV0aW9uLCBub3RpZnlPblVwZGF0ZSB9ID0gb3B0aW9ucyB8fCB7fVxyXG5cclxuICBjb25zdCBnb0hvbWUgPSB1c2VOYXZpZ2F0ZVRvSG9tZSgpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgYXBvbGxvID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgeyBoYXNMb2NrIH0gPSB1c2VMb2NrKFxyXG4gICAgY29tcHV0ZWQoKCkgPT4gYHVzZVByb2plY3RVcGRhdGVUcmFja2luZy0ke3VucmVmKHByb2plY3RJZCl9YClcclxuICApXHJcbiAgY29uc3QgaXNFbmFibGVkID0gY29tcHV0ZWQoKCkgPT4gISEoaGFzTG9jay52YWx1ZSB8fCBoYW5kbGVyKSlcclxuXHJcbiAgY29uc3QgeyBvblJlc3VsdDogb25Qcm9qZWN0VXBkYXRlZCB9ID0gdXNlU3Vic2NyaXB0aW9uKFxyXG4gICAgb25Qcm9qZWN0VXBkYXRlZFN1YnNjcmlwdGlvbixcclxuICAgICgpID0+ICh7XHJcbiAgICAgIGlkOiB1bnJlZihwcm9qZWN0SWQpXHJcbiAgICB9KSxcclxuICAgIHsgZW5hYmxlZDogaXNFbmFibGVkLCBlcnJvclBvbGljeTogJ2FsbCcgfVxyXG4gIClcclxuXHJcbiAgb25Qcm9qZWN0VXBkYXRlZCgocmVzKSA9PiB7XHJcbiAgICBpZiAoIXJlcy5kYXRhPy5wcm9qZWN0VXBkYXRlZCB8fCAhaGFzTG9jay52YWx1ZSkgcmV0dXJuXHJcblxyXG4gICAgY29uc3QgZXZlbnQgPSByZXMuZGF0YS5wcm9qZWN0VXBkYXRlZFxyXG4gICAgY29uc3QgY2FjaGUgPSBhcG9sbG8uY2FjaGVcclxuICAgIGNvbnN0IGlzRGVsZXRlZCA9IGV2ZW50LnR5cGUgPT09IFByb2plY3RVcGRhdGVkTWVzc2FnZVR5cGUuRGVsZXRlZFxyXG5cclxuICAgIGlmIChpc0RlbGV0ZWQpIHtcclxuICAgICAgY2FjaGUuZXZpY3Qoe1xyXG4gICAgICAgIGlkOiBnZXRDYWNoZUlkKCdQcm9qZWN0JywgZXZlbnQuaWQpXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICBpZiAocmVkaXJlY3RPbkRlbGV0aW9uKSB7XHJcbiAgICAgICAgZ29Ib21lKClcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHJlZGlyZWN0T25EZWxldGlvbiB8fCBub3RpZnlPblVwZGF0ZSkge1xyXG4gICAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkluZm8sXHJcbiAgICAgICAgICB0aXRsZTogaXNEZWxldGVkID8gJ1Byb2plY3QgZGVsZXRlZCcgOiAnUHJvamVjdCB1cGRhdGVkJ1xyXG4gICAgICAgIH0pXHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KVxyXG5cclxuICBvblByb2plY3RVcGRhdGVkKChyZXMpID0+IHtcclxuICAgIGlmICghcmVzLmRhdGE/LnByb2plY3RVcGRhdGVkKSByZXR1cm5cclxuICAgIGNvbnN0IGV2ZW50ID0gcmVzLmRhdGEucHJvamVjdFVwZGF0ZWRcclxuICAgIGhhbmRsZXI/LihldmVudCwgYXBvbGxvLmNhY2hlKVxyXG4gIH0pXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VDcmVhdGVQcm9qZWN0KCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcblxyXG4gIHJldHVybiBhc3luYyAoaW5wdXQ6IFByb2plY3RDcmVhdGVJbnB1dCB8IFdvcmtzcGFjZVByb2plY3RDcmVhdGVJbnB1dCkgPT4ge1xyXG4gICAgY29uc3QgdXNlcklkID0gYWN0aXZlVXNlci52YWx1ZT8uaWRcclxuICAgIGlmICghdXNlcklkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCBhcG9sbG9cclxuICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgLi4uKCd3b3Jrc3BhY2VJZCcgaW4gaW5wdXRcclxuICAgICAgICAgID8ge1xyXG4gICAgICAgICAgICAgIG11dGF0aW9uOiBjcmVhdGVXb3Jrc3BhY2VQcm9qZWN0TXV0YXRpb24sXHJcbiAgICAgICAgICAgICAgdmFyaWFibGVzOiB7IGlucHV0IH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgOiB7XHJcbiAgICAgICAgICAgICAgbXV0YXRpb246IGNyZWF0ZVByb2plY3RNdXRhdGlvbixcclxuICAgICAgICAgICAgICB2YXJpYWJsZXM6IHsgaW5wdXQgfVxyXG4gICAgICAgICAgICB9KSxcclxuICAgICAgICB1cGRhdGU6IChjYWNoZSwgeyBkYXRhIH0pID0+IHtcclxuICAgICAgICAgIGNvbnN0IHR5cGVkRGF0YSA9IGRhdGEgYXNcclxuICAgICAgICAgICAgfCBDcmVhdGVXb3Jrc3BhY2VQcm9qZWN0TXV0YXRpb25cclxuICAgICAgICAgICAgfCBDcmVhdGVQcm9qZWN0TXV0YXRpb25cclxuICAgICAgICAgIGlmICghdHlwZWREYXRhKSByZXR1cm5cclxuXHJcbiAgICAgICAgICBtb2RpZnlPYmplY3RGaWVsZHM8dW5kZWZpbmVkLCB7IFtrZXk6IHN0cmluZ106IEFkbWluUGFuZWxQcm9qZWN0c0xpc3RRdWVyeSB9PihcclxuICAgICAgICAgICAgY2FjaGUsXHJcbiAgICAgICAgICAgIFJPT1RfUVVFUlksXHJcbiAgICAgICAgICAgIChfZmllbGROYW1lLCBfdmFyaWFibGVzLCB2YWx1ZSwgZGV0YWlscykgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHByb2plY3RMaXN0RmllbGRzID0gT2JqZWN0LmtleXModmFsdWUpLmZpbHRlcihcclxuICAgICAgICAgICAgICAgIChrKSA9PlxyXG4gICAgICAgICAgICAgICAgICBkZXRhaWxzLnJldm9sdmVGaWVsZE5hbWVBbmRWYXJpYWJsZXMoaykuZmllbGROYW1lID09PSAncHJvamVjdExpc3QnXHJcbiAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgIGNvbnN0IG5ld1ZhbDogdHlwZW9mIHZhbHVlID0geyAuLi52YWx1ZSB9XHJcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiBwcm9qZWN0TGlzdEZpZWxkcykge1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIG5ld1ZhbFtmaWVsZF1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgcmV0dXJuIG5ld1ZhbFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWydhZG1pbiddIH1cclxuICAgICAgICAgIClcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgLy8gbm90IHN1cmUgd2h5IHRoaXMgaXNuJ3QgaGFwcGVuaW5nIGF1dG9tYXRpY2FsbHlcclxuICAgIGNvbnN0IHR5cGVkRGF0YSA9IHJlcy5kYXRhIGFzIE9wdGlvbmFsPFxyXG4gICAgICBDcmVhdGVXb3Jrc3BhY2VQcm9qZWN0TXV0YXRpb24gfCBDcmVhdGVQcm9qZWN0TXV0YXRpb25cclxuICAgID5cclxuXHJcbiAgICBjb25zdCBuZXdQcm9qZWN0ID0gdHlwZWREYXRhXHJcbiAgICAgID8gJ3Byb2plY3RNdXRhdGlvbnMnIGluIHR5cGVkRGF0YVxyXG4gICAgICAgID8gdHlwZWREYXRhLnByb2plY3RNdXRhdGlvbnMuY3JlYXRlXHJcbiAgICAgICAgOiB0eXBlZERhdGEud29ya3NwYWNlTXV0YXRpb25zLnByb2plY3RzLmNyZWF0ZVxyXG4gICAgICA6IHVuZGVmaW5lZFxyXG5cclxuICAgIGlmICghbmV3UHJvamVjdD8uaWQpIHtcclxuICAgICAgY29uc3QgZXJyID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UocmVzLmVycm9ycylcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgICB0aXRsZTogJ1Byb2plY3QgY3JlYXRpb24gZmFpbGVkJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG5ld1Byb2plY3RcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VVcGRhdGVVc2VyUm9sZShcclxuICBwcm9qZWN0PzogUmVmPFBpY2s8UHJvamVjdCwgJ3dvcmtzcGFjZUlkJz4gfCB1bmRlZmluZWQ+XHJcbikge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgaXNXb3Jrc3BhY2VzRW5hYmxlZCA9IHVzZUlzV29ya3NwYWNlc0VuYWJsZWQoKVxyXG5cclxuICBjb25zdCB1cGRhdGVQcm9qZWN0Um9sZSA9IGFzeW5jIChpbnB1dDogUHJvamVjdFVwZGF0ZVJvbGVJbnB1dCkgPT4ge1xyXG4gICAgY29uc3QgdXNlcklkID0gYWN0aXZlVXNlci52YWx1ZT8uaWRcclxuICAgIGlmICghdXNlcklkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiB1cGRhdGVQcm9qZWN0Um9sZU11dGF0aW9uLFxyXG4gICAgICAgIHZhcmlhYmxlczogeyBpbnB1dCB9XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgaWYgKCFkYXRhPy5wcm9qZWN0TXV0YXRpb25zLnVwZGF0ZVJvbGUuaWQpIHtcclxuICAgICAgY29uc3QgZXJyID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnUGVybWlzc2lvbiB1cGRhdGUgZmFpbGVkJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyXHJcbiAgICAgIH0pXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuU3VjY2VzcyxcclxuICAgICAgICB0aXRsZTogaW5wdXQucm9sZSA/ICdQcm9qZWN0IHJvbGUgdXBkYXRlZCcgOiAnVXNlciByZW1vdmVkIGZyb20gcHJvamVjdCdcclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZGF0YT8ucHJvamVjdE11dGF0aW9ucy51cGRhdGVSb2xlXHJcbiAgfVxyXG5cclxuICBjb25zdCB1cGRhdGVXb3Jrc3BhY2VQcm9qZWN0Um9sZSA9IGFzeW5jIChpbnB1dDogUHJvamVjdFVwZGF0ZVJvbGVJbnB1dCkgPT4ge1xyXG4gICAgY29uc3QgdXNlcklkID0gYWN0aXZlVXNlci52YWx1ZT8uaWRcclxuICAgIGlmICghdXNlcklkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiB1cGRhdGVXb3Jrc3BhY2VQcm9qZWN0Um9sZU11dGF0aW9uLFxyXG4gICAgICAgIHZhcmlhYmxlczogeyBpbnB1dCB9LFxyXG4gICAgICAgIHVwZGF0ZTogKGNhY2hlKSA9PiB7XHJcbiAgICAgICAgICBjYWNoZS5ldmljdCh7IGlkOiBnZXRDYWNoZUlkKCdQcm9qZWN0JywgaW5wdXQucHJvamVjdElkKSB9KVxyXG4gICAgICAgICAgY2FjaGUuZXZpY3Qoe1xyXG4gICAgICAgICAgICBpZDogZ2V0Q2FjaGVJZCgnV29ya3NwYWNlQ29sbGFib3JhdG9yJywgaW5wdXQudXNlcklkKVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgaWYgKCFkYXRhPy53b3Jrc3BhY2VNdXRhdGlvbnMucHJvamVjdHMudXBkYXRlUm9sZS5pZCkge1xyXG4gICAgICBjb25zdCBlcnIgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6ICdQZXJtaXNzaW9uIHVwZGF0ZSBmYWlsZWQnLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBlcnJcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzLFxyXG4gICAgICAgIHRpdGxlOiBpbnB1dC5yb2xlID8gJ1Byb2plY3Qgcm9sZSB1cGRhdGVkJyA6ICdVc2VyIHJlbW92ZWQgZnJvbSBwcm9qZWN0J1xyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkYXRhPy53b3Jrc3BhY2VNdXRhdGlvbnMucHJvamVjdHNcclxuICB9XHJcblxyXG4gIGNvbnN0IGlzV29ya3NwYWNlUHJvamVjdCA9XHJcbiAgICBpc1dvcmtzcGFjZXNFbmFibGVkLnZhbHVlICYmIHByb2plY3Q/LnZhbHVlPy53b3Jrc3BhY2VJZD8ubGVuZ3RoXHJcblxyXG4gIHJldHVybiBpc1dvcmtzcGFjZVByb2plY3QgPyB1cGRhdGVXb3Jrc3BhY2VQcm9qZWN0Um9sZSA6IHVwZGF0ZVByb2plY3RSb2xlXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VJbnZpdGVVc2VyVG9Qcm9qZWN0KCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcblxyXG4gIHJldHVybiBhc3luYyAoXHJcbiAgICBwcm9qZWN0SWQ6IHN0cmluZyxcclxuICAgIGlucHV0OiBQcm9qZWN0SW52aXRlQ3JlYXRlSW5wdXRbXSB8IFdvcmtzcGFjZVByb2plY3RJbnZpdGVDcmVhdGVJbnB1dFtdLFxyXG4gICAgb3B0aW9ucz86IHsgaGlkZVRvYXN0cz86IGJvb2xlYW4gfVxyXG4gICkgPT4ge1xyXG4gICAgY29uc3QgdXNlcklkID0gYWN0aXZlVXNlci52YWx1ZT8uaWRcclxuICAgIGNvbnN0IHsgaGlkZVRvYXN0cyB9ID0gb3B0aW9ucyB8fCB7fVxyXG4gICAgaWYgKCF1c2VySWQpIHJldHVyblxyXG5cclxuICAgIGNvbnN0IGlzV29ya3NwYWNlSW5wdXQgPSAoXHJcbiAgICAgIGlucHV0OiBQcm9qZWN0SW52aXRlQ3JlYXRlSW5wdXRbXSB8IFdvcmtzcGFjZVByb2plY3RJbnZpdGVDcmVhdGVJbnB1dFtdXHJcbiAgICApOiBpbnB1dCBpcyBXb3Jrc3BhY2VQcm9qZWN0SW52aXRlQ3JlYXRlSW5wdXRbXSA9PiB7XHJcbiAgICAgIHJldHVybiBpbnB1dC5zb21lKChpKSA9PiAnd29ya3NwYWNlUm9sZScgaW4gaSlcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcmVzOiBPcHRpb25hbDxcclxuICAgICAgSW52aXRlUHJvamVjdFVzZXJNdXRhdGlvblsncHJvamVjdE11dGF0aW9ucyddWydpbnZpdGVzJ11bJ2JhdGNoQ3JlYXRlJ11cclxuICAgID4gPSB1bmRlZmluZWRcclxuICAgIGxldCBlcnI6IE9wdGlvbmFsPHN0cmluZz4gPSB1bmRlZmluZWRcclxuICAgIGlmIChpc1dvcmtzcGFjZUlucHV0KGlucHV0KSkge1xyXG4gICAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgICBtdXRhdGlvbjogaW52aXRlV29ya3NwYWNlUHJvamVjdFVzZXJNdXRhdGlvbixcclxuICAgICAgICAgIHZhcmlhYmxlczogeyBpbnB1dHM6IGlucHV0LCBwcm9qZWN0SWQgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuICAgICAgcmVzID0gZGF0YT8ucHJvamVjdE11dGF0aW9ucy5pbnZpdGVzLmNyZWF0ZUZvcldvcmtzcGFjZVxyXG4gICAgICBlcnIgPSAhcmVzPy5pZCA/IGdldEZpcnN0RXJyb3JNZXNzYWdlKGVycm9ycykgOiB1bmRlZmluZWRcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IHsgZGF0YSwgZXJyb3JzIH0gPSBhd2FpdCBhcG9sbG9cclxuICAgICAgICAubXV0YXRlKHtcclxuICAgICAgICAgIG11dGF0aW9uOiBpbnZpdGVQcm9qZWN0VXNlck11dGF0aW9uLFxyXG4gICAgICAgICAgdmFyaWFibGVzOiB7IGlucHV0LCBwcm9qZWN0SWQgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuICAgICAgcmVzID0gZGF0YT8ucHJvamVjdE11dGF0aW9ucy5pbnZpdGVzLmJhdGNoQ3JlYXRlXHJcbiAgICAgIGVyciA9ICFyZXM/LmlkID8gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKSA6IHVuZGVmaW5lZFxyXG4gICAgfVxyXG5cclxuICAgIGlmIChlcnIgJiYgIWhpZGVUb2FzdHMpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgICB0aXRsZTpcclxuICAgICAgICAgIGlucHV0Lmxlbmd0aCA+IDFcclxuICAgICAgICAgICAgPyBcIkNvdWxkbid0IHNlbmQgcHJvamVjdCBpbnZpdGVzXCJcclxuICAgICAgICAgICAgOiBcIkNvdWxkbid0IHNlbmQgcHJvamVjdCBpbnZpdGVcIixcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyXHJcbiAgICAgIH0pXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoIWhpZGVUb2FzdHMpIHtcclxuICAgICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5TdWNjZXNzLFxyXG4gICAgICAgICAgdGl0bGU6XHJcbiAgICAgICAgICAgIGlucHV0Lmxlbmd0aCA+IDFcclxuICAgICAgICAgICAgICA/ICdQcm9qZWN0IGludml0ZXMgc3VjY2Vzc2Z1bGx5IHNlbnQnXHJcbiAgICAgICAgICAgICAgOiAnUHJvamVjdCBpbnZpdGUgc3VjY2Vzc2Z1bGx5IHNlbnQnXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChoaWRlVG9hc3RzICYmIGVycikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyKVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXNcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VDYW5jZWxQcm9qZWN0SW52aXRlKCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcblxyXG4gIHJldHVybiBhc3luYyAoaW5wdXQ6IHsgcHJvamVjdElkOiBzdHJpbmc7IGludml0ZUlkOiBzdHJpbmcgfSkgPT4ge1xyXG4gICAgY29uc3QgdXNlcklkID0gYWN0aXZlVXNlci52YWx1ZT8uaWRcclxuICAgIGlmICghdXNlcklkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBjYW5jZWxQcm9qZWN0SW52aXRlTXV0YXRpb24sXHJcbiAgICAgICAgdmFyaWFibGVzOiBpbnB1dFxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmICghZGF0YT8ucHJvamVjdE11dGF0aW9ucy5pbnZpdGVzLmNhbmNlbCkge1xyXG4gICAgICBjb25zdCBlcnIgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6ICdJbnZpdGF0aW9uIGNhbmNlbGF0aW9uIGZhaWxlZCcsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGVyclxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkluZm8sXHJcbiAgICAgICAgdGl0bGU6ICdJbnZpdGF0aW9uIGNhbmNlbGVkJ1xyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkYXRhPy5wcm9qZWN0TXV0YXRpb25zLmludml0ZXMuY2FuY2VsXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlVXBkYXRlUHJvamVjdCgpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IGFjdGl2ZVVzZXIgfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKFxyXG4gICAgdXBkYXRlOiBQcm9qZWN0VXBkYXRlSW5wdXQsXHJcbiAgICBvcHRpb25zPzogUGFydGlhbDx7XHJcbiAgICAgIGN1c3RvbVN1Y2Nlc3NNZXNzYWdlPzogc3RyaW5nXHJcbiAgICAgIG9wdGltaXN0aWNSZXNwb25zZTogVXBkYXRlUHJvamVjdE1ldGFkYXRhTXV0YXRpb25cclxuICAgIH0+XHJcbiAgKSA9PiB7XHJcbiAgICBpZiAoIWFjdGl2ZVVzZXIudmFsdWUpIHJldHVyblxyXG5cclxuICAgIGNvbnN0IHN1Y2Nlc3NNZXNzYWdlID0gb3B0aW9ucz8uY3VzdG9tU3VjY2Vzc01lc3NhZ2UgfHwgJ1Byb2plY3QgdXBkYXRlZCdcclxuXHJcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcG9sbG9cclxuICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgbXV0YXRpb246IHVwZGF0ZVByb2plY3RNZXRhZGF0YU11dGF0aW9uLFxyXG4gICAgICAgIHZhcmlhYmxlczogeyB1cGRhdGUgfSxcclxuICAgICAgICBvcHRpbWlzdGljUmVzcG9uc2U6IG9wdGlvbnM/Lm9wdGltaXN0aWNSZXNwb25zZVxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChyZXN1bHQ/LmRhdGE/LnByb2plY3RNdXRhdGlvbnMudXBkYXRlPy5pZCkge1xyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuU3VjY2VzcyxcclxuICAgICAgICB0aXRsZTogc3VjY2Vzc01lc3NhZ2VcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGVyck1zZyA9IGdldEZpcnN0RXJyb3JNZXNzYWdlKHJlc3VsdC5lcnJvcnMpXHJcbiAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgdGl0bGU6ICdQcm9qZWN0IHVwZGF0ZSBmYWlsZWQnLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBlcnJNc2dcclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcmVzdWx0LmRhdGE/LnByb2plY3RNdXRhdGlvbnMudXBkYXRlXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlRGVsZXRlUHJvamVjdCgpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IGFjdGl2ZVVzZXIgfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG4gIGNvbnN0IG5hdmlnYXRlSG9tZSA9IHVzZU5hdmlnYXRlVG9Ib21lKClcclxuICBjb25zdCByb3V0ZXIgPSB1c2VSb3V0ZXIoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKFxyXG4gICAgaWQ6IHN0cmluZyxcclxuICAgIG9wdGlvbnM/OiBQYXJ0aWFsPHsgZ29Ib21lOiBib29sZWFuOyB3b3Jrc3BhY2VTbHVnPzogc3RyaW5nIH0+XHJcbiAgKSA9PiB7XHJcbiAgICBpZiAoIWFjdGl2ZVVzZXIudmFsdWUpIHJldHVyblxyXG4gICAgY29uc3QgeyBnb0hvbWUsIHdvcmtzcGFjZVNsdWcgfSA9IG9wdGlvbnMgfHwge31cclxuXHJcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcG9sbG9cclxuICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgbXV0YXRpb246IGRlbGV0ZVByb2plY3RNdXRhdGlvbixcclxuICAgICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICAgIGlkXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChyZXN1bHQ/LmRhdGE/LnByb2plY3RNdXRhdGlvbnMuZGVsZXRlKSB7XHJcbiAgICAgIGlmIChnb0hvbWUpIHtcclxuICAgICAgICBpZiAod29ya3NwYWNlU2x1Zykge1xyXG4gICAgICAgICAgcm91dGVyLnB1c2god29ya3NwYWNlUm91dGUod29ya3NwYWNlU2x1ZykpXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG5hdmlnYXRlSG9tZSgpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBldmljdCBwcm9qZWN0IGZyb20gY2FjaGVcclxuICAgICAgYXBvbGxvLmNhY2hlLmV2aWN0KHtcclxuICAgICAgICBpZDogZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIGlkKVxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UocmVzdWx0LmVycm9ycylcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgICB0aXRsZTogJ1Byb2plY3QgZGVsZXRpb24gZmFpbGVkJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyTXNnXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuICEhcmVzdWx0LmRhdGE/LnByb2plY3RNdXRhdGlvbnMuZGVsZXRlXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlUHJvY2Vzc1Byb2plY3RJbnZpdGUoKSB7XHJcbiAgY29uc3QgYXBvbGxvID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgeyBhY3RpdmVVc2VyIH0gPSB1c2VBY3RpdmVVc2VyKClcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuXHJcbiAgcmV0dXJuIGFzeW5jIChcclxuICAgIGlucHV0OiBQcm9qZWN0SW52aXRlVXNlSW5wdXQsXHJcbiAgICBvcHRpb25zPzogUGFydGlhbDx7IGludml0ZUlkOiBzdHJpbmc7IHNraXBUb2FzdDogYm9vbGVhbiB9PlxyXG4gICkgPT4ge1xyXG4gICAgaWYgKCFhY3RpdmVVc2VyLnZhbHVlKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiB1c2VQcm9qZWN0SW52aXRlTXV0YXRpb24sXHJcbiAgICAgICAgdmFyaWFibGVzOiB7IGlucHV0IH0sXHJcbiAgICAgICAgdXBkYXRlOiAoY2FjaGUsIHsgZGF0YSB9KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIWRhdGE/LnByb2plY3RNdXRhdGlvbnMuaW52aXRlcy51c2UpIHJldHVyblxyXG5cclxuICAgICAgICAgIGlmIChvcHRpb25zPy5pbnZpdGVJZCkge1xyXG4gICAgICAgICAgICAvLyBFdmljdCBpbnZpdGUgaXRzZWxmIChiZWNhdXNlIG9mIGltcGxpY2l0IHdvcmtzcGFjZSBpbnZpdGVzLCB3ZSBuZWVkIHRvIGFsc28gZXZpY3QgZXF1aXZhbGVudCB3b3Jrc3BhY2UgaW52aXRlKVxyXG4gICAgICAgICAgICBjYWNoZS5ldmljdCh7XHJcbiAgICAgICAgICAgICAgaWQ6IGdldENhY2hlSWQoJ1BlbmRpbmdTdHJlYW1Db2xsYWJvcmF0b3InLCBvcHRpb25zLmludml0ZUlkKVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICBjYWNoZS5ldmljdCh7XHJcbiAgICAgICAgICAgICAgaWQ6IGdldENhY2hlSWQoJ1BlbmRpbmdXb3Jrc3BhY2VDb2xsYWJvcmF0b3InLCBvcHRpb25zLmludml0ZUlkKVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAoIW9wdGlvbnM/LnNraXBUb2FzdCkge1xyXG4gICAgICBpZiAoZGF0YT8ucHJvamVjdE11dGF0aW9ucy5pbnZpdGVzLnVzZSkge1xyXG4gICAgICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICAgICAgdHlwZTogaW5wdXQuYWNjZXB0XHJcbiAgICAgICAgICAgID8gVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3NcclxuICAgICAgICAgICAgOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuSW5mbyxcclxuICAgICAgICAgIHRpdGxlOiBpbnB1dC5hY2NlcHQgPyAnUHJvamVjdCBpbnZpdGUgYWNjZXB0ZWQnIDogJ1Byb2plY3QgaW52aXRlIGRpc21pc3NlZCdcclxuICAgICAgICB9KVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGVyck1zZyA9IGdldEZpcnN0RXJyb3JNZXNzYWdlKGVycm9ycylcclxuICAgICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICAgIHR5cGU6IFRvYXN0Tm90aWZpY2F0aW9uVHlwZS5EYW5nZXIsXHJcbiAgICAgICAgICB0aXRsZTogXCJDb3VsZG4ndCBwcm9jZXNzIHByb2plY3QgaW52aXRlXCIsXHJcbiAgICAgICAgICBkZXNjcmlwdGlvbjogZXJyTXNnXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkYXRhPy5wcm9qZWN0TXV0YXRpb25zLmludml0ZXMudXNlXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlTGVhdmVQcm9qZWN0KCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgbmF2aWdhdGVIb21lID0gdXNlTmF2aWdhdGVUb0hvbWUoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKHByb2plY3RJZDogc3RyaW5nLCBvcHRpb25zPzogUGFydGlhbDx7IGdvSG9tZTogYm9vbGVhbiB9PikgPT4ge1xyXG4gICAgaWYgKCFhY3RpdmVVc2VyLnZhbHVlKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBsZWF2ZVByb2plY3RNdXRhdGlvbixcclxuICAgICAgICB2YXJpYWJsZXM6IHsgcHJvamVjdElkIH0sXHJcbiAgICAgICAgdXBkYXRlOiAoY2FjaGUsIHsgZGF0YSB9KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIWRhdGE/LnByb2plY3RNdXRhdGlvbnMubGVhdmUpIHJldHVyblxyXG5cclxuICAgICAgICAgIGNhY2hlLmV2aWN0KHtcclxuICAgICAgICAgICAgaWQ6IGdldENhY2hlSWQoJ1Byb2plY3QnLCBwcm9qZWN0SWQpXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAoZGF0YT8ucHJvamVjdE11dGF0aW9ucy5sZWF2ZSkge1xyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuSW5mbyxcclxuICAgICAgICB0aXRsZTogXCJZb3UndmUgbGVmdCB0aGUgcHJvamVjdFwiXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICBpZiAob3B0aW9ucz8uZ29Ib21lKSBuYXZpZ2F0ZUhvbWUoKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiBcIkNvdWxkbid0IGxlYXZlIHByb2plY3RcIixcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyTXNnXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlTW92ZVByb2plY3RUb1dvcmtzcGFjZSgpIHtcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuICBjb25zdCBtaXhwYW5lbCA9IHVzZU1peHBhbmVsKClcclxuICBjb25zdCB7IG11dGF0ZSB9ID0gdXNlTXV0YXRpb24odXNlTW92ZVByb2plY3RUb1dvcmtzcGFjZU11dGF0aW9uKVxyXG4gIGNvbnN0IHsgYWN0aXZlVXNlciB9ID0gdXNlQWN0aXZlVXNlcigpXHJcblxyXG4gIHJldHVybiBhc3luYyAocGFyYW1zOiB7XHJcbiAgICBwcm9qZWN0SWQ6IHN0cmluZ1xyXG4gICAgd29ya3NwYWNlSWQ6IHN0cmluZ1xyXG4gICAgd29ya3NwYWNlTmFtZTogc3RyaW5nXHJcbiAgICBldmVudFNvdXJjZT86IHN0cmluZ1xyXG4gIH0pID0+IHtcclxuICAgIGNvbnN0IHVzZXJJZCA9IGFjdGl2ZVVzZXIudmFsdWU/LmlkXHJcbiAgICBpZiAoIXVzZXJJZCkgcmV0dXJuXHJcbiAgICBjb25zdCB7IHByb2plY3RJZCwgd29ya3NwYWNlSWQsIHdvcmtzcGFjZU5hbWUsIGV2ZW50U291cmNlIH0gPSBwYXJhbXNcclxuXHJcbiAgICBjb25zdCByZXMgPSBhd2FpdCBtdXRhdGUoXHJcbiAgICAgIHsgcHJvamVjdElkLCB3b3Jrc3BhY2VJZCB9LFxyXG4gICAgICB7XHJcbiAgICAgICAgdXBkYXRlOiAoY2FjaGUsIHsgZGF0YSB9KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIWRhdGE/LndvcmtzcGFjZU11dGF0aW9ucy5wcm9qZWN0cy5tb3ZlVG9Xb3Jrc3BhY2UpIHJldHVyblxyXG4gICAgICAgICAgaWYgKCF3b3Jrc3BhY2VJZCkgcmV0dXJuXHJcblxyXG4gICAgICAgICAgLy8gQWRkIHRvIHdvcmtzcGFjZS5wcm9qZWN0c1xyXG4gICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGQoXHJcbiAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICBnZXRDYWNoZUlkKCdXb3Jrc3BhY2UnLCB3b3Jrc3BhY2VJZCksXHJcbiAgICAgICAgICAgICdwcm9qZWN0cycsXHJcbiAgICAgICAgICAgICh7IGhlbHBlcnM6IHsgY3JlYXRlVXBkYXRlZFZhbHVlLCByZWYgfSB9KSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZWRWYWx1ZSgoeyB1cGRhdGUgfSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlKCdpdGVtcycsIChpdGVtcykgPT4gW3JlZignUHJvamVjdCcsIHByb2plY3RJZCksIC4uLml0ZW1zXSlcclxuICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICApXHJcblxyXG4gICAgICAgICAgLy8gUmVtb3ZlIGZyb20gcGVyc29uYWxPbmx5IHVzZXIgcHJvamVjdHNcclxuICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkKFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnVXNlcicsIHVzZXJJZCksXHJcbiAgICAgICAgICAgICdwcm9qZWN0cycsXHJcbiAgICAgICAgICAgICh7IHZhcmlhYmxlcywgaGVscGVyczogeyBjcmVhdGVVcGRhdGVkVmFsdWUsIHJlZiB9IH0pID0+IHtcclxuICAgICAgICAgICAgICBpZiAoIXZhcmlhYmxlcy5maWx0ZXI/LnBlcnNvbmFsT25seSkgcmV0dXJuXHJcbiAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVVwZGF0ZWRWYWx1ZSgoeyB1cGRhdGUgfSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlKCdpdGVtcycsIChpdGVtcykgPT5cclxuICAgICAgICAgICAgICAgICAgaXRlbXMuZmlsdGVyKChpdGVtKSA9PiBpdGVtLl9fcmVmICE9PSByZWYoJ1Byb2plY3QnLCBwcm9qZWN0SWQpLl9fcmVmKVxyXG4gICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIClcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICkuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChyZXM/LmRhdGE/LndvcmtzcGFjZU11dGF0aW9ucy5wcm9qZWN0cy5tb3ZlVG9Xb3Jrc3BhY2UuaWQpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6IGBNb3ZlZCBwcm9qZWN0IHRvICR7d29ya3NwYWNlTmFtZX1gXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICBtaXhwYW5lbC50cmFjaygnUHJvamVjdCBNb3ZlZCBUbyBXb3Jrc3BhY2UnLCB7XHJcbiAgICAgICAgcHJvamVjdElkLFxyXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcclxuICAgICAgICB3b3Jrc3BhY2VfaWQ6IHdvcmtzcGFjZUlkLFxyXG4gICAgICAgIHNvdXJjZTogZXZlbnRTb3VyY2VcclxuICAgICAgfSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnN0IGVyck1zZyA9IGdldEZpcnN0RXJyb3JNZXNzYWdlKHJlcz8uZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiBcIkNvdWxkbid0IG1vdmUgcHJvamVjdFwiLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBlcnJNc2dcclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcmVzPy5kYXRhPy53b3Jrc3BhY2VNdXRhdGlvbnMucHJvamVjdHMubW92ZVRvV29ya3NwYWNlXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlQ29weVByb2plY3RMaW5rKCkge1xyXG4gIGNvbnN0IHsgY29weSB9ID0gdXNlQ2xpcGJvYXJkKClcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuXHJcbiAgcmV0dXJuIGFzeW5jIChwcm9qZWN0SWQ6IHN0cmluZykgPT4ge1xyXG4gICAgaWYgKGltcG9ydC5tZXRhLnNlcnZlcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBzdXBwb3J0ZWQgaW4gU1NSJylcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBwYXRoID0gcHJvamVjdFJvdXRlKHByb2plY3RJZClcclxuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocGF0aCwgd2luZG93LmxvY2F0aW9uLnRvU3RyaW5nKCkpLnRvU3RyaW5nKClcclxuXHJcbiAgICBhd2FpdCBjb3B5KHVybClcclxuICAgIHRyaWdnZXJOb3RpZmljYXRpb24oe1xyXG4gICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuU3VjY2VzcyxcclxuICAgICAgdGl0bGU6ICdQcm9qZWN0IGxpbmsgY29waWVkIHRvIGNsaXBib2FyZCdcclxuICAgIH0pXHJcbiAgfVxyXG59XHJcbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9saWIvcHJvamVjdHMvY29tcG9zYWJsZXMvcHJvamVjdE1hbmFnZW1lbnQudHMifQ==