504 lines
67 KiB
Plaintext
504 lines
67 KiB
Plaintext
import { useApolloClient, useQuery, useSubscription } from "/_nuxt/node_modules/@vue/apollo-composable/dist/index.mjs?v=e4f18c29";
|
|
import { SpeckleViewer } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/index.js";
|
|
import { ToastNotificationType, useGlobalToast } from "/_nuxt/lib/common/composables/toast.ts";
|
|
import {
|
|
ProjectPendingVersionsUpdatedMessageType,
|
|
ProjectVersionsUpdatedMessageType
|
|
} from "/_nuxt/lib/common/generated/gql/graphql.ts";
|
|
import { modelRoute, modelVersionsRoute } from "/_nuxt/lib/common/helpers/route.ts";
|
|
import {
|
|
onProjectPendingVersionsUpdatedSubscription,
|
|
onProjectVersionsUpdateSubscription
|
|
} from "/_nuxt/lib/projects/graphql/subscriptions.ts";
|
|
import {
|
|
convertThrowIntoFetchResult,
|
|
evictObjectFields,
|
|
getCacheId,
|
|
getFirstErrorMessage,
|
|
getObjectReference,
|
|
modifyObjectFields
|
|
} from "/_nuxt/lib/common/helpers/graphql.ts";
|
|
import { projectModelVersionsQuery } from "/_nuxt/lib/projects/graphql/queries.ts";
|
|
import {
|
|
deleteVersionsMutation,
|
|
moveVersionsMutation,
|
|
updateVersionMutation
|
|
} from "/_nuxt/lib/projects/graphql/mutations.ts";
|
|
import { useActiveUser } from "/_nuxt/lib/auth/composables/activeUser.ts";
|
|
import { useEvictProjectModelFields } from "/_nuxt/lib/projects/composables/modelManagement.ts";
|
|
import { intersection, isUndefined, uniqBy } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
|
|
import { FileUploadConvertedStatus } from "/_nuxt/lib/core/api/fileImport.ts";
|
|
import { useLock } from "/_nuxt/lib/common/composables/singleton.ts";
|
|
import {
|
|
useFailedFileImportJobUtils,
|
|
useGlobalFileImportManager
|
|
} from "/_nuxt/lib/core/composables/fileImport.ts";
|
|
|
|
import { computed, unref, ref } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
|
|
export function useProjectVersionUpdateTracking(projectId, handler, options) {
|
|
const { silenceToast = false } = options || {};
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const { hasLock } = useLock(
|
|
computed(() => `useProjectVersionUpdateTracking-${unref(projectId)}`)
|
|
);
|
|
const isEnabled = computed(() => !!(hasLock.value || handler));
|
|
const { onResult: onProjectVersionsUpdate } = useSubscription(
|
|
onProjectVersionsUpdateSubscription,
|
|
() => ({
|
|
id: unref(projectId)
|
|
}),
|
|
{ enabled: isEnabled, errorPolicy: "all" }
|
|
);
|
|
onProjectVersionsUpdate((res) => {
|
|
if (!res.data?.projectVersionsUpdated || !hasLock.value) return;
|
|
const event = res.data.projectVersionsUpdated;
|
|
const version = event.version;
|
|
if ([
|
|
ProjectVersionsUpdatedMessageType.Created,
|
|
ProjectVersionsUpdatedMessageType.Updated
|
|
].includes(event.type) && version) {
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(_fieldName, variables, value, { ref: ref2 }) => {
|
|
if (variables.filter?.search) return;
|
|
const limit = variables.limit;
|
|
const newModelRef = ref2("Model", version.model.id);
|
|
const newItems = (value?.items || []).slice();
|
|
let itemAdded = false;
|
|
if (!newItems.find((i) => i.__ref === newModelRef.__ref) && (isUndefined(limit) || newItems.length < limit)) {
|
|
newItems.unshift(newModelRef);
|
|
itemAdded = true;
|
|
}
|
|
return {
|
|
...value || {},
|
|
items: newItems,
|
|
totalCount: (value.totalCount || 0) + (itemAdded ? 1 : 0)
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["models"] }
|
|
);
|
|
evictObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(fieldName, variables, value, { readField }) => {
|
|
if (fieldName !== "modelsTree") return false;
|
|
if (variables.filter?.search) return false;
|
|
if (variables.filter?.contributors?.length) return false;
|
|
if (variables.filter?.sourceApps?.length) return false;
|
|
const items = value?.items || [];
|
|
for (const item of items) {
|
|
const fullName = readField("fullName", item);
|
|
if (fullName === version.model.name) return false;
|
|
}
|
|
return true;
|
|
}
|
|
);
|
|
if (event.type === ProjectVersionsUpdatedMessageType.Created) {
|
|
evictObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(fieldName) => ["viewerResources", "viewerResourcesExtended"].includes(fieldName)
|
|
);
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Model", version.model.id),
|
|
(_fieldName, _variables, value, { readField }) => {
|
|
if (!value?.length) return;
|
|
const newMessage = version.message || "";
|
|
const pendingWithFittingMessageIdx = (value || []).findIndex((i) => {
|
|
const fileName = readField("fileName", i) || "";
|
|
return newMessage.includes(fileName);
|
|
});
|
|
const newVersions = (value || []).slice();
|
|
if (pendingWithFittingMessageIdx !== -1) {
|
|
newVersions.splice(pendingWithFittingMessageIdx, 1);
|
|
}
|
|
return newVersions;
|
|
},
|
|
{ fieldNameWhitelist: ["pendingImportedVersions"] }
|
|
);
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Model", version.model.id),
|
|
(_fieldName, variables, value, { ref: ref2 }) => {
|
|
if (variables.filter?.priorityIdsOnly && variables.filter?.priorityIds && !variables.filter.priorityIds.includes(version.id)) {
|
|
return;
|
|
}
|
|
const limit = variables.limit;
|
|
if (!limit) {
|
|
return;
|
|
}
|
|
const newItems = (value?.items || []).slice();
|
|
if (isUndefined(limit) || newItems.length < limit) {
|
|
newItems.unshift(ref2("Version", version.id));
|
|
}
|
|
return {
|
|
...value || {},
|
|
items: newItems,
|
|
totalCount: (value.totalCount || 0) + 1
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["versions"] }
|
|
);
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(_fieldName, variables, value, { ref: ref2 }) => {
|
|
const newVersionRef = ref2("Version", version.id);
|
|
const limit = variables.limit;
|
|
const newItems = (value?.items || []).slice();
|
|
if (!newItems.find((i) => i.__ref === newVersionRef.__ref) && (isUndefined(limit) || newItems.length < limit)) {
|
|
newItems.unshift(newVersionRef);
|
|
}
|
|
return {
|
|
...value || {},
|
|
items: newItems,
|
|
totalCount: (value.totalCount || 0) + 1
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["versions"] }
|
|
);
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Project", unref(projectId)),
|
|
(_fieldName, _variables, value, { readField }) => {
|
|
if (!value?.length) return;
|
|
const versionModelName = version.model.name;
|
|
const currentModels = (value || []).filter((i) => {
|
|
const itemModelName = readField("modelName", i);
|
|
return itemModelName !== versionModelName;
|
|
});
|
|
return currentModels;
|
|
},
|
|
{ fieldNameWhitelist: ["pendingImportedModels"] }
|
|
);
|
|
if (!silenceToast) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Info,
|
|
title: "A new version was created!",
|
|
cta: {
|
|
title: "View Version",
|
|
url: modelRoute(
|
|
unref(projectId),
|
|
SpeckleViewer.ViewerRoute.resourceBuilder().addModel(version.model.id, version.id).toString()
|
|
)
|
|
}
|
|
});
|
|
}
|
|
}
|
|
} else if (event.type === ProjectVersionsUpdatedMessageType.Deleted) {
|
|
apollo.cache.evict({
|
|
id: getCacheId("Version", event.id)
|
|
});
|
|
if (event.modelId) {
|
|
evictObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Model", event.modelId),
|
|
(fieldName) => ["updatedAt", "previewUrl", "versionCount", "versions"].includes(fieldName)
|
|
);
|
|
apollo.cache.evict({
|
|
id: getCacheId("Project", unref(projectId)),
|
|
fieldName: "viewerResources"
|
|
});
|
|
apollo.cache.evict({
|
|
id: getCacheId("Project", unref(projectId)),
|
|
fieldName: "viewerResourcesExtended"
|
|
});
|
|
}
|
|
}
|
|
});
|
|
onProjectVersionsUpdate((res) => {
|
|
if (!res.data?.projectVersionsUpdated) return;
|
|
const event = res.data.projectVersionsUpdated;
|
|
handler?.(event, apollo.cache);
|
|
});
|
|
}
|
|
export function useModelVersions(params) {
|
|
const { projectId, modelId } = params;
|
|
const cursor = ref(null);
|
|
const { result, fetchMore, onResult } = useQuery(projectModelVersionsQuery, () => ({
|
|
projectId: unref(projectId),
|
|
modelId: unref(modelId),
|
|
versionsCursor: cursor.value
|
|
}));
|
|
onResult((res) => {
|
|
cursor.value = res.data.project?.model?.versions.cursor || null;
|
|
});
|
|
const versions = computed(() => result.value?.project?.model?.versions);
|
|
const moreToLoad = computed(
|
|
() => (!versions.value || versions.value.items.length < versions.value.totalCount) && cursor.value
|
|
);
|
|
const loadMore = () => {
|
|
if (!moreToLoad.value) return;
|
|
return fetchMore({ variables: { versionsCursor: cursor.value } });
|
|
};
|
|
return {
|
|
versions,
|
|
loadMore,
|
|
moreToLoad
|
|
};
|
|
}
|
|
export function useDeleteVersions() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const { isLoggedIn } = useActiveUser();
|
|
return async (input, options) => {
|
|
if (!input.versionIds.length) return;
|
|
if (!isLoggedIn.value) return;
|
|
const { data, errors } = await apollo.mutate({
|
|
mutation: deleteVersionsMutation,
|
|
variables: { input },
|
|
update: (cache, { data: data2 }) => {
|
|
if (!data2?.versionMutations.delete) return;
|
|
for (const versionId of input.versionIds) {
|
|
cache.evict({
|
|
id: getCacheId("Version", versionId)
|
|
});
|
|
}
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Project", input.projectId),
|
|
(_fieldName, _variables, data3) => {
|
|
return {
|
|
...data3,
|
|
...!isUndefined(data3.totalCount) ? {
|
|
totalCount: Math.max(data3.totalCount - input.versionIds.length, 0)
|
|
} : {}
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["versions"] }
|
|
);
|
|
if (options?.modelId) {
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Model", options.modelId),
|
|
(_fieldName, variables, data3) => {
|
|
let removedCount = input.versionIds.length;
|
|
if (variables.filter?.priorityIdsOnly && variables.filter?.priorityIds) {
|
|
const idIntersection = intersection(
|
|
variables.filter.priorityIds,
|
|
input.versionIds
|
|
);
|
|
if (idIntersection.length < 1) return;
|
|
removedCount = idIntersection.length;
|
|
}
|
|
return {
|
|
...data3,
|
|
...!isUndefined(data3.totalCount) ? {
|
|
totalCount: Math.max(data3.totalCount - removedCount, 0)
|
|
} : {}
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["versions"] }
|
|
);
|
|
}
|
|
}
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (data?.versionMutations.delete) {
|
|
const deleteCount = input.versionIds.length;
|
|
triggerNotification({
|
|
type: ToastNotificationType.Info,
|
|
title: `${deleteCount} version${deleteCount > 1 ? "s" : ""} deleted`
|
|
});
|
|
} else {
|
|
const errMsg = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Version deletion failed",
|
|
description: errMsg
|
|
});
|
|
}
|
|
return !!data?.versionMutations.delete;
|
|
};
|
|
}
|
|
export function useMoveVersions() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const { isLoggedIn } = useActiveUser();
|
|
const evictProjectModels = useEvictProjectModelFields();
|
|
return async (input, options) => {
|
|
if (!input.versionIds.length || !input.targetModelName.trim()) return;
|
|
if (!isLoggedIn.value) return;
|
|
const { data, errors } = await apollo.mutate({
|
|
mutation: moveVersionsMutation,
|
|
variables: { input },
|
|
update: (cache, { data: data2 }) => {
|
|
if (!data2?.versionMutations.moveToModel.id) return;
|
|
const newModelId = data2.versionMutations.moveToModel.id;
|
|
const previousModelId = options?.previousModelId;
|
|
if (!previousModelId) return;
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Model", previousModelId),
|
|
(_fieldName, variables) => {
|
|
if (!input.versionIds.includes(variables.id)) return;
|
|
return null;
|
|
},
|
|
{ fieldNameWhitelist: ["version"] }
|
|
);
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Model", previousModelId),
|
|
(_fieldName, _variables, data3) => {
|
|
const oldItems = data3.items || [];
|
|
const newItems = oldItems.filter(
|
|
(i) => !input.versionIds.map((id) => getCacheId("Version", id)).includes(i.__ref)
|
|
);
|
|
const removedItemsCount = Math.max(0, oldItems.length - newItems.length);
|
|
return {
|
|
...data3,
|
|
...data3.items ? { items: newItems } : {},
|
|
...!isUndefined(data3.totalCount) ? {
|
|
totalCount: data3.totalCount - removedItemsCount
|
|
} : {}
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["versions"] }
|
|
);
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Model", newModelId),
|
|
(_fieldName, variables) => {
|
|
if (!input.versionIds.includes(variables.id)) return;
|
|
return getObjectReference("Version", variables.id);
|
|
},
|
|
{ fieldNameWhitelist: ["version"] }
|
|
);
|
|
modifyObjectFields(
|
|
cache,
|
|
getCacheId("Model", newModelId),
|
|
(_fieldName, _variables, data3) => {
|
|
const oldItems = data3.items || [];
|
|
const newItems = [
|
|
...input.versionIds.map((i) => getObjectReference("Version", i)),
|
|
...oldItems
|
|
];
|
|
const addedItemAmount = newItems.length - oldItems.length;
|
|
return {
|
|
...data3,
|
|
...data3.items ? { items: newItems } : {},
|
|
...!isUndefined(data3.totalCount) ? {
|
|
totalCount: data3.totalCount + addedItemAmount
|
|
} : {}
|
|
};
|
|
},
|
|
{ fieldNameWhitelist: ["versions"] }
|
|
);
|
|
if (options?.newModelCreated) {
|
|
evictProjectModels(input.projectId);
|
|
}
|
|
}
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (data?.versionMutations.moveToModel.id) {
|
|
const deleteCount = input.versionIds.length;
|
|
triggerNotification({
|
|
type: ToastNotificationType.Info,
|
|
title: `${deleteCount} version${deleteCount > 1 ? "s" : ""} moved`,
|
|
cta: {
|
|
title: "View versions",
|
|
url: modelVersionsRoute(input.projectId, data.versionMutations.moveToModel.id)
|
|
}
|
|
});
|
|
} else {
|
|
const errMsg = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Version move failed",
|
|
description: errMsg
|
|
});
|
|
}
|
|
return !!data?.versionMutations.moveToModel.id;
|
|
};
|
|
}
|
|
export function useUpdateVersion() {
|
|
const apollo = useApolloClient().client;
|
|
const { triggerNotification } = useGlobalToast();
|
|
const { isLoggedIn } = useActiveUser();
|
|
return async (input) => {
|
|
if (!input.versionId) return;
|
|
if (!isLoggedIn.value) return;
|
|
const { data, errors } = await apollo.mutate({
|
|
mutation: updateVersionMutation,
|
|
variables: { input }
|
|
}).catch(convertThrowIntoFetchResult);
|
|
if (data?.versionMutations.update.id) {
|
|
triggerNotification({
|
|
type: ToastNotificationType.Success,
|
|
title: `Version successfully updated`
|
|
});
|
|
} else {
|
|
const errMsg = getFirstErrorMessage(errors);
|
|
triggerNotification({
|
|
type: ToastNotificationType.Danger,
|
|
title: "Version update failed",
|
|
description: errMsg
|
|
});
|
|
}
|
|
return data?.versionMutations.update;
|
|
};
|
|
}
|
|
export function useProjectPendingVersionUpdateTracking(projectId, handler) {
|
|
const { hasLock } = useLock(
|
|
computed(() => `useProjectPendingVersionUpdateTracking-${unref(projectId)}`)
|
|
);
|
|
const { addFailedJob } = useGlobalFileImportManager();
|
|
const { convertUploadToFailedJob } = useFailedFileImportJobUtils();
|
|
const { userId } = useActiveUser();
|
|
const isEnabled = computed(() => !!(hasLock.value || handler));
|
|
const { onResult: onProjectPendingVersionsUpdate } = useSubscription(
|
|
onProjectPendingVersionsUpdatedSubscription,
|
|
() => ({
|
|
id: unref(projectId)
|
|
}),
|
|
{ enabled: isEnabled, errorPolicy: "all" }
|
|
);
|
|
const apollo = useApolloClient().client;
|
|
onProjectPendingVersionsUpdate((res) => {
|
|
if (!res.data?.projectPendingVersionsUpdated.id || !hasLock.value) return;
|
|
const event = res.data.projectPendingVersionsUpdated;
|
|
const modelId = event.version.model?.id;
|
|
if (!modelId) return;
|
|
if (event.type === ProjectPendingVersionsUpdatedMessageType.Created) {
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Model", modelId),
|
|
(_fieldName, _variables, value, { ref: ref2 }) => {
|
|
const currentVersions = (value || []).slice();
|
|
currentVersions.push(ref2("FileUpload", event.id));
|
|
return uniqBy(currentVersions, (v) => v.__ref);
|
|
},
|
|
{ fieldNameWhitelist: ["pendingImportedVersions"] }
|
|
);
|
|
} else if (event.type === ProjectPendingVersionsUpdatedMessageType.Updated) {
|
|
const success = event.version.convertedStatus === FileUploadConvertedStatus.Completed;
|
|
const failure = event.version.convertedStatus === FileUploadConvertedStatus.Error;
|
|
if (success) {
|
|
modifyObjectFields(
|
|
apollo.cache,
|
|
getCacheId("Model", modelId),
|
|
(_fieldName, _variables, value, { ref: ref2 }) => {
|
|
if (!value?.length) return;
|
|
const currentVersions = (value || []).filter(
|
|
(i) => i.__ref !== ref2("FileUpload", event.id).__ref
|
|
);
|
|
return currentVersions;
|
|
},
|
|
{ fieldNameWhitelist: ["pendingImportedVersions"] }
|
|
);
|
|
} else if (failure) {
|
|
if (event.version.userId === userId.value) {
|
|
addFailedJob(convertUploadToFailedJob(event.version));
|
|
}
|
|
}
|
|
}
|
|
});
|
|
onProjectPendingVersionsUpdate((res) => {
|
|
if (!res.data?.projectPendingVersionsUpdated.id) return;
|
|
const event = res.data.projectPendingVersionsUpdated;
|
|
handler?.(event, apollo.cache);
|
|
});
|
|
}
|
|
|
|
//# sourceMappingURL=data:application/json;base64,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QU0sUUFBUSxJQUFJLEtBQUs7QUFDdkIsY0FBVSxPQUFPLE9BQU8sS0FBSztBQUFBLEVBQy9CLENBQUM7QUFDSCIsIm5hbWVzIjpbInJlZiIsImRhdGEiXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsidmVyc2lvbk1hbmFnZW1lbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBcG9sbG9DYWNoZSB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2NvcmUnXHJcbmltcG9ydCB7IHVzZUFwb2xsb0NsaWVudCwgdXNlUXVlcnksIHVzZVN1YnNjcmlwdGlvbiB9IGZyb20gJ0B2dWUvYXBvbGxvLWNvbXBvc2FibGUnXHJcbmltcG9ydCB0eXBlIHsgTWF5YmVSZWYgfSBmcm9tICdAdnVldXNlL2NvcmUnXHJcbmltcG9ydCB0eXBlIHsgR2V0IH0gZnJvbSAndHlwZS1mZXN0J1xyXG5pbXBvcnQgeyBTcGVja2xlVmlld2VyIH0gZnJvbSAnQHNwZWNrbGUvc2hhcmVkJ1xyXG5pbXBvcnQgdHlwZSB7IE51bGxhYmxlIH0gZnJvbSAnQHNwZWNrbGUvc2hhcmVkJ1xyXG5pbXBvcnQgeyBUb2FzdE5vdGlmaWNhdGlvblR5cGUsIHVzZUdsb2JhbFRvYXN0IH0gZnJvbSAnfn4vbGliL2NvbW1vbi9jb21wb3NhYmxlcy90b2FzdCdcclxuaW1wb3J0IHR5cGUge1xyXG4gIERlbGV0ZVZlcnNpb25zSW5wdXQsXHJcbiAgTW9kZWwsXHJcbiAgTW9kZWxQZW5kaW5nSW1wb3J0ZWRWZXJzaW9uc0FyZ3MsXHJcbiAgTW9kZWxWZXJzaW9uQXJncyxcclxuICBNb2RlbFZlcnNpb25zQXJncyxcclxuICBNb3ZlVmVyc2lvbnNJbnB1dCxcclxuICBPblByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkU3Vic2NyaXB0aW9uLFxyXG4gIE9uUHJvamVjdFZlcnNpb25zVXBkYXRlU3Vic2NyaXB0aW9uLFxyXG4gIFByb2plY3QsXHJcbiAgUHJvamVjdE1vZGVsc0FyZ3MsXHJcbiAgUHJvamVjdE1vZGVsc1RyZWVBcmdzLFxyXG4gIFByb2plY3RQZW5kaW5nSW1wb3J0ZWRNb2RlbHNBcmdzLFxyXG4gIFByb2plY3RWZXJzaW9uc0FyZ3MsXHJcbiAgVXBkYXRlVmVyc2lvbklucHV0XHJcbn0gZnJvbSAnfn4vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcbmltcG9ydCB7XHJcbiAgUHJvamVjdFBlbmRpbmdWZXJzaW9uc1VwZGF0ZWRNZXNzYWdlVHlwZSxcclxuICBQcm9qZWN0VmVyc2lvbnNVcGRhdGVkTWVzc2FnZVR5cGVcclxufSBmcm9tICd+fi9saWIvY29tbW9uL2dlbmVyYXRlZC9ncWwvZ3JhcGhxbCdcclxuaW1wb3J0IHsgbW9kZWxSb3V0ZSwgbW9kZWxWZXJzaW9uc1JvdXRlIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9oZWxwZXJzL3JvdXRlJ1xyXG5pbXBvcnQge1xyXG4gIG9uUHJvamVjdFBlbmRpbmdWZXJzaW9uc1VwZGF0ZWRTdWJzY3JpcHRpb24sXHJcbiAgb25Qcm9qZWN0VmVyc2lvbnNVcGRhdGVTdWJzY3JpcHRpb25cclxufSBmcm9tICd+fi9saWIvcHJvamVjdHMvZ3JhcGhxbC9zdWJzY3JpcHRpb25zJ1xyXG5pbXBvcnQge1xyXG4gIGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdCxcclxuICBldmljdE9iamVjdEZpZWxkcyxcclxuICBnZXRDYWNoZUlkLFxyXG4gIGdldEZpcnN0RXJyb3JNZXNzYWdlLFxyXG4gIGdldE9iamVjdFJlZmVyZW5jZSxcclxuICBtb2RpZnlPYmplY3RGaWVsZHNcclxufSBmcm9tICd+fi9saWIvY29tbW9uL2hlbHBlcnMvZ3JhcGhxbCdcclxuaW1wb3J0IHsgcHJvamVjdE1vZGVsVmVyc2lvbnNRdWVyeSB9IGZyb20gJ35+L2xpYi9wcm9qZWN0cy9ncmFwaHFsL3F1ZXJpZXMnXHJcbmltcG9ydCB7XHJcbiAgZGVsZXRlVmVyc2lvbnNNdXRhdGlvbixcclxuICBtb3ZlVmVyc2lvbnNNdXRhdGlvbixcclxuICB1cGRhdGVWZXJzaW9uTXV0YXRpb25cclxufSBmcm9tICd+fi9saWIvcHJvamVjdHMvZ3JhcGhxbC9tdXRhdGlvbnMnXHJcbmltcG9ydCB7IHVzZUFjdGl2ZVVzZXIgfSBmcm9tICd+fi9saWIvYXV0aC9jb21wb3NhYmxlcy9hY3RpdmVVc2VyJ1xyXG5pbXBvcnQgeyB1c2VFdmljdFByb2plY3RNb2RlbEZpZWxkcyB9IGZyb20gJ35+L2xpYi9wcm9qZWN0cy9jb21wb3NhYmxlcy9tb2RlbE1hbmFnZW1lbnQnXHJcbmltcG9ydCB7IGludGVyc2VjdGlvbiwgaXNVbmRlZmluZWQsIHVuaXFCeSB9IGZyb20gJ2xvZGFzaC1lcydcclxuaW1wb3J0IHsgRmlsZVVwbG9hZENvbnZlcnRlZFN0YXR1cyB9IGZyb20gJ35+L2xpYi9jb3JlL2FwaS9maWxlSW1wb3J0J1xyXG5pbXBvcnQgeyB1c2VMb2NrIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9jb21wb3NhYmxlcy9zaW5nbGV0b24nXHJcbmltcG9ydCB7XHJcbiAgdXNlRmFpbGVkRmlsZUltcG9ydEpvYlV0aWxzLFxyXG4gIHVzZUdsb2JhbEZpbGVJbXBvcnRNYW5hZ2VyXHJcbn0gZnJvbSAnfi9saWIvY29yZS9jb21wb3NhYmxlcy9maWxlSW1wb3J0J1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZVByb2plY3RWZXJzaW9uVXBkYXRlVHJhY2tpbmcoXHJcbiAgcHJvamVjdElkOiBNYXliZVJlZjxzdHJpbmc+LFxyXG4gIGhhbmRsZXI/OiAoXHJcbiAgICBkYXRhOiBOb25OdWxsYWJsZTxcclxuICAgICAgR2V0PE9uUHJvamVjdFZlcnNpb25zVXBkYXRlU3Vic2NyaXB0aW9uLCAncHJvamVjdFZlcnNpb25zVXBkYXRlZCc+XHJcbiAgICA+LFxyXG4gICAgY2FjaGU6IEFwb2xsb0NhY2hlPHVua25vd24+XHJcbiAgKSA9PiB2b2lkLFxyXG4gIG9wdGlvbnM/OiBQYXJ0aWFsPHtcclxuICAgIHNpbGVuY2VUb2FzdDogYm9vbGVhblxyXG4gIH0+XHJcbikge1xyXG4gIGNvbnN0IHsgc2lsZW5jZVRvYXN0ID0gZmFsc2UgfSA9IG9wdGlvbnMgfHwge31cclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuXHJcbiAgY29uc3QgeyBoYXNMb2NrIH0gPSB1c2VMb2NrKFxyXG4gICAgY29tcHV0ZWQoKCkgPT4gYHVzZVByb2plY3RWZXJzaW9uVXBkYXRlVHJhY2tpbmctJHt1bnJlZihwcm9qZWN0SWQpfWApXHJcbiAgKVxyXG4gIGNvbnN0IGlzRW5hYmxlZCA9IGNvbXB1dGVkKCgpID0+ICEhKGhhc0xvY2sudmFsdWUgfHwgaGFuZGxlcikpXHJcbiAgY29uc3QgeyBvblJlc3VsdDogb25Qcm9qZWN0VmVyc2lvbnNVcGRhdGUgfSA9IHVzZVN1YnNjcmlwdGlvbihcclxuICAgIG9uUHJvamVjdFZlcnNpb25zVXBkYXRlU3Vic2NyaXB0aW9uLFxyXG4gICAgKCkgPT4gKHtcclxuICAgICAgaWQ6IHVucmVmKHByb2plY3RJZClcclxuICAgIH0pLFxyXG4gICAgeyBlbmFibGVkOiBpc0VuYWJsZWQsIGVycm9yUG9saWN5OiAnYWxsJyB9XHJcbiAgKVxyXG5cclxuICAvLyBDYWNoZSB1cGRhdGVzIHRoYXQgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCBvbmNlXHJcbiAgb25Qcm9qZWN0VmVyc2lvbnNVcGRhdGUoKHJlcykgPT4ge1xyXG4gICAgaWYgKCFyZXMuZGF0YT8ucHJvamVjdFZlcnNpb25zVXBkYXRlZCB8fCAhaGFzTG9jay52YWx1ZSkgcmV0dXJuXHJcblxyXG4gICAgY29uc3QgZXZlbnQgPSByZXMuZGF0YS5wcm9qZWN0VmVyc2lvbnNVcGRhdGVkXHJcbiAgICBjb25zdCB2ZXJzaW9uID0gZXZlbnQudmVyc2lvblxyXG4gICAgaWYgKFxyXG4gICAgICAoXHJcbiAgICAgICAgW1xyXG4gICAgICAgICAgUHJvamVjdFZlcnNpb25zVXBkYXRlZE1lc3NhZ2VUeXBlLkNyZWF0ZWQsXHJcbiAgICAgICAgICBQcm9qZWN0VmVyc2lvbnNVcGRhdGVkTWVzc2FnZVR5cGUuVXBkYXRlZFxyXG4gICAgICAgIF0gYXMgc3RyaW5nW11cclxuICAgICAgKS5pbmNsdWRlcyhldmVudC50eXBlKSAmJlxyXG4gICAgICB2ZXJzaW9uXHJcbiAgICApIHtcclxuICAgICAgLy8gQWRkZWQgbmV3IG1vZGVsIHcvIHZlcnNpb25zIE9SIHVwZGF0ZWQgbW9kZWwgdGhhdCBub3cgaGFzIHZlcnNpb25zIChpdCBtaWdodCBub3QgaGF2ZSBoYWQgdGhlbSBwcmV2aW91c2x5KVxyXG4gICAgICAvLyBTbyAtIGFkZCBpdCB0byB0aGUgbGlzdCwgaWYgaXRzIG5vdCBhbHJlYWR5IHRoZXJlXHJcbiAgICAgIG1vZGlmeU9iamVjdEZpZWxkczxQcm9qZWN0TW9kZWxzQXJncywgUHJvamVjdFsnbW9kZWxzJ10+KFxyXG4gICAgICAgIGFwb2xsby5jYWNoZSxcclxuICAgICAgICBnZXRDYWNoZUlkKCdQcm9qZWN0JywgdW5yZWYocHJvamVjdElkKSksXHJcbiAgICAgICAgKF9maWVsZE5hbWUsIHZhcmlhYmxlcywgdmFsdWUsIHsgcmVmIH0pID0+IHtcclxuICAgICAgICAgIGlmICh2YXJpYWJsZXMuZmlsdGVyPy5zZWFyY2gpIHJldHVyblxyXG5cclxuICAgICAgICAgIGNvbnN0IGxpbWl0ID0gdmFyaWFibGVzLmxpbWl0XHJcbiAgICAgICAgICBjb25zdCBuZXdNb2RlbFJlZiA9IHJlZignTW9kZWwnLCB2ZXJzaW9uLm1vZGVsLmlkKVxyXG4gICAgICAgICAgY29uc3QgbmV3SXRlbXMgPSAodmFsdWU/Lml0ZW1zIHx8IFtdKS5zbGljZSgpXHJcblxyXG4gICAgICAgICAgbGV0IGl0ZW1BZGRlZCA9IGZhbHNlXHJcbiAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICFuZXdJdGVtcy5maW5kKChpKSA9PiBpLl9fcmVmID09PSBuZXdNb2RlbFJlZi5fX3JlZikgJiZcclxuICAgICAgICAgICAgKGlzVW5kZWZpbmVkKGxpbWl0KSB8fCBuZXdJdGVtcy5sZW5ndGggPCBsaW1pdClcclxuICAgICAgICAgICkge1xyXG4gICAgICAgICAgICBuZXdJdGVtcy51bnNoaWZ0KG5ld01vZGVsUmVmKVxyXG4gICAgICAgICAgICBpdGVtQWRkZWQgPSB0cnVlXHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLi4uKHZhbHVlIHx8IHt9KSxcclxuICAgICAgICAgICAgaXRlbXM6IG5ld0l0ZW1zLFxyXG4gICAgICAgICAgICB0b3RhbENvdW50OiAodmFsdWUudG90YWxDb3VudCB8fCAwKSArIChpdGVtQWRkZWQgPyAxIDogMClcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIHsgZmllbGROYW1lV2hpdGVsaXN0OiBbJ21vZGVscyddIH1cclxuICAgICAgKVxyXG5cclxuICAgICAgLy8gKyBFdmljdCBtb2RlbHNUcmVlLCBpZiBpdCBkb2VzbnQgaGF2ZSB0aGlzIG1vZGVsXHJcbiAgICAgIGV2aWN0T2JqZWN0RmllbGRzPFByb2plY3RNb2RlbHNUcmVlQXJncywgUHJvamVjdFsnbW9kZWxzVHJlZSddPihcclxuICAgICAgICBhcG9sbG8uY2FjaGUsXHJcbiAgICAgICAgZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHVucmVmKHByb2plY3RJZCkpLFxyXG4gICAgICAgIChmaWVsZE5hbWUsIHZhcmlhYmxlcywgdmFsdWUsIHsgcmVhZEZpZWxkIH0pID0+IHtcclxuICAgICAgICAgIGlmIChmaWVsZE5hbWUgIT09ICdtb2RlbHNUcmVlJykgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgICBpZiAodmFyaWFibGVzLmZpbHRlcj8uc2VhcmNoKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgIGlmICh2YXJpYWJsZXMuZmlsdGVyPy5jb250cmlidXRvcnM/Lmxlbmd0aCkgcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgICBpZiAodmFyaWFibGVzLmZpbHRlcj8uc291cmNlQXBwcz8ubGVuZ3RoKSByZXR1cm4gZmFsc2VcclxuXHJcbiAgICAgICAgICBjb25zdCBpdGVtcyA9IHZhbHVlPy5pdGVtcyB8fCBbXVxyXG4gICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZ1bGxOYW1lID0gcmVhZEZpZWxkKCdmdWxsTmFtZScsIGl0ZW0pXHJcbiAgICAgICAgICAgIGlmIChmdWxsTmFtZSA9PT0gdmVyc2lvbi5tb2RlbC5uYW1lKSByZXR1cm4gZmFsc2VcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgKVxyXG5cclxuICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFByb2plY3RWZXJzaW9uc1VwZGF0ZWRNZXNzYWdlVHlwZS5DcmVhdGVkKSB7XHJcbiAgICAgICAgLy8gRXZpY3QgcHJvamVjdCB2aWV3ZXIgcmVzb3VyY2UgcmVzb2x1dGlvbiBmaWVsZHNcbiAgICAgICAgZXZpY3RPYmplY3RGaWVsZHMoXG4gICAgICAgICAgYXBvbGxvLmNhY2hlLFxuICAgICAgICAgIGdldENhY2hlSWQoJ1Byb2plY3QnLCB1bnJlZihwcm9qZWN0SWQpKSxcbiAgICAgICAgICAoZmllbGROYW1lKSA9PlxuICAgICAgICAgICAgWyd2aWV3ZXJSZXNvdXJjZXMnLCAndmlld2VyUmVzb3VyY2VzRXh0ZW5kZWQnXS5pbmNsdWRlcyhmaWVsZE5hbWUpXG4gICAgICAgIClcblxyXG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIHBlbmRpbmdWZXJzaW9ucywgaW4gY2FzZSBpdCdzIHRoZXJlXHJcbiAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPFxyXG4gICAgICAgICAgTW9kZWxQZW5kaW5nSW1wb3J0ZWRWZXJzaW9uc0FyZ3MsXHJcbiAgICAgICAgICBNb2RlbFsncGVuZGluZ0ltcG9ydGVkVmVyc2lvbnMnXVxyXG4gICAgICAgID4oXHJcbiAgICAgICAgICBhcG9sbG8uY2FjaGUsXHJcbiAgICAgICAgICBnZXRDYWNoZUlkKCdNb2RlbCcsIHZlcnNpb24ubW9kZWwuaWQpLFxyXG4gICAgICAgICAgKF9maWVsZE5hbWUsIF92YXJpYWJsZXMsIHZhbHVlLCB7IHJlYWRGaWVsZCB9KSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdmFsdWU/Lmxlbmd0aCkgcmV0dXJuXHJcblxyXG4gICAgICAgICAgICAvLyBVbmZvcnR1bmF0ZWx5IG1lc3NhZ2UgbWF0Y2hpbmcgaXMgdGhlIGJlc3Qgd2UgY2FuIGRvXHJcbiAgICAgICAgICAgIGNvbnN0IG5ld01lc3NhZ2UgPSB2ZXJzaW9uLm1lc3NhZ2UgfHwgJydcclxuICAgICAgICAgICAgY29uc3QgcGVuZGluZ1dpdGhGaXR0aW5nTWVzc2FnZUlkeCA9ICh2YWx1ZSB8fCBbXSkuZmluZEluZGV4KChpKSA9PiB7XHJcbiAgICAgICAgICAgICAgY29uc3QgZmlsZU5hbWUgPSA8c3RyaW5nPnJlYWRGaWVsZCgnZmlsZU5hbWUnLCBpKSB8fCAnJ1xyXG4gICAgICAgICAgICAgIHJldHVybiBuZXdNZXNzYWdlLmluY2x1ZGVzKGZpbGVOYW1lKVxyXG4gICAgICAgICAgICB9KVxyXG5cclxuICAgICAgICAgICAgY29uc3QgbmV3VmVyc2lvbnMgPSAodmFsdWUgfHwgW10pLnNsaWNlKClcclxuICAgICAgICAgICAgaWYgKHBlbmRpbmdXaXRoRml0dGluZ01lc3NhZ2VJZHggIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgbmV3VmVyc2lvbnMuc3BsaWNlKHBlbmRpbmdXaXRoRml0dGluZ01lc3NhZ2VJZHgsIDEpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG5ld1ZlcnNpb25zXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgeyBmaWVsZE5hbWVXaGl0ZWxpc3Q6IFsncGVuZGluZ0ltcG9ydGVkVmVyc2lvbnMnXSB9XHJcbiAgICAgICAgKVxyXG5cclxuICAgICAgICAvLyBBZGQgdG8gbW9kZWwudmVyc2lvbnNcclxuICAgICAgICBtb2RpZnlPYmplY3RGaWVsZHM8TW9kZWxWZXJzaW9uc0FyZ3MsIE1vZGVsWyd2ZXJzaW9ucyddPihcclxuICAgICAgICAgIGFwb2xsby5jYWNoZSxcclxuICAgICAgICAgIGdldENhY2hlSWQoJ01vZGVsJywgdmVyc2lvbi5tb2RlbC5pZCksXHJcbiAgICAgICAgICAoX2ZpZWxkTmFtZSwgdmFyaWFibGVzLCB2YWx1ZSwgeyByZWYgfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgdmFyaWFibGVzLmZpbHRlcj8ucHJpb3JpdHlJZHNPbmx5ICYmXHJcbiAgICAgICAgICAgICAgdmFyaWFibGVzLmZpbHRlcj8ucHJpb3JpdHlJZHMgJiZcclxuICAgICAgICAgICAgICAhdmFyaWFibGVzLmZpbHRlci5wcmlvcml0eUlkcy5pbmNsdWRlcyh2ZXJzaW9uLmlkKVxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICByZXR1cm5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgY29uc3QgbGltaXQgPSB2YXJpYWJsZXMubGltaXRcclxuICAgICAgICAgICAgaWYgKCFsaW1pdCkge1xyXG4gICAgICAgICAgICAgIHJldHVybiAvLyBhbHJlYWR5IHVwZGF0ZWQgdGhyb3VnaCBQcm9qZWN0UGFnZUxhdGVzdEl0ZW1zTW9kZWxJdGVtIGZyYWdtZW50IGluIHJlc3BvbnNlXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IG5ld0l0ZW1zID0gKHZhbHVlPy5pdGVtcyB8fCBbXSkuc2xpY2UoKVxyXG5cclxuICAgICAgICAgICAgaWYgKGlzVW5kZWZpbmVkKGxpbWl0KSB8fCBuZXdJdGVtcy5sZW5ndGggPCBsaW1pdCkge1xyXG4gICAgICAgICAgICAgIG5ld0l0ZW1zLnVuc2hpZnQocmVmKCdWZXJzaW9uJywgdmVyc2lvbi5pZCkpXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgLi4uKHZhbHVlIHx8IHt9KSxcclxuICAgICAgICAgICAgICBpdGVtczogbmV3SXRlbXMsXHJcbiAgICAgICAgICAgICAgdG90YWxDb3VudDogKHZhbHVlLnRvdGFsQ291bnQgfHwgMCkgKyAxXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWyd2ZXJzaW9ucyddIH1cclxuICAgICAgICApXHJcblxyXG4gICAgICAgIC8vIEFkZCB0byBwcm9qZWN0LnZlcnNpb25zXHJcbiAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPFByb2plY3RWZXJzaW9uc0FyZ3MsIFByb2plY3RbJ3ZlcnNpb25zJ10+KFxyXG4gICAgICAgICAgYXBvbGxvLmNhY2hlLFxyXG4gICAgICAgICAgZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHVucmVmKHByb2plY3RJZCkpLFxyXG4gICAgICAgICAgKF9maWVsZE5hbWUsIHZhcmlhYmxlcywgdmFsdWUsIHsgcmVmIH0pID0+IHtcclxuICAgICAgICAgICAgY29uc3QgbmV3VmVyc2lvblJlZiA9IHJlZignVmVyc2lvbicsIHZlcnNpb24uaWQpXHJcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0ID0gdmFyaWFibGVzLmxpbWl0XHJcblxyXG4gICAgICAgICAgICBjb25zdCBuZXdJdGVtcyA9ICh2YWx1ZT8uaXRlbXMgfHwgW10pLnNsaWNlKClcclxuICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICFuZXdJdGVtcy5maW5kKChpKSA9PiBpLl9fcmVmID09PSBuZXdWZXJzaW9uUmVmLl9fcmVmKSAmJlxyXG4gICAgICAgICAgICAgIChpc1VuZGVmaW5lZChsaW1pdCkgfHwgbmV3SXRlbXMubGVuZ3RoIDwgbGltaXQpXHJcbiAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgIG5ld0l0ZW1zLnVuc2hpZnQobmV3VmVyc2lvblJlZilcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAuLi4odmFsdWUgfHwge30pLFxyXG4gICAgICAgICAgICAgIGl0ZW1zOiBuZXdJdGVtcyxcclxuICAgICAgICAgICAgICB0b3RhbENvdW50OiAodmFsdWUudG90YWxDb3VudCB8fCAwKSArIDFcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHsgZmllbGROYW1lV2hpdGVsaXN0OiBbJ3ZlcnNpb25zJ10gfVxyXG4gICAgICAgIClcclxuXHJcbiAgICAgICAgLy8gUG90ZW50aWFsbHkgcmVtb3ZlIGl0ZW0gZnJvbSBQcm9qZWN0LnBlbmRpbmdJbXBvcnRlZE1vZGVscz9cclxuICAgICAgICAvLyBSZW1vdmUgZnJvbSBwZW5kaW5nIG1vZGVscz9cclxuICAgICAgICBtb2RpZnlPYmplY3RGaWVsZHM8XHJcbiAgICAgICAgICBQcm9qZWN0UGVuZGluZ0ltcG9ydGVkTW9kZWxzQXJncyxcclxuICAgICAgICAgIFByb2plY3RbJ3BlbmRpbmdJbXBvcnRlZE1vZGVscyddXHJcbiAgICAgICAgPihcclxuICAgICAgICAgIGFwb2xsby5jYWNoZSxcclxuICAgICAgICAgIGdldENhY2hlSWQoJ1Byb2plY3QnLCB1bnJlZihwcm9qZWN0SWQpKSxcclxuICAgICAgICAgIChfZmllbGROYW1lLCBfdmFyaWFibGVzLCB2YWx1ZSwgeyByZWFkRmllbGQgfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXZhbHVlPy5sZW5ndGgpIHJldHVyblxyXG5cclxuICAgICAgICAgICAgY29uc3QgdmVyc2lvbk1vZGVsTmFtZSA9IHZlcnNpb24ubW9kZWwubmFtZVxyXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50TW9kZWxzID0gKHZhbHVlIHx8IFtdKS5maWx0ZXIoKGkpID0+IHtcclxuICAgICAgICAgICAgICBjb25zdCBpdGVtTW9kZWxOYW1lID0gcmVhZEZpZWxkKCdtb2RlbE5hbWUnLCBpKVxyXG4gICAgICAgICAgICAgIHJldHVybiBpdGVtTW9kZWxOYW1lICE9PSB2ZXJzaW9uTW9kZWxOYW1lXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50TW9kZWxzXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgeyBmaWVsZE5hbWVXaGl0ZWxpc3Q6IFsncGVuZGluZ0ltcG9ydGVkTW9kZWxzJ10gfVxyXG4gICAgICAgIClcclxuXHJcbiAgICAgICAgLy8gRW1pdCB0b2FzdFxyXG4gICAgICAgIGlmICghc2lsZW5jZVRvYXN0KSB7XHJcbiAgICAgICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLkluZm8sXHJcbiAgICAgICAgICAgIHRpdGxlOiAnQSBuZXcgdmVyc2lvbiB3YXMgY3JlYXRlZCEnLFxyXG4gICAgICAgICAgICBjdGE6IHtcclxuICAgICAgICAgICAgICB0aXRsZTogJ1ZpZXcgVmVyc2lvbicsXHJcbiAgICAgICAgICAgICAgdXJsOiBtb2RlbFJvdXRlKFxyXG4gICAgICAgICAgICAgICAgdW5yZWYocHJvamVjdElkKSxcclxuICAgICAgICAgICAgICAgIFNwZWNrbGVWaWV3ZXIuVmlld2VyUm91dGUucmVzb3VyY2VCdWlsZGVyKClcclxuICAgICAgICAgICAgICAgICAgLmFkZE1vZGVsKHZlcnNpb24ubW9kZWwuaWQsIHZlcnNpb24uaWQpXHJcbiAgICAgICAgICAgICAgICAgIC50b1N0cmluZygpXHJcbiAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBQcm9qZWN0VmVyc2lvbnNVcGRhdGVkTWVzc2FnZVR5cGUuRGVsZXRlZCkge1xyXG4gICAgICAvLyBEZWxldGUgZnJvbSBjYWNoZVxyXG4gICAgICBhcG9sbG8uY2FjaGUuZXZpY3Qoe1xyXG4gICAgICAgIGlkOiBnZXRDYWNoZUlkKCdWZXJzaW9uJywgZXZlbnQuaWQpXHJcbiAgICAgIH0pXHJcblxyXG4gICAgICBpZiAoZXZlbnQubW9kZWxJZCkge1xyXG4gICAgICAgIC8vIEV2aWN0IHN0YWxlIG1vZGVsIGZpZWxkc1xyXG4gICAgICAgIGV2aWN0T2JqZWN0RmllbGRzKFxyXG4gICAgICAgICAgYXBvbGxvLmNhY2hlLFxyXG4gICAgICAgICAgZ2V0Q2FjaGVJZCgnTW9kZWwnLCBldmVudC5tb2RlbElkKSxcclxuICAgICAgICAgIChmaWVsZE5hbWUpID0+XHJcbiAgICAgICAgICAgIFsndXBkYXRlZEF0JywgJ3ByZXZpZXdVcmwnLCAndmVyc2lvbkNvdW50JywgJ3ZlcnNpb25zJ10uaW5jbHVkZXMoZmllbGROYW1lKVxyXG4gICAgICAgIClcclxuXHJcbiAgICAgICAgLy8gRXZpY3QgcHJvamVjdCB2aWV3ZXIgcmVzb3VyY2UgcmVzb2x1dGlvbiBmaWVsZHNcbiAgICAgICAgYXBvbGxvLmNhY2hlLmV2aWN0KHtcbiAgICAgICAgICBpZDogZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHVucmVmKHByb2plY3RJZCkpLFxuICAgICAgICAgIGZpZWxkTmFtZTogJ3ZpZXdlclJlc291cmNlcydcbiAgICAgICAgfSlcbiAgICAgICAgYXBvbGxvLmNhY2hlLmV2aWN0KHtcbiAgICAgICAgICBpZDogZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIHVucmVmKHByb2plY3RJZCkpLFxuICAgICAgICAgIGZpZWxkTmFtZTogJ3ZpZXdlclJlc291cmNlc0V4dGVuZGVkJ1xuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cclxuICB9KVxyXG5cclxuICBvblByb2plY3RWZXJzaW9uc1VwZGF0ZSgocmVzKSA9PiB7XHJcbiAgICBpZiAoIXJlcy5kYXRhPy5wcm9qZWN0VmVyc2lvbnNVcGRhdGVkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCBldmVudCA9IHJlcy5kYXRhLnByb2plY3RWZXJzaW9uc1VwZGF0ZWRcclxuICAgIGhhbmRsZXI/LihldmVudCwgYXBvbGxvLmNhY2hlKVxyXG4gIH0pXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VNb2RlbFZlcnNpb25zKHBhcmFtczoge1xyXG4gIHByb2plY3RJZDogTWF5YmVSZWY8c3RyaW5nPlxyXG4gIG1vZGVsSWQ6IE1heWJlUmVmPHN0cmluZz5cclxufSkge1xyXG4gIGNvbnN0IHsgcHJvamVjdElkLCBtb2RlbElkIH0gPSBwYXJhbXNcclxuXHJcbiAgY29uc3QgY3Vyc29yID0gcmVmKG51bGwgYXMgTnVsbGFibGU8c3RyaW5nPilcclxuICBjb25zdCB7IHJlc3VsdCwgZmV0Y2hNb3JlLCBvblJlc3VsdCB9ID0gdXNlUXVlcnkocHJvamVjdE1vZGVsVmVyc2lvbnNRdWVyeSwgKCkgPT4gKHtcclxuICAgIHByb2plY3RJZDogdW5yZWYocHJvamVjdElkKSxcclxuICAgIG1vZGVsSWQ6IHVucmVmKG1vZGVsSWQpLFxyXG4gICAgdmVyc2lvbnNDdXJzb3I6IGN1cnNvci52YWx1ZVxyXG4gIH0pKVxyXG5cclxuICBvblJlc3VsdCgocmVzKSA9PiB7XHJcbiAgICBjdXJzb3IudmFsdWUgPSByZXMuZGF0YS5wcm9qZWN0Py5tb2RlbD8udmVyc2lvbnMuY3Vyc29yIHx8IG51bGxcclxuICB9KVxyXG5cclxuICBjb25zdCB2ZXJzaW9ucyA9IGNvbXB1dGVkKCgpID0+IHJlc3VsdC52YWx1ZT8ucHJvamVjdD8ubW9kZWw/LnZlcnNpb25zKVxyXG4gIGNvbnN0IG1vcmVUb0xvYWQgPSBjb21wdXRlZChcclxuICAgICgpID0+XHJcbiAgICAgICghdmVyc2lvbnMudmFsdWUgfHwgdmVyc2lvbnMudmFsdWUuaXRlbXMubGVuZ3RoIDwgdmVyc2lvbnMudmFsdWUudG90YWxDb3VudCkgJiZcclxuICAgICAgY3Vyc29yLnZhbHVlXHJcbiAgKVxyXG5cclxuICBjb25zdCBsb2FkTW9yZSA9ICgpID0+IHtcclxuICAgIGlmICghbW9yZVRvTG9hZC52YWx1ZSkgcmV0dXJuXHJcbiAgICByZXR1cm4gZmV0Y2hNb3JlKHsgdmFyaWFibGVzOiB7IHZlcnNpb25zQ3Vyc29yOiBjdXJzb3IudmFsdWUgfSB9KVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIHZlcnNpb25zLFxyXG4gICAgbG9hZE1vcmUsXHJcbiAgICBtb3JlVG9Mb2FkXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlRGVsZXRlVmVyc2lvbnMoKSB7XHJcbiAgY29uc3QgYXBvbGxvID0gdXNlQXBvbGxvQ2xpZW50KCkuY2xpZW50XHJcbiAgY29uc3QgeyB0cmlnZ2VyTm90aWZpY2F0aW9uIH0gPSB1c2VHbG9iYWxUb2FzdCgpXHJcbiAgY29uc3QgeyBpc0xvZ2dlZEluIH0gPSB1c2VBY3RpdmVVc2VyKClcclxuXHJcbiAgcmV0dXJuIGFzeW5jIChcclxuICAgIGlucHV0OiBEZWxldGVWZXJzaW9uc0lucHV0LFxyXG4gICAgLyoqXHJcbiAgICAgKiBWYXJpb3VzIG9wdGlvbnMgZm9yIGJldHRlciBjYWNoZSB1cGRhdGVzLCBzZXQgaWYgcG9zc2libGVcclxuICAgICAqL1xyXG4gICAgb3B0aW9ucz86IFBhcnRpYWw8e1xyXG4gICAgICBtb2RlbElkOiBzdHJpbmdcclxuICAgIH0+XHJcbiAgKSA9PiB7XHJcbiAgICBpZiAoIWlucHV0LnZlcnNpb25JZHMubGVuZ3RoKSByZXR1cm5cclxuICAgIGlmICghaXNMb2dnZWRJbi52YWx1ZSkgcmV0dXJuXHJcblxyXG4gICAgY29uc3QgeyBkYXRhLCBlcnJvcnMgfSA9IGF3YWl0IGFwb2xsb1xyXG4gICAgICAubXV0YXRlKHtcclxuICAgICAgICBtdXRhdGlvbjogZGVsZXRlVmVyc2lvbnNNdXRhdGlvbixcclxuICAgICAgICB2YXJpYWJsZXM6IHsgaW5wdXQgfSxcclxuICAgICAgICB1cGRhdGU6IChjYWNoZSwgeyBkYXRhIH0pID0+IHtcclxuICAgICAgICAgIGlmICghZGF0YT8udmVyc2lvbk11dGF0aW9ucy5kZWxldGUpIHJldHVyblxyXG5cclxuICAgICAgICAgIC8vIEV2aWN0IGFsbCB2ZXJzaW9ucyBmcm9tIGNhY2hlXHJcbiAgICAgICAgICBmb3IgKGNvbnN0IHZlcnNpb25JZCBvZiBpbnB1dC52ZXJzaW9uSWRzKSB7XHJcbiAgICAgICAgICAgIGNhY2hlLmV2aWN0KHtcclxuICAgICAgICAgICAgICBpZDogZ2V0Q2FjaGVJZCgnVmVyc2lvbicsIHZlcnNpb25JZClcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBVcGRhdGUgdG90YWxDb3VudHMgaW4gcHJvamVjdFxyXG4gICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPFByb2plY3RWZXJzaW9uc0FyZ3MsIFByb2plY3RbJ3ZlcnNpb25zJ10+KFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnUHJvamVjdCcsIGlucHV0LnByb2plY3RJZCksXHJcbiAgICAgICAgICAgIChfZmllbGROYW1lLCBfdmFyaWFibGVzLCBkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIC4uLmRhdGEsXHJcbiAgICAgICAgICAgICAgICAuLi4oIWlzVW5kZWZpbmVkKGRhdGEudG90YWxDb3VudClcclxuICAgICAgICAgICAgICAgICAgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0b3RhbENvdW50OiBNYXRoLm1heChkYXRhLnRvdGFsQ291bnQgLSBpbnB1dC52ZXJzaW9uSWRzLmxlbmd0aCwgMClcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIDoge30pXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWyd2ZXJzaW9ucyddIH1cclxuICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAvLyBVcGRhdGUgdG90YWxDb3VudHMgaW4gbW9kZWxcclxuICAgICAgICAgIGlmIChvcHRpb25zPy5tb2RlbElkKSB7XHJcbiAgICAgICAgICAgIG1vZGlmeU9iamVjdEZpZWxkczxNb2RlbFZlcnNpb25zQXJncywgTW9kZWxbJ3ZlcnNpb25zJ10+KFxyXG4gICAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICAgIGdldENhY2hlSWQoJ01vZGVsJywgb3B0aW9ucy5tb2RlbElkKSxcclxuICAgICAgICAgICAgICAoX2ZpZWxkTmFtZSwgdmFyaWFibGVzLCBkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlZENvdW50ID0gaW5wdXQudmVyc2lvbklkcy5sZW5ndGhcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgdmFyaWFibGVzLmZpbHRlcj8ucHJpb3JpdHlJZHNPbmx5ICYmXHJcbiAgICAgICAgICAgICAgICAgIHZhcmlhYmxlcy5maWx0ZXI/LnByaW9yaXR5SWRzXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgY29uc3QgaWRJbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb24oXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzLmZpbHRlci5wcmlvcml0eUlkcyxcclxuICAgICAgICAgICAgICAgICAgICBpbnB1dC52ZXJzaW9uSWRzXHJcbiAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgaWYgKGlkSW50ZXJzZWN0aW9uLmxlbmd0aCA8IDEpIHJldHVyblxyXG4gICAgICAgICAgICAgICAgICByZW1vdmVkQ291bnQgPSBpZEludGVyc2VjdGlvbi5sZW5ndGhcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAuLi5kYXRhLFxyXG4gICAgICAgICAgICAgICAgICAuLi4oIWlzVW5kZWZpbmVkKGRhdGEudG90YWxDb3VudClcclxuICAgICAgICAgICAgICAgICAgICA/IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxDb3VudDogTWF0aC5tYXgoZGF0YS50b3RhbENvdW50IC0gcmVtb3ZlZENvdW50LCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIDoge30pXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWyd2ZXJzaW9ucyddIH1cclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAoZGF0YT8udmVyc2lvbk11dGF0aW9ucy5kZWxldGUpIHtcclxuICAgICAgY29uc3QgZGVsZXRlQ291bnQgPSBpbnB1dC52ZXJzaW9uSWRzLmxlbmd0aFxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuSW5mbyxcclxuICAgICAgICB0aXRsZTogYCR7ZGVsZXRlQ291bnR9IHZlcnNpb24ke2RlbGV0ZUNvdW50ID4gMSA/ICdzJyA6ICcnfSBkZWxldGVkYFxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnVmVyc2lvbiBkZWxldGlvbiBmYWlsZWQnLFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBlcnJNc2dcclxuICAgICAgfSlcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gISFkYXRhPy52ZXJzaW9uTXV0YXRpb25zLmRlbGV0ZVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZU1vdmVWZXJzaW9ucygpIHtcclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuICBjb25zdCB7IHRyaWdnZXJOb3RpZmljYXRpb24gfSA9IHVzZUdsb2JhbFRvYXN0KClcclxuICBjb25zdCB7IGlzTG9nZ2VkSW4gfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IGV2aWN0UHJvamVjdE1vZGVscyA9IHVzZUV2aWN0UHJvamVjdE1vZGVsRmllbGRzKClcclxuXHJcbiAgcmV0dXJuIGFzeW5jIChcclxuICAgIGlucHV0OiBNb3ZlVmVyc2lvbnNJbnB1dCxcclxuICAgIG9wdGlvbnM/OiBQYXJ0aWFsPHtcclxuICAgICAgcHJldmlvdXNNb2RlbElkOiBzdHJpbmdcclxuICAgICAgbmV3TW9kZWxDcmVhdGVkOiBib29sZWFuXHJcbiAgICB9PlxyXG4gICkgPT4ge1xyXG4gICAgaWYgKCFpbnB1dC52ZXJzaW9uSWRzLmxlbmd0aCB8fCAhaW5wdXQudGFyZ2V0TW9kZWxOYW1lLnRyaW0oKSkgcmV0dXJuXHJcbiAgICBpZiAoIWlzTG9nZ2VkSW4udmFsdWUpIHJldHVyblxyXG5cclxuICAgIGNvbnN0IHsgZGF0YSwgZXJyb3JzIH0gPSBhd2FpdCBhcG9sbG9cclxuICAgICAgLm11dGF0ZSh7XHJcbiAgICAgICAgbXV0YXRpb246IG1vdmVWZXJzaW9uc011dGF0aW9uLFxyXG4gICAgICAgIHZhcmlhYmxlczogeyBpbnB1dCB9LFxyXG4gICAgICAgIHVwZGF0ZTogKGNhY2hlLCB7IGRhdGEgfSkgPT4ge1xyXG4gICAgICAgICAgaWYgKCFkYXRhPy52ZXJzaW9uTXV0YXRpb25zLm1vdmVUb01vZGVsLmlkKSByZXR1cm5cclxuXHJcbiAgICAgICAgICBjb25zdCBuZXdNb2RlbElkID0gZGF0YS52ZXJzaW9uTXV0YXRpb25zLm1vdmVUb01vZGVsLmlkXHJcbiAgICAgICAgICBjb25zdCBwcmV2aW91c01vZGVsSWQgPSBvcHRpb25zPy5wcmV2aW91c01vZGVsSWRcclxuICAgICAgICAgIGlmICghcHJldmlvdXNNb2RlbElkKSByZXR1cm5cclxuXHJcbiAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBNb2RlbC52ZXJzaW9uXHJcbiAgICAgICAgICBtb2RpZnlPYmplY3RGaWVsZHM8TW9kZWxWZXJzaW9uQXJncz4oXHJcbiAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICBnZXRDYWNoZUlkKCdNb2RlbCcsIHByZXZpb3VzTW9kZWxJZCksXHJcbiAgICAgICAgICAgIChfZmllbGROYW1lLCB2YXJpYWJsZXMpID0+IHtcclxuICAgICAgICAgICAgICBpZiAoIWlucHV0LnZlcnNpb25JZHMuaW5jbHVkZXModmFyaWFibGVzLmlkKSkgcmV0dXJuXHJcblxyXG4gICAgICAgICAgICAgIC8vIFNldCB0byBudWxsXHJcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGxcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgeyBmaWVsZE5hbWVXaGl0ZWxpc3Q6IFsndmVyc2lvbiddIH1cclxuICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBNb2RlbC52ZXJzaW9uc1xyXG4gICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPE1vZGVsVmVyc2lvbnNBcmdzLCBNb2RlbFsndmVyc2lvbnMnXT4oXHJcbiAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICBnZXRDYWNoZUlkKCdNb2RlbCcsIHByZXZpb3VzTW9kZWxJZCksXHJcbiAgICAgICAgICAgIChfZmllbGROYW1lLCBfdmFyaWFibGVzLCBkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgICAgY29uc3Qgb2xkSXRlbXMgPSBkYXRhLml0ZW1zIHx8IFtdXHJcbiAgICAgICAgICAgICAgY29uc3QgbmV3SXRlbXMgPSBvbGRJdGVtcy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgICAoaSkgPT5cclxuICAgICAgICAgICAgICAgICAgIWlucHV0LnZlcnNpb25JZHNcclxuICAgICAgICAgICAgICAgICAgICAubWFwKChpZCkgPT4gZ2V0Q2FjaGVJZCgnVmVyc2lvbicsIGlkKSlcclxuICAgICAgICAgICAgICAgICAgICAuaW5jbHVkZXMoaS5fX3JlZilcclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgY29uc3QgcmVtb3ZlZEl0ZW1zQ291bnQgPSBNYXRoLm1heCgwLCBvbGRJdGVtcy5sZW5ndGggLSBuZXdJdGVtcy5sZW5ndGgpXHJcblxyXG4gICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAuLi5kYXRhLFxyXG4gICAgICAgICAgICAgICAgLi4uKGRhdGEuaXRlbXMgPyB7IGl0ZW1zOiBuZXdJdGVtcyB9IDoge30pLFxyXG4gICAgICAgICAgICAgICAgLi4uKCFpc1VuZGVmaW5lZChkYXRhLnRvdGFsQ291bnQpXHJcbiAgICAgICAgICAgICAgICAgID8ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdG90YWxDb3VudDogZGF0YS50b3RhbENvdW50IC0gcmVtb3ZlZEl0ZW1zQ291bnRcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIDoge30pXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWyd2ZXJzaW9ucyddIH1cclxuICAgICAgICAgIClcclxuXHJcbiAgICAgICAgICAvLyBBZGQgdG8gbmV3IG1vZGVsJ3MgTW9kZWwudmVyc2lvblxyXG4gICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPE1vZGVsVmVyc2lvbkFyZ3M+KFxyXG4gICAgICAgICAgICBjYWNoZSxcclxuICAgICAgICAgICAgZ2V0Q2FjaGVJZCgnTW9kZWwnLCBuZXdNb2RlbElkKSxcclxuICAgICAgICAgICAgKF9maWVsZE5hbWUsIHZhcmlhYmxlcykgPT4ge1xyXG4gICAgICAgICAgICAgIGlmICghaW5wdXQudmVyc2lvbklkcy5pbmNsdWRlcyh2YXJpYWJsZXMuaWQpKSByZXR1cm5cclxuICAgICAgICAgICAgICByZXR1cm4gZ2V0T2JqZWN0UmVmZXJlbmNlKCdWZXJzaW9uJywgdmFyaWFibGVzLmlkKVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7IGZpZWxkTmFtZVdoaXRlbGlzdDogWyd2ZXJzaW9uJ10gfVxyXG4gICAgICAgICAgKVxyXG5cclxuICAgICAgICAgIC8vIEFkZCB0byBuZXcgbW9kZWwncyBNb2RlbC52ZXJzaW9uc1xyXG4gICAgICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPE1vZGVsVmVyc2lvbnNBcmdzLCBNb2RlbFsndmVyc2lvbnMnXT4oXHJcbiAgICAgICAgICAgIGNhY2hlLFxyXG4gICAgICAgICAgICBnZXRDYWNoZUlkKCdNb2RlbCcsIG5ld01vZGVsSWQpLFxyXG4gICAgICAgICAgICAoX2ZpZWxkTmFtZSwgX3ZhcmlhYmxlcywgZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgIGNvbnN0IG9sZEl0ZW1zID0gZGF0YS5pdGVtcyB8fCBbXVxyXG4gICAgICAgICAgICAgIGNvbnN0IG5ld0l0ZW1zID0gW1xyXG4gICAgICAgICAgICAgICAgLi4uaW5wdXQudmVyc2lvbklkcy5tYXAoKGkpID0+IGdldE9iamVjdFJlZmVyZW5jZSgnVmVyc2lvbicsIGkpKSxcclxuICAgICAgICAgICAgICAgIC4uLm9sZEl0ZW1zXHJcbiAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICAgIGNvbnN0IGFkZGVkSXRlbUFtb3VudCA9IG5ld0l0ZW1zLmxlbmd0aCAtIG9sZEl0ZW1zLmxlbmd0aFxyXG5cclxuICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgLi4uZGF0YSxcclxuICAgICAgICAgICAgICAgIC4uLihkYXRhLml0ZW1zID8geyBpdGVtczogbmV3SXRlbXMgfSA6IHt9KSxcclxuICAgICAgICAgICAgICAgIC4uLighaXNVbmRlZmluZWQoZGF0YS50b3RhbENvdW50KVxyXG4gICAgICAgICAgICAgICAgICA/IHtcclxuICAgICAgICAgICAgICAgICAgICAgIHRvdGFsQ291bnQ6IGRhdGEudG90YWxDb3VudCArIGFkZGVkSXRlbUFtb3VudFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgOiB7fSlcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHsgZmllbGROYW1lV2hpdGVsaXN0OiBbJ3ZlcnNpb25zJ10gfVxyXG4gICAgICAgICAgKVxyXG5cclxuICAgICAgICAgIGlmIChvcHRpb25zPy5uZXdNb2RlbENyZWF0ZWQpIHtcclxuICAgICAgICAgICAgZXZpY3RQcm9qZWN0TW9kZWxzKGlucHV0LnByb2plY3RJZClcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQpXHJcblxyXG4gICAgaWYgKGRhdGE/LnZlcnNpb25NdXRhdGlvbnMubW92ZVRvTW9kZWwuaWQpIHtcclxuICAgICAgY29uc3QgZGVsZXRlQ291bnQgPSBpbnB1dC52ZXJzaW9uSWRzLmxlbmd0aFxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuSW5mbyxcclxuICAgICAgICB0aXRsZTogYCR7ZGVsZXRlQ291bnR9IHZlcnNpb24ke2RlbGV0ZUNvdW50ID4gMSA/ICdzJyA6ICcnfSBtb3ZlZGAsXHJcbiAgICAgICAgY3RhOiB7XHJcbiAgICAgICAgICB0aXRsZTogJ1ZpZXcgdmVyc2lvbnMnLFxyXG4gICAgICAgICAgdXJsOiBtb2RlbFZlcnNpb25zUm91dGUoaW5wdXQucHJvamVjdElkLCBkYXRhLnZlcnNpb25NdXRhdGlvbnMubW92ZVRvTW9kZWwuaWQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnVmVyc2lvbiBtb3ZlIGZhaWxlZCcsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGVyck1zZ1xyXG4gICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAhIWRhdGE/LnZlcnNpb25NdXRhdGlvbnMubW92ZVRvTW9kZWwuaWRcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1c2VVcGRhdGVWZXJzaW9uKCkge1xyXG4gIGNvbnN0IGFwb2xsbyA9IHVzZUFwb2xsb0NsaWVudCgpLmNsaWVudFxyXG4gIGNvbnN0IHsgdHJpZ2dlck5vdGlmaWNhdGlvbiB9ID0gdXNlR2xvYmFsVG9hc3QoKVxyXG4gIGNvbnN0IHsgaXNMb2dnZWRJbiB9ID0gdXNlQWN0aXZlVXNlcigpXHJcblxyXG4gIHJldHVybiBhc3luYyAoaW5wdXQ6IFVwZGF0ZVZlcnNpb25JbnB1dCkgPT4ge1xyXG4gICAgaWYgKCFpbnB1dC52ZXJzaW9uSWQpIHJldHVyblxyXG4gICAgaWYgKCFpc0xvZ2dlZEluLnZhbHVlKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCB7IGRhdGEsIGVycm9ycyB9ID0gYXdhaXQgYXBvbGxvXHJcbiAgICAgIC5tdXRhdGUoe1xyXG4gICAgICAgIG11dGF0aW9uOiB1cGRhdGVWZXJzaW9uTXV0YXRpb24sXHJcbiAgICAgICAgdmFyaWFibGVzOiB7IGlucHV0IH1cclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGNvbnZlcnRUaHJvd0ludG9GZXRjaFJlc3VsdClcclxuXHJcbiAgICBpZiAoZGF0YT8udmVyc2lvbk11dGF0aW9ucy51cGRhdGUuaWQpIHtcclxuICAgICAgdHJpZ2dlck5vdGlmaWNhdGlvbih7XHJcbiAgICAgICAgdHlwZTogVG9hc3ROb3RpZmljYXRpb25UeXBlLlN1Y2Nlc3MsXHJcbiAgICAgICAgdGl0bGU6IGBWZXJzaW9uIHN1Y2Nlc3NmdWxseSB1cGRhdGVkYFxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZXJyTXNnID0gZ2V0Rmlyc3RFcnJvck1lc3NhZ2UoZXJyb3JzKVxyXG4gICAgICB0cmlnZ2VyTm90aWZpY2F0aW9uKHtcclxuICAgICAgICB0eXBlOiBUb2FzdE5vdGlmaWNhdGlvblR5cGUuRGFuZ2VyLFxyXG4gICAgICAgIHRpdGxlOiAnVmVyc2lvbiB1cGRhdGUgZmFpbGVkJyxcclxuICAgICAgICBkZXNjcmlwdGlvbjogZXJyTXNnXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRhdGE/LnZlcnNpb25NdXRhdGlvbnMudXBkYXRlXHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlUHJvamVjdFBlbmRpbmdWZXJzaW9uVXBkYXRlVHJhY2tpbmcoXHJcbiAgcHJvamVjdElkOiBNYXliZVJlZjxzdHJpbmc+LFxyXG4gIGhhbmRsZXI/OiAoXHJcbiAgICBkYXRhOiBOb25OdWxsYWJsZTxcclxuICAgICAgR2V0PE9uUHJvamVjdFBlbmRpbmdWZXJzaW9uc1VwZGF0ZWRTdWJzY3JpcHRpb24sICdwcm9qZWN0UGVuZGluZ1ZlcnNpb25zVXBkYXRlZCc+XHJcbiAgICA+LFxyXG4gICAgY2FjaGU6IEFwb2xsb0NhY2hlPHVua25vd24+XHJcbiAgKSA9PiB2b2lkXHJcbikge1xyXG4gIGNvbnN0IHsgaGFzTG9jayB9ID0gdXNlTG9jayhcclxuICAgIGNvbXB1dGVkKCgpID0+IGB1c2VQcm9qZWN0UGVuZGluZ1ZlcnNpb25VcGRhdGVUcmFja2luZy0ke3VucmVmKHByb2plY3RJZCl9YClcclxuICApXHJcblxyXG4gIGNvbnN0IHsgYWRkRmFpbGVkSm9iIH0gPSB1c2VHbG9iYWxGaWxlSW1wb3J0TWFuYWdlcigpXHJcbiAgY29uc3QgeyBjb252ZXJ0VXBsb2FkVG9GYWlsZWRKb2IgfSA9IHVzZUZhaWxlZEZpbGVJbXBvcnRKb2JVdGlscygpXHJcbiAgY29uc3QgeyB1c2VySWQgfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG4gIGNvbnN0IGlzRW5hYmxlZCA9IGNvbXB1dGVkKCgpID0+ICEhKGhhc0xvY2sudmFsdWUgfHwgaGFuZGxlcikpXHJcbiAgY29uc3QgeyBvblJlc3VsdDogb25Qcm9qZWN0UGVuZGluZ1ZlcnNpb25zVXBkYXRlIH0gPSB1c2VTdWJzY3JpcHRpb24oXHJcbiAgICBvblByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkU3Vic2NyaXB0aW9uLFxyXG4gICAgKCkgPT4gKHtcclxuICAgICAgaWQ6IHVucmVmKHByb2plY3RJZClcclxuICAgIH0pLFxyXG4gICAgeyBlbmFibGVkOiBpc0VuYWJsZWQsIGVycm9yUG9saWN5OiAnYWxsJyB9XHJcbiAgKVxyXG5cclxuICBjb25zdCBhcG9sbG8gPSB1c2VBcG9sbG9DbGllbnQoKS5jbGllbnRcclxuXHJcbiAgb25Qcm9qZWN0UGVuZGluZ1ZlcnNpb25zVXBkYXRlKChyZXMpID0+IHtcclxuICAgIGlmICghcmVzLmRhdGE/LnByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkLmlkIHx8ICFoYXNMb2NrLnZhbHVlKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCBldmVudCA9IHJlcy5kYXRhLnByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkXHJcbiAgICBjb25zdCBtb2RlbElkID0gZXZlbnQudmVyc2lvbi5tb2RlbD8uaWRcclxuICAgIGlmICghbW9kZWxJZCkgcmV0dXJuXHJcblxyXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09IFByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkTWVzc2FnZVR5cGUuQ3JlYXRlZCkge1xyXG4gICAgICAvLyBJbnNlcnQgaW50byBtb2RlbC5wZW5kaW5nVmVyc2lvbnNcclxuICAgICAgbW9kaWZ5T2JqZWN0RmllbGRzPFxyXG4gICAgICAgIE1vZGVsUGVuZGluZ0ltcG9ydGVkVmVyc2lvbnNBcmdzLFxyXG4gICAgICAgIE1vZGVsWydwZW5kaW5nSW1wb3J0ZWRWZXJzaW9ucyddXHJcbiAgICAgID4oXHJcbiAgICAgICAgYXBvbGxvLmNhY2hlLFxyXG4gICAgICAgIGdldENhY2hlSWQoJ01vZGVsJywgbW9kZWxJZCksXHJcbiAgICAgICAgKF9maWVsZE5hbWUsIF92YXJpYWJsZXMsIHZhbHVlLCB7IHJlZiB9KSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBjdXJyZW50VmVyc2lvbnMgPSAodmFsdWUgfHwgW10pLnNsaWNlKClcclxuICAgICAgICAgIGN1cnJlbnRWZXJzaW9ucy5wdXNoKHJlZignRmlsZVVwbG9hZCcsIGV2ZW50LmlkKSlcclxuICAgICAgICAgIHJldHVybiB1bmlxQnkoY3VycmVudFZlcnNpb25zLCAodikgPT4gdi5fX3JlZilcclxuICAgICAgICB9LFxyXG4gICAgICAgIHsgZmllbGROYW1lV2hpdGVsaXN0OiBbJ3BlbmRpbmdJbXBvcnRlZFZlcnNpb25zJ10gfVxyXG4gICAgICApXHJcbiAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkTWVzc2FnZVR5cGUuVXBkYXRlZCkge1xyXG4gICAgICBjb25zdCBzdWNjZXNzID1cclxuICAgICAgICBldmVudC52ZXJzaW9uLmNvbnZlcnRlZFN0YXR1cyA9PT0gRmlsZVVwbG9hZENvbnZlcnRlZFN0YXR1cy5Db21wbGV0ZWRcclxuICAgICAgY29uc3QgZmFpbHVyZSA9IGV2ZW50LnZlcnNpb24uY29udmVydGVkU3RhdHVzID09PSBGaWxlVXBsb2FkQ29udmVydGVkU3RhdHVzLkVycm9yXHJcblxyXG4gICAgICBpZiAoc3VjY2Vzcykge1xyXG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIG1vZGVsLnBlbmRpbmdWZXJzaW9uc1xyXG4gICAgICAgIG1vZGlmeU9iamVjdEZpZWxkczxcclxuICAgICAgICAgIE1vZGVsUGVuZGluZ0ltcG9ydGVkVmVyc2lvbnNBcmdzLFxyXG4gICAgICAgICAgTW9kZWxbJ3BlbmRpbmdJbXBvcnRlZFZlcnNpb25zJ11cclxuICAgICAgICA+KFxyXG4gICAgICAgICAgYXBvbGxvLmNhY2hlLFxyXG4gICAgICAgICAgZ2V0Q2FjaGVJZCgnTW9kZWwnLCBtb2RlbElkKSxcclxuICAgICAgICAgIChfZmllbGROYW1lLCBfdmFyaWFibGVzLCB2YWx1ZSwgeyByZWYgfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXZhbHVlPy5sZW5ndGgpIHJldHVyblxyXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50VmVyc2lvbnMgPSAodmFsdWUgfHwgW10pLmZpbHRlcihcclxuICAgICAgICAgICAgICAoaSkgPT4gaS5fX3JlZiAhPT0gcmVmKCdGaWxlVXBsb2FkJywgZXZlbnQuaWQpLl9fcmVmXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRWZXJzaW9uc1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHsgZmllbGROYW1lV2hpdGVsaXN0OiBbJ3BlbmRpbmdJbXBvcnRlZFZlcnNpb25zJ10gfVxyXG4gICAgICAgIClcclxuICAgICAgfSBlbHNlIGlmIChmYWlsdXJlKSB7XHJcbiAgICAgICAgLy8gUmVwb3J0IHcvIGRpYWxvZyB0byB1cGxvYWRlciB1c2VyXHJcbiAgICAgICAgaWYgKGV2ZW50LnZlcnNpb24udXNlcklkID09PSB1c2VySWQudmFsdWUpIHtcclxuICAgICAgICAgIGFkZEZhaWxlZEpvYihjb252ZXJ0VXBsb2FkVG9GYWlsZWRKb2IoZXZlbnQudmVyc2lvbikpXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSlcclxuXHJcbiAgb25Qcm9qZWN0UGVuZGluZ1ZlcnNpb25zVXBkYXRlKChyZXMpID0+IHtcclxuICAgIGlmICghcmVzLmRhdGE/LnByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkLmlkKSByZXR1cm5cclxuXHJcbiAgICBjb25zdCBldmVudCA9IHJlcy5kYXRhLnByb2plY3RQZW5kaW5nVmVyc2lvbnNVcGRhdGVkXHJcbiAgICBoYW5kbGVyPy4oZXZlbnQsIGFwb2xsby5jYWNoZSlcclxuICB9KVxyXG59XHJcbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9saWIvcHJvamVjdHMvY29tcG9zYWJsZXMvdmVyc2lvbk1hbmFnZW1lbnQudHMifQ== |