import { useApolloClient, useSubscription } from "/_nuxt/node_modules/@vue/apollo-composable/dist/index.mjs?v=e4f18c29"; import __vite__cjsImport1_dayjs from "/_nuxt/node_modules/.cache/vite/client/deps/dayjs.js?v=e4f18c29"; const dayjs = __vite__cjsImport1_dayjs.__esModule ? __vite__cjsImport1_dayjs.default : __vite__cjsImport1_dayjs; import { useActiveUser } from "/_nuxt/lib/auth/composables/activeUser.ts"; import { convertThrowIntoFetchResult, getCacheId, getFirstErrorMessage } from "/_nuxt/lib/common/helpers/graphql.ts"; import { archiveCommentMutation, createCommentReplyMutation, createCommentThreadMutation, markCommentViewedMutation } from "/_nuxt/lib/viewer/graphql/mutations.ts"; import { onViewerCommentsUpdatedSubscription } from "/_nuxt/lib/viewer/graphql/subscriptions.ts"; import { useInjectedViewerState } from "/_nuxt/lib/viewer/composables/setup.ts"; import { ToastNotificationType, useGlobalToast } from "/_nuxt/lib/common/composables/toast.ts"; import { isValidCommentContentInput } from "/_nuxt/lib/viewer/helpers/comments.ts"; import { useStateSerialization, useApplySerializedState, StateApplyMode } from "/_nuxt/lib/viewer/composables/serialization.ts"; import { graphql } from "/_nuxt/lib/common/generated/gql/index.ts"; import { unref, computed } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; import { useLogger } from "/_nuxt/composables/logging.ts"; import { useState } from "/_nuxt/node_modules/nuxt/dist/app/composables/state.js?v=e4f18c29"; export function useViewerCommentUpdateTracking(params, handler) { const apollo = useApolloClient().client; const { onResult: onViewerCommentUpdated } = useSubscription( onViewerCommentsUpdatedSubscription, () => ({ target: { projectId: unref(params.projectId), resourceIdString: unref(params.resourceIdString), loadedVersionsOnly: unref(params.loadedVersionsOnly) } }), () => ({ errorPolicy: "all" }) ); onViewerCommentUpdated((res) => { if (!res.data?.projectCommentsUpdated) return; const event = res.data.projectCommentsUpdated; const cache = apollo.cache; handler?.(event, cache); }); } export function useMarkThreadViewed() { const apollo = useApolloClient().client; const { isLoggedIn } = useActiveUser(); const logger = useLogger(); return async (projectId, threadId) => { if (!isLoggedIn.value) return false; const { data, errors } = await apollo.mutate({ mutation: markCommentViewedMutation, variables: { input: { projectId, commentId: threadId } }, update: (cache, { data: data2 }) => { if (!data2?.commentMutations.markViewed) return; cache.modify({ id: getCacheId("Comment", threadId), fields: { viewedAt: () => dayjs().toISOString() } }); } }).catch(convertThrowIntoFetchResult); if (errors) { logger.error("Marking thread as viewed failed", errors); } return !!data?.commentMutations.markViewed; }; } export function useSubmitComment() { const { projectId, resources: { request: { resourceIdString } }, viewer: { instance: viewerInstance } } = useInjectedViewerState(); const { isLoggedIn } = useActiveUser(); const client = useApolloClient().client; const { triggerNotification } = useGlobalToast(); const { serialize } = useStateSerialization(); return async (content) => { if (!isLoggedIn.value) return null; if (!isValidCommentContentInput(content)) return null; const screenshot = await viewerInstance.screenshot(); const { data, errors } = await client.mutate({ mutation: createCommentThreadMutation, variables: { input: { projectId: projectId.value, resourceIdString: resourceIdString.value, content, viewerState: serialize({ concreteResourceIdString: true }), screenshot } } }).catch(convertThrowIntoFetchResult); if (data?.commentMutations.create) { return data.commentMutations.create; } const errMsg = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Comment creation failed", description: errMsg }); return null; }; } export function useSubmitReply() { const { isLoggedIn } = useActiveUser(); const client = useApolloClient().client; const { triggerNotification } = useGlobalToast(); return async (input) => { if (!isLoggedIn.value) return null; if (!isValidCommentContentInput(input.content)) return null; const { data, errors } = await client.mutate({ mutation: createCommentReplyMutation, variables: { input } }).catch(convertThrowIntoFetchResult); if (data?.commentMutations.reply) { return data.commentMutations.reply; } const errMsg = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Reply creation failed", description: errMsg }); return null; }; } export function useArchiveComment() { const { isLoggedIn } = useActiveUser(); const client = useApolloClient().client; const { triggerNotification } = useGlobalToast(); return async (input) => { const { commentId, projectId } = input; if (!isLoggedIn.value || !commentId || !projectId) return false; const { data, errors } = await client.mutate({ mutation: archiveCommentMutation, variables: { input } }).catch(convertThrowIntoFetchResult); if (data?.commentMutations.archive) return true; const errMsg = getFirstErrorMessage(errors); triggerNotification({ type: ToastNotificationType.Danger, title: "Comment archival failed", description: errMsg }); return false; }; } graphql(` fragment UseCheckViewerCommentingAccess_Project on Project { id permissions { canCreateComment { ...FullPermissionCheckResult } } } `); export function useCheckViewerCommentingAccess() { const { resources: { response: { project } } } = useInjectedViewerState(); return computed(() => { return project.value?.permissions.canCreateComment.authorized; }); } const useActiveThreadContext = () => { return useState("thread-context", () => ({ threadId: null, previousState: null })); }; export const useCommentContext = () => { const applyState = useApplySerializedState(); const { serialize } = useStateSerialization(); const state = useInjectedViewerState(); const threadContext = useActiveThreadContext(); const thread = computed(() => state.ui.threads.openThread.thread.value); const calculateThreadResourceStatus = (threadData) => { if (!threadData) return { isLoaded: false }; const loadedResources = state.resources.response.resourceItems.value; const resourceLinks = threadData?.resources; if (!resourceLinks) { return { isLoaded: false }; } const objectLinks = resourceLinks.filter((l) => l.resourceType === "object").map((l) => l.resourceId); const commitLinks = resourceLinks.filter((l) => l.resourceType === "commit").map((l) => l.resourceId); const hasLoadedObjects = objectLinks.length > 0 && objectLinks.every((objId) => loadedResources.some((lr) => lr.objectId === objId)); const hasLoadedVersions = commitLinks.length > 0 && commitLinks.every( (commitId) => loadedResources.some((lr) => lr.versionId && lr.versionId === commitId) ); const currentModels = state.resources.response.modelsAndVersionIds.value; const threadModels = threadData.viewerResources.filter( (r) => r.modelId !== null && r.versionId !== null ); const hasFederatedModels = threadModels.some( (threadModel) => !currentModels.some((m) => m.model.id === threadModel.modelId) ); const hasDifferentVersions = threadModels.some((threadModel) => { const currentModel = currentModels.find((m) => m.model.id === threadModel.modelId); return currentModel && currentModel.versionId !== threadModel.versionId; }); return { isLoaded: hasLoadedObjects || hasLoadedVersions, isDifferentVersion: hasDifferentVersions, isFederatedModel: hasFederatedModels }; }; const threadResourceStatus = computed( () => calculateThreadResourceStatus(thread.value) ); const hasClickedFullContext = computed(() => { const threadId = thread.value?.id; return threadContext.value.threadId === threadId; }); const loadContext = async (mode) => { const state2 = thread.value?.viewerState; const threadId = thread.value?.id ?? null; if (!state2) return; threadContext.value = { threadId, previousState: serialize() }; await applyState(state2, mode); }; const loadThreadVersionContext = () => loadContext(StateApplyMode.ThreadFullContextOpen); const loadFederatedContext = () => loadContext(StateApplyMode.FederatedContext); const handleContextClick = () => { if (threadResourceStatus.value.isDifferentVersion) { loadThreadVersionContext(); } else { loadFederatedContext(); } }; const goBack = async () => { if (!threadContext.value.previousState) { return; } await applyState( threadContext.value.previousState, StateApplyMode.ThreadFullContextOpen ); threadContext.value = { threadId: null, previousState: null }; }; const cleanupThreadContext = () => { threadContext.value = { threadId: null, previousState: null }; }; return { threadResourceStatus, calculateThreadResourceStatus, handleContextClick, goBack, hasClickedFullContext, cleanupThreadContext }; }; //# sourceMappingURL=data:application/json;base64,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QjtBQUFBLEVBQ0Y7QUFFQSxRQUFNLFNBQVMsWUFBWTtBQUN6QixRQUFJLENBQUMsY0FBYyxNQUFNLGVBQWU7QUFDdEM7QUFBQSxJQUNGO0FBRUEsVUFBTTtBQUFBLE1BQ0osY0FBYyxNQUFNO0FBQUEsTUFDcEIsZUFBZTtBQUFBLElBQ2pCO0FBQ0Esa0JBQWMsUUFBUTtBQUFBLE1BQ3BCLFVBQVU7QUFBQSxNQUNWLGVBQWU7QUFBQSxJQUNqQjtBQUFBLEVBQ0Y7QUFFQSxRQUFNLHVCQUF1QixNQUFNO0FBQ2pDLGtCQUFjLFFBQVE7QUFBQSxNQUNwQixVQUFVO0FBQUEsTUFDVixlQUFlO0FBQUEsSUFDakI7QUFBQSxFQUNGO0FBRUEsU0FBTztBQUFBLElBQ0w7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0Y7QUFDRiIsIm5hbWVzIjpbImRhdGEiLCJzdGF0ZSJdLCJpZ25vcmVMaXN0IjpbXSwic291cmNlcyI6WyJjb21tZW50TWFuYWdlbWVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEFwb2xsb0NhY2hlIH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY2FjaGUnXHJcbmltcG9ydCB0eXBlIHsgSlNPTkNvbnRlbnQgfSBmcm9tICdAdGlwdGFwL2NvcmUnXHJcbmltcG9ydCB7IHVzZUFwb2xsb0NsaWVudCwgdXNlU3Vic2NyaXB0aW9uIH0gZnJvbSAnQHZ1ZS9hcG9sbG8tY29tcG9zYWJsZSdcclxuaW1wb3J0IHR5cGUgeyBNYXliZVJlZiB9IGZyb20gJ0B2dWV1c2UvY29yZSdcclxuaW1wb3J0IGRheWpzIGZyb20gJ2RheWpzJ1xyXG5pbXBvcnQgdHlwZSB7IEdldCB9IGZyb20gJ3R5cGUtZmVzdCdcclxuaW1wb3J0IHsgdXNlQWN0aXZlVXNlciB9IGZyb20gJ35+L2xpYi9hdXRoL2NvbXBvc2FibGVzL2FjdGl2ZVVzZXInXHJcbmltcG9ydCB0eXBlIHtcclxuICBBcmNoaXZlQ29tbWVudElucHV0LFxyXG4gIENvbW1lbnRDb250ZW50SW5wdXQsXHJcbiAgQ3JlYXRlQ29tbWVudFJlcGx5SW5wdXQsXHJcbiAgT25WaWV3ZXJDb21tZW50c1VwZGF0ZWRTdWJzY3JpcHRpb24sXHJcbiAgVmlld2VyUmVzb3VyY2VJdGVtXHJcbn0gZnJvbSAnfn4vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcbmltcG9ydCB7XHJcbiAgY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0LFxyXG4gIGdldENhY2hlSWQsXHJcbiAgZ2V0Rmlyc3RFcnJvck1lc3NhZ2VcclxufSBmcm9tICd+fi9saWIvY29tbW9uL2hlbHBlcnMvZ3JhcGhxbCdcclxuaW1wb3J0IHtcclxuICBhcmNoaXZlQ29tbWVudE11dGF0aW9uLFxyXG4gIGNyZWF0ZUNvbW1lbnRSZXBseU11dGF0aW9uLFxyXG4gIGNyZWF0ZUNvbW1lbnRUaHJlYWRNdXRhdGlvbixcclxuICBtYXJrQ29tbWVudFZpZXdlZE11dGF0aW9uXHJcbn0gZnJvbSAnfn4vbGliL3ZpZXdlci9ncmFwaHFsL211dGF0aW9ucydcclxuaW1wb3J0IHsgb25WaWV3ZXJDb21tZW50c1VwZGF0ZWRTdWJzY3JpcHRpb24gfSBmcm9tICd+fi9saWIvdmlld2VyL2dyYXBocWwvc3Vic2NyaXB0aW9ucydcclxuaW1wb3J0IHtcclxuICB1c2VJbmplY3RlZFZpZXdlclN0YXRlLFxyXG4gIHR5cGUgTG9hZGVkQ29tbWVudFRocmVhZFxyXG59IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2V0dXAnXHJcbmltcG9ydCB0eXBlIHsgTWF5YmVOdWxsT3JVbmRlZmluZWQsIFNwZWNrbGVWaWV3ZXIgfSBmcm9tICdAc3BlY2tsZS9zaGFyZWQnXHJcbmltcG9ydCB7IFRvYXN0Tm90aWZpY2F0aW9uVHlwZSwgdXNlR2xvYmFsVG9hc3QgfSBmcm9tICd+fi9saWIvY29tbW9uL2NvbXBvc2FibGVzL3RvYXN0J1xyXG5pbXBvcnQgdHlwZSB7IFN1Y2Nlc3NmdWxseVVwbG9hZGVkRmlsZUl0ZW0gfSBmcm9tICd+fi9saWIvY29yZS9hcGkvYmxvYlN0b3JhZ2UnXHJcbmltcG9ydCB7IGlzVmFsaWRDb21tZW50Q29udGVudElucHV0IH0gZnJvbSAnfn4vbGliL3ZpZXdlci9oZWxwZXJzL2NvbW1lbnRzJ1xyXG5pbXBvcnQge1xyXG4gIHVzZVN0YXRlU2VyaWFsaXphdGlvbixcclxuICB1c2VBcHBseVNlcmlhbGl6ZWRTdGF0ZSxcclxuICBTdGF0ZUFwcGx5TW9kZVxyXG59IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2VyaWFsaXphdGlvbidcclxuaW1wb3J0IHR5cGUgeyBDb21tZW50QnViYmxlTW9kZWwgfSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvY29tbWVudEJ1YmJsZXMnXHJcbmltcG9ydCB7IGdyYXBocWwgfSBmcm9tICd+L2xpYi9jb21tb24vZ2VuZXJhdGVkL2dxbCdcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VWaWV3ZXJDb21tZW50VXBkYXRlVHJhY2tpbmcoXHJcbiAgcGFyYW1zOiB7XHJcbiAgICBwcm9qZWN0SWQ6IE1heWJlUmVmPHN0cmluZz5cclxuICAgIHJlc291cmNlSWRTdHJpbmc6IE1heWJlUmVmPHN0cmluZz5cclxuICAgIGxvYWRlZFZlcnNpb25zT25seT86IE1heWJlUmVmPE1heWJlTnVsbE9yVW5kZWZpbmVkPGJvb2xlYW4+PlxyXG4gIH0sXHJcbiAgaGFuZGxlcj86IChcclxuICAgIGRhdGE6IE5vbk51bGxhYmxlPFxyXG4gICAgICBHZXQ8T25WaWV3ZXJDb21tZW50c1VwZGF0ZWRTdWJzY3JpcHRpb24sICdwcm9qZWN0Q29tbWVudHNVcGRhdGVkJz5cclxuICAgID4sXHJcbiAgICBjYWNoZTogQXBvbGxvQ2FjaGU8dW5rbm93bj5cclxuICApID0+IHZvaWRcclxuKSB7XHJcbiAgY29uc3QgYXBvbGxvID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgeyBvblJlc3VsdDogb25WaWV3ZXJDb21tZW50VXBkYXRlZCB9ID0gdXNlU3Vic2NyaXB0aW9uKFxyXG4gICAgb25WaWV3ZXJDb21tZW50c1VwZGF0ZWRTdWJzY3JpcHRpb24sXHJcbiAgICAoKSA9PiAoe1xyXG4gICAgICB0YXJnZXQ6IHtcclxuICAgICAgICBwcm9qZWN0SWQ6IHVucmVmKHBhcmFtcy5wcm9qZWN0SWQpLFxyXG4gICAgICAgIHJlc291cmNlSWRTdHJpbmc6IHVucmVmKHBhcmFtcy5yZXNvdXJjZUlkU3RyaW5nKSxcclxuICAgICAgICBsb2FkZWRWZXJzaW9uc09ubHk6IHVucmVmKHBhcmFtcy5sb2FkZWRWZXJzaW9uc09ubHkpXHJcbiAgICAgIH1cclxuICAgIH0pLFxyXG4gICAgKCkgPT4gKHtcclxuICAgICAgZXJyb3JQb2xpY3k6ICdhbGwnXHJcbiAgICB9KVxyXG4gIClcclxuXHJcbiAgb25WaWV3ZXJDb21tZW50VXBkYXRlZCgocmVzKSA9PiB7XHJcbiAgICBpZiAoIXJlcy5kYXRhPy5wcm9qZWN0Q29tbWVudHNVcGRhdGVkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCBldmVudCA9IHJlcy5kYXRhLnByb2plY3RDb21tZW50c1VwZGF0ZWRcclxuICAgIGNvbnN0IGNhY2hlID0gYXBvbGxvLmNhY2hlXHJcblxyXG4gICAgaGFuZGxlcj8uKGV2ZW50LCBjYWNoZSlcclxuICB9KVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlTWFya1RocmVhZFZpZXdlZCgpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IGlzTG9nZ2VkSW4gfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IGxvZ2dlciA9IHVzZUxvZ2dlcigpXHJcblxyXG4gIHJldHVybiBhc3luYyAocHJvamVjdElkOiBzdHJpbmcsIHRocmVhZElkOiBzdHJpbmcpID0+IHtcclxuICAgIGlmICghaXNMb2dnZWRJbi52YWx1ZSkgcmV0dXJuIGZhbHNlXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBtYXJrQ29tbWVudFZpZXdlZE11dGF0aW9uLFxyXG4gICAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgICAgaW5wdXQ6IHtcclxuICAgICAgICAgICAgcHJvamVjdElkLFxyXG4gICAgICAgICAgICBjb21tZW50SWQ6IHRocmVhZElkXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICB1cGRhdGU6IChjYWNoZSwgeyBkYXRhIH0pID0+IHtcclxuICAgICAgICAgIGlmICghZGF0YT8uY29tbWVudE11dGF0aW9ucy5tYXJrVmlld2VkKSByZXR1cm5cclxuXHJcbiAgICAgICAgICBjYWNoZS5tb2RpZnkoe1xyXG4gICAgICAgICAgICBpZDogZ2V0Q2FjaGVJZCgnQ29tbWVudCcsIHRocmVhZElkKSxcclxuICAgICAgICAgICAgZmllbGRzOiB7XHJcbiAgICAgICAgICAgICAgdmlld2VkQXQ6ICgpID0+IGRheWpzKCkudG9JU09TdHJpbmcoKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAoZXJyb3JzKSB7XHJcbiAgICAgIGxvZ2dlci5lcnJvcignTWFya2luZyB0aHJlYWQgYXMgdmlld2VkIGZhaWxlZCcsIGVycm9ycylcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gISFkYXRhPy5jb21tZW50TXV0YXRpb25zLm1hcmtWaWV3ZWRcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIENvbW1lbnRFZGl0b3JWYWx1ZSA9IHtcclxuICBkb2M/OiBKU09OQ29udGVudCB8IG51bGxcclxuICBhdHRhY2htZW50cz86IFN1Y2Nlc3NmdWxseVVwbG9hZGVkRmlsZUl0ZW1bXSB8IG51bGxcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZVN1Ym1pdENvbW1lbnQoKSB7XHJcbiAgY29uc3Qge1xyXG4gICAgcHJvamVjdElkLFxyXG4gICAgcmVzb3VyY2VzOiB7XHJcbiAgICAgIHJlcXVlc3Q6IHsgcmVzb3VyY2VJZFN0cmluZyB9XHJcbiAgICB9LFxyXG4gICAgdmlld2VyOiB7IGluc3RhbmNlOiB2aWV3ZXJJbnN0YW5jZSB9XHJcbiAgfSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG4gIGNvbnN0IHsgaXNMb2dnZWRJbiB9ID0gdXNlQWN0aXZlVXNlcigpXHJcbiAgY29uc3QgY2xpZW50ID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgeyBzZXJpYWxpemUgfSA9IHVzZVN0YXRlU2VyaWFsaXphdGlvbigpXHJcblxyXG4gIHJldHVybiBhc3luYyAoY29udGVudDogQ29tbWVudENvbnRlbnRJbnB1dCkgPT4ge1xyXG4gICAgaWYgKCFpc0xvZ2dlZEluLnZhbHVlKSByZXR1cm4gbnVsbFxyXG4gICAgaWYgKCFpc1ZhbGlkQ29tbWVudENvbnRlbnRJbnB1dChjb250ZW50KSkgcmV0dXJuIG51bGxcclxuICAgIGNvbnN0IHNjcmVlbnNob3QgPSBhd2FpdCB2aWV3ZXJJbnN0YW5jZS5zY3JlZW5zaG90KClcclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgY2xpZW50XHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBjcmVhdGVDb21tZW50VGhyZWFkTXV0YXRpb24sXHJcbiAgICAgICAgdmFyaWFibGVzOiB7XHJcbiAgICAgICAgICBpbnB1dDoge1xyXG4gICAgICAgICAgICBwcm9qZWN0SWQ6IHByb2plY3RJZC52YWx1ZSxcclxuICAgICAgICAgICAgcmVzb3VyY2VJZFN0cmluZzogcmVzb3VyY2VJZFN0cmluZy52YWx1ZSxcclxuICAgICAgICAgICAgY29udGVudCxcclxuICAgICAgICAgICAgdmlld2VyU3RhdGU6IHNlcmlhbGl6ZSh7IGNvbmNyZXRlUmVzb3VyY2VJZFN0cmluZzogdHJ1ZSB9KSxcclxuICAgICAgICAgICAgc2NyZWVuc2hvdFxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAoZGF0YT8uY29tbWVudE11dGF0aW9ucy5jcmVhdGUpIHtcclxuICAgICAgcmV0dXJuIGRhdGEuY29tbWVudE11dGF0aW9ucy5jcmVhdGVcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBlcnJNc2cgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgdGl0bGU6ICdDb21tZW50IGNyZWF0aW9uIGZhaWxlZCcsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiBlcnJNc2dcclxuICAgIH0pXHJcblxyXG4gICAgcmV0dXJuIG51bGxcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VTdWJtaXRSZXBseSgpIHtcclxuICBjb25zdCB7IGlzTG9nZ2VkSW4gfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IGNsaWVudCA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG5cclxuICByZXR1cm4gYXN5bmMgKGlucHV0OiBDcmVhdGVDb21tZW50UmVwbHlJbnB1dCkgPT4ge1xyXG4gICAgaWYgKCFpc0xvZ2dlZEluLnZhbHVlKSByZXR1cm4gbnVsbFxyXG4gICAgaWYgKCFpc1ZhbGlkQ29tbWVudENvbnRlbnRJbnB1dChpbnB1dC5jb250ZW50KSkgcmV0dXJuIG51bGxcclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgY2xpZW50XHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBjcmVhdGVDb21tZW50UmVwbHlNdXRhdGlvbixcclxuICAgICAgICB2YXJpYWJsZXM6IHtcclxuICAgICAgICAgIGlucHV0XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goY29udmVydFRocm93SW50b0ZldGNoUmVzdWx0KVxyXG5cclxuICAgIGlmIChkYXRhPy5jb21tZW50TXV0YXRpb25zLnJlcGx5KSB7XHJcbiAgICAgIHJldHVybiBkYXRhLmNvbW1lbnRNdXRhdGlvbnMucmVwbHlcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBlcnJNc2cgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgdGl0bGU6ICdSZXBseSBjcmVhdGlvbiBmYWlsZWQnLFxyXG4gICAgICBkZXNjcmlwdGlvbjogZXJyTXNnXHJcbiAgICB9KVxyXG5cclxuICAgIHJldHVybiBudWxsXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlQXJjaGl2ZUNvbW1lbnQoKSB7XHJcbiAgY29uc3QgeyBpc0xvZ2dlZEluIH0gPSB1c2VBY3RpdmVVc2VyKClcclxuICBjb25zdCBjbGllbnQgPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuXHJcbiAgcmV0dXJuIGFzeW5jIChpbnB1dDogQXJjaGl2ZUNvbW1lbnRJbnB1dCkgPT4ge1xyXG4gICAgY29uc3QgeyBjb21tZW50SWQsIHByb2plY3RJZCB9ID0gaW5wdXRcclxuXHJcbiAgICBpZiAoIWlzTG9nZ2VkSW4udmFsdWUgfHwgIWNvbW1lbnRJZCB8fCAhcHJvamVjdElkKSByZXR1cm4gZmFsc2VcclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgY2xpZW50XHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiBhcmNoaXZlQ29tbWVudE11dGF0aW9uLFxyXG4gICAgICAgIHZhcmlhYmxlczoge1xyXG4gICAgICAgICAgaW5wdXRcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgaWYgKGRhdGE/LmNvbW1lbnRNdXRhdGlvbnMuYXJjaGl2ZSkgcmV0dXJuIHRydWVcclxuXHJcbiAgICBjb25zdCBlcnJNc2cgPSBnZXRGaXJzdEVycm9yTWVzc2FnZShlcnJvcnMpXHJcbiAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkRhbmdlcixcclxuICAgICAgdGl0bGU6ICdDb21tZW50IGFyY2hpdmFsIGZhaWxlZCcsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiBlcnJNc2dcclxuICAgIH0pXHJcblxyXG4gICAgcmV0dXJuIGZhbHNlXHJcbiAgfVxyXG59XHJcblxyXG5ncmFwaHFsKGBcclxuICBmcmFnbWVudCBVc2VDaGVja1ZpZXdlckNvbW1lbnRpbmdBY2Nlc3NfUHJvamVjdCBvbiBQcm9qZWN0IHtcclxuICAgIGlkXHJcbiAgICBwZXJtaXNzaW9ucyB7XHJcbiAgICAgIGNhbkNyZWF0ZUNvbW1lbnQge1xyXG4gICAgICAgIC4uLkZ1bGxQZXJtaXNzaW9uQ2hlY2tSZXN1bHRcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuYClcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VDaGVja1ZpZXdlckNvbW1lbnRpbmdBY2Nlc3MoKSB7XHJcbiAgY29uc3Qge1xyXG4gICAgcmVzb3VyY2VzOiB7XHJcbiAgICAgIHJlc3BvbnNlOiB7IHByb2plY3QgfVxyXG4gICAgfVxyXG4gIH0gPSB1c2VJbmplY3RlZFZpZXdlclN0YXRlKClcclxuXHJcbiAgcmV0dXJuIGNvbXB1dGVkKCgpID0+IHtcclxuICAgIHJldHVybiBwcm9qZWN0LnZhbHVlPy5wZXJtaXNzaW9ucy5jYW5DcmVhdGVDb21tZW50LmF1dGhvcml6ZWRcclxuICB9KVxyXG59XHJcblxyXG5jb25zdCB1c2VBY3RpdmVUaHJlYWRDb250ZXh0ID0gKCkgPT4ge1xyXG4gIHR5cGUgVGhyZWFkQ29udGV4dCA9IHtcclxuICAgIHRocmVhZElkOiBzdHJpbmcgfCBudWxsXHJcbiAgICBwcmV2aW91c1N0YXRlOiBTcGVja2xlVmlld2VyLlZpZXdlclN0YXRlLlNlcmlhbGl6ZWRWaWV3ZXJTdGF0ZSB8IG51bGxcclxuICB9XHJcbiAgcmV0dXJuIHVzZVN0YXRlPFRocmVhZENvbnRleHQ+KCd0aHJlYWQtY29udGV4dCcsICgpID0+ICh7XHJcbiAgICB0aHJlYWRJZDogbnVsbCxcclxuICAgIHByZXZpb3VzU3RhdGU6IG51bGxcclxuICB9KSlcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IHVzZUNvbW1lbnRDb250ZXh0ID0gKCkgPT4ge1xyXG4gIGNvbnN0IGFwcGx5U3RhdGUgPSB1c2VBcHBseVNlcmlhbGl6ZWRTdGF0ZSgpXHJcbiAgY29uc3QgeyBzZXJpYWxpemUgfSA9IHVzZVN0YXRlU2VyaWFsaXphdGlvbigpXHJcbiAgY29uc3Qgc3RhdGUgPSB1c2VJbmplY3RlZFZpZXdlclN0YXRlKClcclxuICBjb25zdCB0aHJlYWRDb250ZXh0ID0gdXNlQWN0aXZlVGhyZWFkQ29udGV4dCgpXHJcblxyXG4gIGNvbnN0IHRocmVhZCA9IGNvbXB1dGVkKCgpID0+IHN0YXRlLnVpLnRocmVhZHMub3BlblRocmVhZC50aHJlYWQudmFsdWUpXHJcblxyXG4gIGNvbnN0IGNhbGN1bGF0ZVRocmVhZFJlc291cmNlU3RhdHVzID0gKFxyXG4gICAgdGhyZWFkRGF0YTogTG9hZGVkQ29tbWVudFRocmVhZCB8IENvbW1lbnRCdWJibGVNb2RlbCB8IG51bGwgfCB1bmRlZmluZWRcclxuICApID0+IHtcclxuICAgIGlmICghdGhyZWFkRGF0YSkgcmV0dXJuIHsgaXNMb2FkZWQ6IGZhbHNlIH1cclxuICAgIGNvbnN0IGxvYWRlZFJlc291cmNlcyA9IHN0YXRlLnJlc291cmNlcy5yZXNwb25zZS5yZXNvdXJjZUl0ZW1zLnZhbHVlXHJcbiAgICBjb25zdCByZXNvdXJjZUxpbmtzID0gdGhyZWFkRGF0YT8ucmVzb3VyY2VzXHJcblxyXG4gICAgaWYgKCFyZXNvdXJjZUxpbmtzKSB7XHJcbiAgICAgIHJldHVybiB7IGlzTG9hZGVkOiBmYWxzZSB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgYW55IG9mIHRoZSB0aHJlYWQncyBvYmplY3RzIGFyZSBsb2FkZWRcclxuICAgIGNvbnN0IG9iamVjdExpbmtzID0gcmVzb3VyY2VMaW5rc1xyXG4gICAgICAuZmlsdGVyKChsKSA9PiBsLnJlc291cmNlVHlwZSA9PT0gJ29iamVjdCcpXHJcbiAgICAgIC5tYXAoKGwpID0+IGwucmVzb3VyY2VJZClcclxuICAgIGNvbnN0IGNvbW1pdExpbmtzID0gcmVzb3VyY2VMaW5rc1xyXG4gICAgICAuZmlsdGVyKChsKSA9PiBsLnJlc291cmNlVHlwZSA9PT0gJ2NvbW1pdCcpXHJcbiAgICAgIC5tYXAoKGwpID0+IGwucmVzb3VyY2VJZClcclxuXHJcbiAgICAvLyBDaGVjayBpZiBBTEwgb2YgdGhlIHRocmVhZCdzIG9iamVjdHMgYXJlIGxvYWRlZFxyXG4gICAgY29uc3QgaGFzTG9hZGVkT2JqZWN0cyA9XHJcbiAgICAgIG9iamVjdExpbmtzLmxlbmd0aCA+IDAgJiZcclxuICAgICAgb2JqZWN0TGlua3MuZXZlcnkoKG9iaklkKSA9PiBsb2FkZWRSZXNvdXJjZXMuc29tZSgobHIpID0+IGxyLm9iamVjdElkID09PSBvYmpJZCkpXHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgQUxMIG9mIHRoZSB0aHJlYWQncyBjb21taXRzIGFyZSBsb2FkZWRcclxuICAgIGNvbnN0IGhhc0xvYWRlZFZlcnNpb25zID1cclxuICAgICAgY29tbWl0TGlua3MubGVuZ3RoID4gMCAmJlxyXG4gICAgICBjb21taXRMaW5rcy5ldmVyeSgoY29tbWl0SWQpID0+XHJcbiAgICAgICAgbG9hZGVkUmVzb3VyY2VzLnNvbWUoKGxyKSA9PiBsci52ZXJzaW9uSWQgJiYgbHIudmVyc2lvbklkID09PSBjb21taXRJZClcclxuICAgICAgKVxyXG5cclxuICAgIC8vIFJlc291cmNlIGlzIGxvYWRlZCwgY2hlY2sgdmVyc2lvbnMgYW5kIGZlZGVyYXRpb25cclxuICAgIGNvbnN0IGN1cnJlbnRNb2RlbHMgPSBzdGF0ZS5yZXNvdXJjZXMucmVzcG9uc2UubW9kZWxzQW5kVmVyc2lvbklkcy52YWx1ZVxyXG4gICAgY29uc3QgdGhyZWFkTW9kZWxzID0gdGhyZWFkRGF0YS52aWV3ZXJSZXNvdXJjZXMuZmlsdGVyKFxyXG4gICAgICAocik6IHIgaXMgVmlld2VyUmVzb3VyY2VJdGVtICYgeyBtb2RlbElkOiBzdHJpbmc7IHZlcnNpb25JZDogc3RyaW5nIH0gPT5cclxuICAgICAgICByLm1vZGVsSWQgIT09IG51bGwgJiYgci52ZXJzaW9uSWQgIT09IG51bGxcclxuICAgIClcclxuXHJcbiAgICAvLyBDaGVjayBpZiBhbnkgdGhyZWFkIG1vZGVscyBhcmUgbm90IGluIGN1cnJlbnQgdmlldyAoZmVkZXJhdGVkKVxyXG4gICAgY29uc3QgaGFzRmVkZXJhdGVkTW9kZWxzID0gdGhyZWFkTW9kZWxzLnNvbWUoXHJcbiAgICAgICh0aHJlYWRNb2RlbCkgPT4gIWN1cnJlbnRNb2RlbHMuc29tZSgobSkgPT4gbS5tb2RlbC5pZCA9PT0gdGhyZWFkTW9kZWwubW9kZWxJZClcclxuICAgIClcclxuXHJcbiAgICAvLyBGb3IgbW9kZWxzIHRoYXQgZXhpc3QgaW4gYm90aCBzdGF0ZXMsIGNoZWNrIHZlcnNpb24gZGlmZmVyZW5jZXNcclxuICAgIGNvbnN0IGhhc0RpZmZlcmVudFZlcnNpb25zID0gdGhyZWFkTW9kZWxzLnNvbWUoKHRocmVhZE1vZGVsKSA9PiB7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRNb2RlbCA9IGN1cnJlbnRNb2RlbHMuZmluZCgobSkgPT4gbS5tb2RlbC5pZCA9PT0gdGhyZWFkTW9kZWwubW9kZWxJZClcclxuICAgICAgcmV0dXJuIGN1cnJlbnRNb2RlbCAmJiBjdXJyZW50TW9kZWwudmVyc2lvbklkICE9PSB0aHJlYWRNb2RlbC52ZXJzaW9uSWRcclxuICAgIH0pXHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgaXNMb2FkZWQ6IGhhc0xvYWRlZE9iamVjdHMgfHwgaGFzTG9hZGVkVmVyc2lvbnMsXHJcbiAgICAgIGlzRGlmZmVyZW50VmVyc2lvbjogaGFzRGlmZmVyZW50VmVyc2lvbnMsXHJcbiAgICAgIGlzRmVkZXJhdGVkTW9kZWw6IGhhc0ZlZGVyYXRlZE1vZGVsc1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3QgdGhyZWFkUmVzb3VyY2VTdGF0dXMgPSBjb21wdXRlZCgoKSA9PlxyXG4gICAgY2FsY3VsYXRlVGhyZWFkUmVzb3VyY2VTdGF0dXModGhyZWFkLnZhbHVlKVxyXG4gIClcclxuXHJcbiAgY29uc3QgaGFzQ2xpY2tlZEZ1bGxDb250ZXh0ID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gICAgY29uc3QgdGhyZWFkSWQgPSB0aHJlYWQudmFsdWU/LmlkXHJcbiAgICByZXR1cm4gdGhyZWFkQ29udGV4dC52YWx1ZS50aHJlYWRJZCA9PT0gdGhyZWFkSWRcclxuICB9KVxyXG5cclxuICBjb25zdCBsb2FkQ29udGV4dCA9IGFzeW5jIChcclxuICAgIG1vZGU6IFN0YXRlQXBwbHlNb2RlLlRocmVhZEZ1bGxDb250ZXh0T3BlbiB8IFN0YXRlQXBwbHlNb2RlLkZlZGVyYXRlZENvbnRleHRcclxuICApID0+IHtcclxuICAgIGNvbnN0IHN0YXRlID0gdGhyZWFkLnZhbHVlPy52aWV3ZXJTdGF0ZVxyXG4gICAgY29uc3QgdGhyZWFkSWQgPSB0aHJlYWQudmFsdWU/LmlkID8/IG51bGxcclxuICAgIGlmICghc3RhdGUpIHJldHVyblxyXG5cclxuICAgIC8vIFN0b3JlIGJvdGggY3VycmVudCBzdGF0ZSBhbmQgdGhyZWFkIElEXHJcbiAgICB0aHJlYWRDb250ZXh0LnZhbHVlID0ge1xyXG4gICAgICB0aHJlYWRJZCxcclxuICAgICAgcHJldmlvdXNTdGF0ZTogc2VyaWFsaXplKClcclxuICAgIH1cclxuXHJcbiAgICBhd2FpdCBhcHBseVN0YXRlKHN0YXRlLCBtb2RlKVxyXG4gIH1cclxuXHJcbiAgY29uc3QgbG9hZFRocmVhZFZlcnNpb25Db250ZXh0ID0gKCkgPT5cclxuICAgIGxvYWRDb250ZXh0KFN0YXRlQXBwbHlNb2RlLlRocmVhZEZ1bGxDb250ZXh0T3BlbilcclxuICBjb25zdCBsb2FkRmVkZXJhdGVkQ29udGV4dCA9ICgpID0+IGxvYWRDb250ZXh0KFN0YXRlQXBwbHlNb2RlLkZlZGVyYXRlZENvbnRleHQpXHJcblxyXG4gIGNvbnN0IGhhbmRsZUNvbnRleHRDbGljayA9ICgpID0+IHtcclxuICAgIGlmICh0aHJlYWRSZXNvdXJjZVN0YXR1cy52YWx1ZS5pc0RpZmZlcmVudFZlcnNpb24pIHtcclxuICAgICAgbG9hZFRocmVhZFZlcnNpb25Db250ZXh0KClcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxvYWRGZWRlcmF0ZWRDb250ZXh0KClcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0IGdvQmFjayA9IGFzeW5jICgpID0+IHtcclxuICAgIGlmICghdGhyZWFkQ29udGV4dC52YWx1ZS5wcmV2aW91c1N0YXRlKSB7XHJcbiAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIGF3YWl0IGFwcGx5U3RhdGUoXHJcbiAgICAgIHRocmVhZENvbnRleHQudmFsdWUucHJldmlvdXNTdGF0ZSxcclxuICAgICAgU3RhdGVBcHBseU1vZGUuVGhyZWFkRnVsbENvbnRleHRPcGVuXHJcbiAgICApXHJcbiAgICB0aHJlYWRDb250ZXh0LnZhbHVlID0ge1xyXG4gICAgICB0aHJlYWRJZDogbnVsbCxcclxuICAgICAgcHJldmlvdXNTdGF0ZTogbnVsbFxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3QgY2xlYW51cFRocmVhZENvbnRleHQgPSAoKSA9PiB7XHJcbiAgICB0aHJlYWRDb250ZXh0LnZhbHVlID0ge1xyXG4gICAgICB0aHJlYWRJZDogbnVsbCxcclxuICAgICAgcHJldmlvdXNTdGF0ZTogbnVsbFxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIHRocmVhZFJlc291cmNlU3RhdHVzLFxyXG4gICAgY2FsY3VsYXRlVGhyZWFkUmVzb3VyY2VTdGF0dXMsXHJcbiAgICBoYW5kbGVDb250ZXh0Q2xpY2ssXHJcbiAgICBnb0JhY2ssXHJcbiAgICBoYXNDbGlja2VkRnVsbENvbnRleHQsXHJcbiAgICBjbGVhbnVwVGhyZWFkQ29udGV4dFxyXG4gIH1cclxufVxyXG4iXSwiZmlsZSI6IkQ6L3NwZWNrbGUtc2VydmVyL3BhY2thZ2VzL2Zyb250ZW5kLTIvbGliL3ZpZXdlci9jb21wb3NhYmxlcy9jb21tZW50TWFuYWdlbWVudC50cyJ9