Files
speckle-server/scratch/edge-debug-selection/Default/Cache/Cache_Data/f_000135
T

464 lines
46 KiB
Plaintext

import { createHotContext as __vite__createHotContext } from "/_nuxt/@vite/client";import.meta.hot = __vite__createHotContext("/components/viewer/AnchoredPoints.vue");import { default as __nuxt_component_0 } from "/_nuxt/components/viewer/anchored-point/NewThread.vue";
import { default as __nuxt_component_1 } from "/_nuxt/components/viewer/anchored-point/Thread.vue";
import { default as __nuxt_component_2 } from "/_nuxt/components/viewer/contextMenu/ContextMenu.vue";
import { default as __nuxt_component_3 } from "/_nuxt/components/viewer/anchored-point/User.vue";
import { default as __nuxt_component_4 } from "/_nuxt/components/auth/LoginPanel.vue";
import { UserAvatar as __nuxt_component_5 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js";
import { default as __nuxt_component_6 } from "/_nuxt/components/viewer/Scope.vue";
import { FormButton as __nuxt_component_7 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js";
import { default as __nuxt_component_8 } from "/_nuxt/components/viewer/GlobalFilterReset.vue";
import { default as __nuxt_component_9 } from "/_nuxt/components/viewer/GlobalIsolationHiddenReset.vue";
/* Injection by vite-plugin-vue-inspector Start */
import { createBlock as __createBlock,createElementBlock as __createElementBlock,createVNode as __createVNode,createElementVNode as __createElementVNode } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"
function _interopVNode(vnode) {
if (vnode && vnode.props && 'data-v-inspector' in vnode.props) {
const data = vnode.props['data-v-inspector']
delete vnode.props['data-v-inspector']
Object.defineProperty(vnode.props, '__v_inspector', { value: data, enumerable: false })
}
return vnode
}
function _createBlock(...args) { return _interopVNode(__createBlock(...args)) }
function _createElementBlock(...args) { return _interopVNode(__createElementBlock(...args)) }
function _createVNode(...args) { return _interopVNode(__createVNode(...args)) }
function _createElementVNode(...args) { return _interopVNode(__createElementVNode(...args)) }
/* Injection by vite-plugin-vue-inspector End */
import { defineComponent as _defineComponent } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
import { useEmbed } from "/_nuxt/lib/viewer/composables/setup/embed.ts";
import { useActiveUser } from "/_nuxt/lib/auth/composables/activeUser.ts";
import { useMixpanel } from "/_nuxt/lib/core/composables/mp.ts";
import { useViewerUserActivityTracking } from "/_nuxt/lib/viewer/composables/activity.ts";
import {
useViewerCommentBubblesProjection,
useViewerNewThreadBubble
} from "/_nuxt/lib/viewer/composables/commentBubbles.ts";
import { useCheckViewerCommentingAccess } from "/_nuxt/lib/viewer/composables/commentManagement.ts";
import {
useInjectedViewerInterfaceState,
useInjectedViewerState
} from "/_nuxt/lib/viewer/composables/setup.ts";
import { useThreadUtilities } from "/_nuxt/lib/viewer/composables/ui.ts";
import { useFilterUtilities } from "/_nuxt/lib/viewer/composables/filtering/filtering.ts";
import { TailwindBreakpoints } from "/_nuxt/lib/common/helpers/tailwind.ts";
import { useBreakpoints } from "/_nuxt/node_modules/@vueuse/core/index.mjs?v=e4f18c29";
import { ref, computed, watch } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
const _sfc_main = /* @__PURE__ */ _defineComponent({
__name: "ViewerAnchoredPoints",
emits: ["forceClosePanels"],
setup(__props, { expose: __expose, emit: __emit }) {
const emit = __emit;
const parentEl = ref(null);
const { isLoggedIn } = useActiveUser();
const viewerState = useInjectedViewerState();
const { sessionId } = viewerState;
const { users } = useViewerUserActivityTracking({ anchoredPointsParentEl: parentEl });
const { isOpenThread, open, closeAllThreads } = useThreadUtilities();
const {
filters: { hasAnyFiltersApplied },
hasAnyIsolationsApplied,
hasAnyHiddenApplied
} = useFilterUtilities({ state: viewerState });
const canPostComment = useCheckViewerCommentingAccess();
const breakpoints = useBreakpoints(TailwindBreakpoints);
const isMobile = breakpoints.smaller("sm");
const { isEnabled: isEmbedEnabled } = useEmbed();
const followers = computed(() => {
if (!isLoggedIn.value) return [];
const res = [];
Object.values(users.value).forEach((model) => {
if (model.state.ui.spotlightUserSessionId === sessionId.value)
res.push(model.user);
});
return res;
});
const {
spotlightUserSessionId,
threads: {
openThread: { thread: openThread },
items: commentThreads,
hideBubbles
}
} = useInjectedViewerInterfaceState();
const showLoginDialog = ref(false);
const contextMenuOpen = ref(false);
useViewerCommentBubblesProjection({ parentEl });
const { buttonState, closeNewThread } = useViewerNewThreadBubble({
parentEl
});
const state = useInjectedViewerState();
const onThreadUpdate = (thread) => {
commentThreads.value = {
...commentThreads.value,
[thread.id]: thread
};
};
const onThreadExpandedChange = (isExpanded) => {
if (isExpanded) {
closeNewThread();
contextMenuOpen.value = false;
}
};
const shouldShowNewThread = computed(
() => !isEmbedEnabled.value && !state.ui.measurement.enabled.value && canPostComment.value
);
const allThreadsChronologicalOrder = computed(() => {
const vals = Object.values(commentThreads.value);
return vals.sort(
(a, b) => new Date(b.createdAt).getUTCDate() - new Date(a.createdAt).getUTCDate()
);
});
const openNextThread = (currentThread) => {
const threadCount = allThreadsChronologicalOrder.value.length;
let currentThreadIndex = allThreadsChronologicalOrder.value.findIndex(
(t) => currentThread.id === t.id
);
if (++currentThreadIndex > threadCount - 1) currentThreadIndex = 0;
const nextThread = allThreadsChronologicalOrder.value[currentThreadIndex];
if (!nextThread) return;
open(nextThread.id);
};
const openPrevThread = (currentThread) => {
const threadCount = allThreadsChronologicalOrder.value.length;
let currentThreadIndex = allThreadsChronologicalOrder.value.findIndex(
(t) => currentThread.id === t.id
);
if (--currentThreadIndex < 0) currentThreadIndex = threadCount - 1;
const nextThread = allThreadsChronologicalOrder.value[currentThreadIndex];
if (!nextThread) return;
open(nextThread.id);
};
const usersWithAvatars = computed(
() => Object.values(users.value).filter(
(u) => !!u.user
)
);
const visibleUsers = computed(
() => (
// Hide users who are following someone else
Object.values(users.value).filter((user) => !user.state.ui.spotlightUserSessionId)
)
);
const spotlightUser = computed(() => {
return Object.values(users.value).find(
(u) => u.sessionId === spotlightUserSessionId.value
);
});
const showFollowerMessage = computed(
() => !isEmbedEnabled.value && spotlightUserSessionId.value && spotlightUser.value || followers.value.length !== 0
);
const mp = useMixpanel();
function setUserSpotlight(sessionId2) {
if (spotlightUserSessionId.value === sessionId2) {
spotlightUserSessionId.value = null;
mp.track("Viewer Action", {
type: "action",
name: "spotlight-mode",
action: "stop",
source: "navbar"
});
return;
}
spotlightUserSessionId.value = sessionId2;
mp.track("Viewer Action", {
type: "action",
name: "spotlight-mode",
action: "start",
source: "navbar"
});
}
const forceCloseThreads = async () => {
await closeAllThreads();
};
watch(
() => openThread.value,
(newThread, oldThread) => {
if (newThread && !oldThread && isMobile.value) {
emit("forceClosePanels");
}
}
);
watch(
() => contextMenuOpen.value,
(isOpen) => {
if (isOpen) {
closeNewThread();
}
}
);
__expose({
forceCloseThreads
});
const __returned__ = { emit, parentEl, isLoggedIn, viewerState, sessionId, users, isOpenThread, open, closeAllThreads, hasAnyFiltersApplied, hasAnyIsolationsApplied, hasAnyHiddenApplied, canPostComment, breakpoints, isMobile, isEmbedEnabled, followers, spotlightUserSessionId, openThread, commentThreads, hideBubbles, showLoginDialog, contextMenuOpen, buttonState, closeNewThread, state, onThreadUpdate, onThreadExpandedChange, shouldShowNewThread, allThreadsChronologicalOrder, openNextThread, openPrevThread, usersWithAvatars, visibleUsers, spotlightUser, showFollowerMessage, mp, setUserSpotlight, forceCloseThreads };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
});
import { createCommentVNode as _createCommentVNode, resolveComponent as _resolveComponent, openBlock as _openBlock, renderList as _renderList, Fragment as _Fragment, vShow as _vShow, normalizeClass as _normalizeClass, withDirectives as _withDirectives, resolveDirective as _resolveDirective, withCtx as _withCtx, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
const _hoisted_1 = {
ref: "parentEl",
class: "absolute w-full h-full pointer-events-none overflow-hidden",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:2:3"
};
const _hoisted_2 = {
key: 1,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:39:5"
};
const _hoisted_3 = {
key: 0,
class: "scale-90 flex space-x-1 items-center",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:59:9"
};
const _hoisted_4 = ["onClick"];
const _hoisted_5 = {
class: "absolute top-0 left-0 w-full justify-center flex",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:91:7"
};
const _hoisted_6 = {
class: "pointer-events-auto bg-primary text-white text-xs px-3 h-8 flex items-center rounded-b-md cursor-default",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:92:9"
};
const _hoisted_7 = {
key: 0,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:95:11"
};
const _hoisted_8 = ["content"];
const _hoisted_9 = {
key: 0,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:112:13"
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_ViewerAnchoredPointNewThread = __nuxt_component_0;
const _component_ViewerAnchoredPointThread = __nuxt_component_1;
const _component_ViewerContextMenu = __nuxt_component_2;
const _component_ViewerAnchoredPointUser = __nuxt_component_3;
const _component_AuthLoginPanel = __nuxt_component_4;
const _component_UserAvatar = __nuxt_component_5;
const _component_ViewerScope = __nuxt_component_6;
const _component_Portal = _resolveComponent("Portal");
const _component_FormButton = __nuxt_component_7;
const _component_ViewerGlobalFilterReset = __nuxt_component_8;
const _component_ViewerGlobalIsolationHiddenReset = __nuxt_component_9;
const _directive_tippy = _resolveDirective("tippy");
return _openBlock(), _createElementBlock(
"div",
_hoisted_1,
[
_createCommentVNode(" Add new thread bubble "),
$setup.shouldShowNewThread ? (_openBlock(), _createBlock(_component_ViewerAnchoredPointNewThread, {
key: 0,
modelValue: $setup.buttonState,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.buttonState = $event),
"can-post-comment": $setup.canPostComment,
class: "z-[13]",
onClose: $setup.closeNewThread,
onLogin: _cache[1] || (_cache[1] = ($event) => $setup.showLoginDialog = true),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:7:5"
}, null, 8, ["modelValue", "can-post-comment", "onClose"])) : _createCommentVNode("v-if", true),
_createCommentVNode(" Comment bubbles "),
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList(Object.values($setup.commentThreads), (thread) => {
return _withDirectives((_openBlock(), _createBlock(_component_ViewerAnchoredPointThread, {
key: thread.id,
"model-value": thread,
class: _normalizeClass($setup.openThread?.id === thread.id ? "z-[12]" : "z-[11]"),
"has-previous": $setup.allThreadsChronologicalOrder.findIndex((t) => t.id === thread.id) > 0,
"has-next": $setup.allThreadsChronologicalOrder.findIndex((t) => t.id === thread.id) < $setup.allThreadsChronologicalOrder.length - 1,
"onUpdate:modelValue": $setup.onThreadUpdate,
"onUpdate:expanded": $setup.onThreadExpandedChange,
onNext: _cache[2] || (_cache[2] = (model) => $setup.openNextThread(model)),
onPrev: _cache[3] || (_cache[3] = (model) => $setup.openPrevThread(model)),
onLogin: _cache[4] || (_cache[4] = ($event) => $setup.showLoginDialog = true),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:17:5"
}, null, 8, ["model-value", "class", "has-previous", "has-next"])), [
[_vShow, !$setup.hideBubbles || $setup.isOpenThread(thread.id)]
]);
}),
128
/* KEYED_FRAGMENT */
)),
_createVNode(_component_ViewerContextMenu, {
open: $setup.contextMenuOpen,
"onUpdate:open": _cache[5] || (_cache[5] = ($event) => $setup.contextMenuOpen = $event),
"parent-el": $setup.parentEl,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:37:5"
}, null, 8, ["open", "parent-el"]),
!$setup.isEmbedEnabled ? (_openBlock(), _createElementBlock("div", _hoisted_2, [
_createCommentVNode(" Active users "),
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList($setup.visibleUsers, (user) => {
return _openBlock(), _createBlock(_component_ViewerAnchoredPointUser, {
key: user.state.sessionId,
user,
class: "z-[10]",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:41:7"
}, null, 8, ["user"]);
}),
128
/* KEYED_FRAGMENT */
))
])) : _createCommentVNode("v-if", true),
_createVNode(_component_AuthLoginPanel, {
open: $setup.showLoginDialog,
"onUpdate:open": _cache[6] || (_cache[6] = ($event) => $setup.showLoginDialog = $event),
"dialog-mode": "",
"max-width": "sm",
subtitle: "Join the conversation",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:49:5"
}, null, 8, ["open"]),
_createCommentVNode(" Active user avatars in navbar "),
_createVNode(_component_Portal, {
to: "secondary-actions",
"data-v-inspector": "components/viewer/AnchoredPoints.vue:57:5"
}, {
default: _withCtx(() => [
_createVNode(_component_ViewerScope, {
state: $setup.state,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:58:7"
}, {
default: _withCtx(() => [
$setup.usersWithAvatars.length > 0 ? (_openBlock(), _createElementBlock("div", _hoisted_3, [
_createCommentVNode(' <UserAvatarGroup :users="activeUserAvatars" :overlap="false" hover-effect /> '),
(_openBlock(true), _createElementBlock(
_Fragment,
null,
_renderList($setup.usersWithAvatars, (user) => {
return _openBlock(), _createElementBlock("button", {
key: user.id,
onClick: ($event) => $setup.setUserSpotlight(user.sessionId),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:65:13"
}, [
_withDirectives(_createVNode(_component_UserAvatar, {
user: user.user,
"hover-effect": "",
"hide-tooltip": "",
active: user.sessionId === $setup.spotlightUserSessionId,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:66:15"
}, null, 8, ["user", "active"]), [
[
_directive_tippy,
`${user.sessionId === $setup.spotlightUserSessionId ? "Stop following" : "Follow"} ${user.user.name}`
]
])
], 8, _hoisted_4);
}),
128
/* KEYED_FRAGMENT */
))
])) : _createCommentVNode("v-if", true)
]),
_: 1
/* STABLE */
}, 8, ["state"])
]),
_: 1
/* STABLE */
}),
_createCommentVNode(" Active user tracking cancel & Follower count display "),
$setup.showFollowerMessage ? (_openBlock(), _createElementBlock(
"div",
{
key: 2,
class: _normalizeClass(["absolute w-screen z-10 p-1 h-[calc(100dvh-3rem)]", $setup.isEmbedEnabled ? "" : "mt-[3rem]"]),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:86:5"
},
[
_createElementVNode("div", _hoisted_5, [
_createElementVNode("div", _hoisted_6, [
$setup.spotlightUserSessionId && $setup.spotlightUser ? (_openBlock(), _createElementBlock("div", _hoisted_7, [
_createTextVNode(
" Following " + _toDisplayString($setup.spotlightUser?.userName.split(" ")[0]) + " ",
1
/* TEXT */
),
_createVNode(_component_FormButton, {
color: "outline",
size: "sm",
class: "ml-1 -mr-1.5",
onClick: _cache[7] || (_cache[7] = () => $setup.spotlightUserSessionId = null),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:97:13"
}, {
default: _withCtx(() => [..._cache[8] || (_cache[8] = [
_createElementVNode(
"span",
{ "data-v-inspector": "components/viewer/AnchoredPoints.vue:103:15" },
"Stop",
-1
/* CACHED */
)
])]),
_: 1
/* STABLE */
})
])) : $setup.followers.length > 0 ? _withDirectives((_openBlock(), _createElementBlock("div", {
key: 1,
content: $setup.followers.map((u) => u.name).join(", "),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:106:11"
}, [
_createTextVNode(
" Followed by " + _toDisplayString($setup.followers[0].name.split(" ")[0]) + " ",
1
/* TEXT */
),
$setup.followers.length > 1 ? (_openBlock(), _createElementBlock(
"span",
_hoisted_9,
" & " + _toDisplayString($setup.followers.length - 1) + " " + _toDisplayString($setup.followers.length - 1 === 1 ? "other" : "others"),
1
/* TEXT */
)) : _createCommentVNode("v-if", true)
], 8, _hoisted_8)), [
[_directive_tippy, { placement: "bottom" }]
]) : _createCommentVNode("v-if", true)
])
])
],
2
/* CLASS */
)) : _createCommentVNode("v-if", true),
_createCommentVNode(" Shows up when filters are applied for an easy return to normality "),
_createElementVNode(
"div",
{
class: _normalizeClass(["z-20 absolute left-1/2 -translate-x-1/2", $setup.showFollowerMessage ? "top-24" : "top-14"]),
"data-v-inspector": "components/viewer/AnchoredPoints.vue:122:5"
},
[
$setup.hasAnyFiltersApplied ? (_openBlock(), _createBlock(_component_ViewerGlobalFilterReset, {
key: 0,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:126:7"
})) : $setup.hasAnyIsolationsApplied || $setup.hasAnyHiddenApplied ? (_openBlock(), _createBlock(_component_ViewerGlobalIsolationHiddenReset, {
key: 1,
"data-v-inspector": "components/viewer/AnchoredPoints.vue:127:7"
})) : _createCommentVNode("v-if", true)
],
2
/* CLASS */
)
],
512
/* NEED_PATCH */
);
}
_sfc_main.__hmrId = "fdb7c139";
typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main);
import.meta.hot.on("file-changed", ({ file }) => {
__VUE_HMR_RUNTIME__.CHANGED_FILE = file;
});
import.meta.hot.accept((mod) => {
if (!mod) return;
const { default: updated, _rerender_only } = mod;
if (_rerender_only) {
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render);
} else {
__VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated);
}
});
import _export_sfc from "/_nuxt/@id/__x00__plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "D:/speckle-server/packages/frontend-2/components/viewer/AnchoredPoints.vue"]]);
//# sourceMappingURL=data:application/json;base64,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QUFHLHNCQUFlLFNBQVMsTUFBSyxXQUFXO0FBQUEsa0JBQ3JEO0FBQUE7QUFBQTtBQUFBLDZCQU9hO0FBQUEsa0JBTlgsT0FBTTtBQUFBLGtCQUNOLE1BQUs7QUFBQSxrQkFDTCxPQUFNO0FBQUEsa0JBQ0wsU0FBSyxnQ0FBUyxnQ0FBc0I7QUFBQSxrQkFBVSxvQkFBaUI7QUFBQTtvQ0FFaEUsTUFBZ0Y7QUFBQSxvQkFBaEY7QUFBQSxzQkFBZ0Y7QUFBQSx3QkFBMUUsb0JBQWlCLDhDQUE2QztBQUFBLHNCQUFDO0FBQUEsc0JBQUk7QUFBQTtBQUFBO0FBQUE7Ozs7b0JBSWhFLGlCQUFVLFNBQU0sbUNBRDdCLG9CQVVNO0FBQUE7Z0JBUEgsU0FBUyxpQkFBVSxJQUFHLENBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFJO0FBQUEsZ0JBQVEsb0JBQWlCO0FBQUE7O2tCQUNyRSxrQkFDYSxpQkFBRyxpQkFBUyxHQUFJLEtBQUssTUFBSyxXQUFXO0FBQUEsa0JBQ2pEO0FBQUE7QUFBQTtBQUFBLGdCQUFZLGlCQUFVLFNBQU0sbUJBQTVCO0FBQUEsa0JBR087QUFBQSxrQkFIUDtBQUFBLGtCQUFpRyxRQUM3RixpQkFBRyxpQkFBVSxTQUFNLEtBQU8sTUFDNUIsaUJBQUcsaUJBQVUsU0FBTTtBQUFBO0FBQUE7QUFBQTs7bUNBTlosdUJBQXVCO0FBQUE7Ozs7Ozs7TUFheEM7QUFBQSxNQUNBO0FBQUEsUUFRTTtBQUFBO0FBQUEsVUFQSixPQUFLLGlCQUFDLDJDQUNFLDZCQUFtQjtBQUFBLFVBQXdCLG9CQUFpQjtBQUFBOztVQUVyQyw2Q0FBL0IsYUFBcUg7QUFBQTtZQUFoRSxvQkFBaUI7QUFBQSxnQkFFekQsa0NBQTJCLDRDQUR4QyxhQUVFO0FBQUE7WUFEMkQsb0JBQWlCO0FBQUEiLCJuYW1lcyI6WyJzZXNzaW9uSWQiXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsiQW5jaG9yZWRQb2ludHMudnVlIl0sInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICA8ZGl2XHJcbiAgICByZWY9XCJwYXJlbnRFbFwiXHJcbiAgICBjbGFzcz1cImFic29sdXRlIHctZnVsbCBoLWZ1bGwgcG9pbnRlci1ldmVudHMtbm9uZSBvdmVyZmxvdy1oaWRkZW5cIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjI6M1wiXHJcbiAgPlxyXG4gICAgPCEtLSBBZGQgbmV3IHRocmVhZCBidWJibGUgLS0+XHJcbiAgICA8Vmlld2VyQW5jaG9yZWRQb2ludE5ld1RocmVhZFxyXG4gICAgICB2LWlmPVwic2hvdWxkU2hvd05ld1RocmVhZFwiXHJcbiAgICAgIHYtbW9kZWw9XCJidXR0b25TdGF0ZVwiXHJcbiAgICAgIDpjYW4tcG9zdC1jb21tZW50PVwiY2FuUG9zdENvbW1lbnRcIlxyXG4gICAgICBjbGFzcz1cInotWzEzXVwiXHJcbiAgICAgIEBjbG9zZT1cImNsb3NlTmV3VGhyZWFkXCJcclxuICAgICAgQGxvZ2luPVwic2hvd0xvZ2luRGlhbG9nID0gdHJ1ZVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6Nzo1XCJcclxuICAgIC8+XHJcblxyXG4gICAgPCEtLSBDb21tZW50IGJ1YmJsZXMgLS0+XHJcbiAgICA8Vmlld2VyQW5jaG9yZWRQb2ludFRocmVhZFxyXG4gICAgICB2LWZvcj1cInRocmVhZCBpbiBPYmplY3QudmFsdWVzKGNvbW1lbnRUaHJlYWRzKVwiXHJcbiAgICAgIHYtc2hvdz1cIiFoaWRlQnViYmxlcyB8fCBpc09wZW5UaHJlYWQodGhyZWFkLmlkKVwiXHJcbiAgICAgIDprZXk9XCJ0aHJlYWQuaWRcIlxyXG4gICAgICA6bW9kZWwtdmFsdWU9XCJ0aHJlYWRcIlxyXG4gICAgICA6Y2xhc3M9XCJvcGVuVGhyZWFkPy5pZCA9PT0gdGhyZWFkLmlkID8gJ3otWzEyXScgOiAnei1bMTFdJ1wiXHJcbiAgICAgIDpoYXMtcHJldmlvdXM9XCJcclxuICAgICAgICBhbGxUaHJlYWRzQ2hyb25vbG9naWNhbE9yZGVyLmZpbmRJbmRleCgodCkgPT4gdC5pZCA9PT0gdGhyZWFkLmlkKSA+IDBcclxuICAgICAgXCJcclxuICAgICAgOmhhcy1uZXh0PVwiXHJcbiAgICAgICAgYWxsVGhyZWFkc0Nocm9ub2xvZ2ljYWxPcmRlci5maW5kSW5kZXgoKHQpID0+IHQuaWQgPT09IHRocmVhZC5pZCkgPFxyXG4gICAgICAgIGFsbFRocmVhZHNDaHJvbm9sb2dpY2FsT3JkZXIubGVuZ3RoIC0gMVxyXG4gICAgICBcIlxyXG4gICAgICBAdXBkYXRlOm1vZGVsLXZhbHVlPVwib25UaHJlYWRVcGRhdGVcIlxyXG4gICAgICBAdXBkYXRlOmV4cGFuZGVkPVwib25UaHJlYWRFeHBhbmRlZENoYW5nZVwiXHJcbiAgICAgIEBuZXh0PVwiKG1vZGVsKSA9PiBvcGVuTmV4dFRocmVhZChtb2RlbClcIlxyXG4gICAgICBAcHJldj1cIihtb2RlbCkgPT4gb3BlblByZXZUaHJlYWQobW9kZWwpXCJcclxuICAgICAgQGxvZ2luPVwic2hvd0xvZ2luRGlhbG9nID0gdHJ1ZVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6MTc6NVwiXHJcbiAgICAvPlxyXG5cclxuICAgIDxWaWV3ZXJDb250ZXh0TWVudSB2LW1vZGVsOm9wZW49XCJjb250ZXh0TWVudU9wZW5cIiA6cGFyZW50LWVsPVwicGFyZW50RWxcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjM3OjVcIiAvPlxyXG5cclxuICAgIDxkaXYgdi1pZj1cIiFpc0VtYmVkRW5hYmxlZFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6Mzk6NVwiPlxyXG4gICAgICA8IS0tIEFjdGl2ZSB1c2VycyAtLT5cclxuICAgICAgPFZpZXdlckFuY2hvcmVkUG9pbnRVc2VyXHJcbiAgICAgICAgdi1mb3I9XCJ1c2VyIGluIHZpc2libGVVc2Vyc1wiXHJcbiAgICAgICAgOmtleT1cInVzZXIuc3RhdGUuc2Vzc2lvbklkXCJcclxuICAgICAgICA6dXNlcj1cInVzZXJcIlxyXG4gICAgICAgIGNsYXNzPVwiei1bMTBdXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZTo0MTo3XCJcclxuICAgICAgLz5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxBdXRoTG9naW5QYW5lbFxyXG4gICAgICB2LW1vZGVsOm9wZW49XCJzaG93TG9naW5EaWFsb2dcIlxyXG4gICAgICBkaWFsb2ctbW9kZVxyXG4gICAgICBtYXgtd2lkdGg9XCJzbVwiXHJcbiAgICAgIHN1YnRpdGxlPVwiSm9pbiB0aGUgY29udmVyc2F0aW9uXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZTo0OTo1XCJcclxuICAgIC8+XHJcblxyXG4gICAgPCEtLSBBY3RpdmUgdXNlciBhdmF0YXJzIGluIG5hdmJhciAtLT5cclxuICAgIDxQb3J0YWwgdG89XCJzZWNvbmRhcnktYWN0aW9uc1wiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6NTc6NVwiPlxyXG4gICAgICA8Vmlld2VyU2NvcGUgOnN0YXRlPVwic3RhdGVcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjU4OjdcIj5cclxuICAgICAgICA8ZGl2XHJcbiAgICAgICAgICB2LWlmPVwidXNlcnNXaXRoQXZhdGFycy5sZW5ndGggPiAwXCJcclxuICAgICAgICAgIGNsYXNzPVwic2NhbGUtOTAgZmxleCBzcGFjZS14LTEgaXRlbXMtY2VudGVyXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZTo1OTo5XCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8IS0tIDxVc2VyQXZhdGFyR3JvdXAgOnVzZXJzPVwiYWN0aXZlVXNlckF2YXRhcnNcIiA6b3ZlcmxhcD1cImZhbHNlXCIgaG92ZXItZWZmZWN0IC8+IC0tPlxyXG4gICAgICAgICAgPHRlbXBsYXRlIHYtZm9yPVwidXNlciBpbiB1c2Vyc1dpdGhBdmF0YXJzXCIgOmtleT1cInVzZXIuaWRcIj5cclxuICAgICAgICAgICAgPGJ1dHRvbiBAY2xpY2s9XCJzZXRVc2VyU3BvdGxpZ2h0KHVzZXIuc2Vzc2lvbklkKVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6NjU6MTNcIj5cclxuICAgICAgICAgICAgICA8VXNlckF2YXRhclxyXG4gICAgICAgICAgICAgICAgdi10aXBweT1cIlxyXG4gICAgICAgICAgICAgICAgICBgJHtcclxuICAgICAgICAgICAgICAgICAgICB1c2VyLnNlc3Npb25JZCA9PT0gc3BvdGxpZ2h0VXNlclNlc3Npb25JZFxyXG4gICAgICAgICAgICAgICAgICAgICAgPyAnU3RvcCBmb2xsb3dpbmcnXHJcbiAgICAgICAgICAgICAgICAgICAgICA6ICdGb2xsb3cnXHJcbiAgICAgICAgICAgICAgICAgIH0gJHt1c2VyLnVzZXIubmFtZX1gXHJcbiAgICAgICAgICAgICAgICBcIlxyXG4gICAgICAgICAgICAgICAgOnVzZXI9XCJ1c2VyLnVzZXJcIlxyXG4gICAgICAgICAgICAgICAgaG92ZXItZWZmZWN0XHJcbiAgICAgICAgICAgICAgICBoaWRlLXRvb2x0aXBcclxuICAgICAgICAgICAgICAgIDphY3RpdmU9XCJ1c2VyLnNlc3Npb25JZCA9PT0gc3BvdGxpZ2h0VXNlclNlc3Npb25JZFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6NjY6MTVcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPC90ZW1wbGF0ZT5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9WaWV3ZXJTY29wZT5cclxuICAgIDwvUG9ydGFsPlxyXG5cclxuICAgIDwhLS0gQWN0aXZlIHVzZXIgdHJhY2tpbmcgY2FuY2VsICYgRm9sbG93ZXIgY291bnQgZGlzcGxheSAtLT5cclxuICAgIDxkaXZcclxuICAgICAgdi1pZj1cInNob3dGb2xsb3dlck1lc3NhZ2VcIlxyXG4gICAgICBjbGFzcz1cImFic29sdXRlIHctc2NyZWVuIHotMTAgcC0xIGgtW2NhbGMoMTAwZHZoLTNyZW0pXVwiXHJcbiAgICAgIDpjbGFzcz1cImlzRW1iZWRFbmFibGVkID8gJycgOiAnbXQtWzNyZW1dJ1wiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6ODY6NVwiXHJcbiAgICA+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJhYnNvbHV0ZSB0b3AtMCBsZWZ0LTAgdy1mdWxsIGp1c3RpZnktY2VudGVyIGZsZXhcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjkxOjdcIj5cclxuICAgICAgICA8ZGl2XHJcbiAgICAgICAgICBjbGFzcz1cInBvaW50ZXItZXZlbnRzLWF1dG8gYmctcHJpbWFyeSB0ZXh0LXdoaXRlIHRleHQteHMgcHgtMyBoLTggZmxleCBpdGVtcy1jZW50ZXIgcm91bmRlZC1iLW1kIGN1cnNvci1kZWZhdWx0XCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZTo5Mjo5XCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8ZGl2IHYtaWY9XCJzcG90bGlnaHRVc2VyU2Vzc2lvbklkICYmIHNwb3RsaWdodFVzZXJcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjk1OjExXCI+XHJcbiAgICAgICAgICAgIEZvbGxvd2luZyB7eyBzcG90bGlnaHRVc2VyPy51c2VyTmFtZS5zcGxpdCgnICcpWzBdIH19XHJcbiAgICAgICAgICAgIDxGb3JtQnV0dG9uXHJcbiAgICAgICAgICAgICAgY29sb3I9XCJvdXRsaW5lXCJcclxuICAgICAgICAgICAgICBzaXplPVwic21cIlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwibWwtMSAtbXItMS41XCJcclxuICAgICAgICAgICAgICBAY2xpY2s9XCIoKSA9PiAoc3BvdGxpZ2h0VXNlclNlc3Npb25JZCA9IG51bGwpXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZTo5NzoxM1wiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICA8c3BhbiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjEwMzoxNVwiPlN0b3A8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvRm9ybUJ1dHRvbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICB2LWVsc2UtaWY9XCJmb2xsb3dlcnMubGVuZ3RoID4gMFwiXHJcbiAgICAgICAgICAgIHYtdGlwcHk9XCJ7IHBsYWNlbWVudDogJ2JvdHRvbScgfVwiXHJcbiAgICAgICAgICAgIDpjb250ZW50PVwiZm9sbG93ZXJzLm1hcCgodSkgPT4gdS5uYW1lKS5qb2luKCcsICcpXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZToxMDY6MTFcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICBGb2xsb3dlZCBieSB7eyBmb2xsb3dlcnNbMF0ubmFtZS5zcGxpdCgnICcpWzBdIH19XHJcbiAgICAgICAgICAgIDxzcGFuIHYtaWY9XCJmb2xsb3dlcnMubGVuZ3RoID4gMVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6MTEyOjEzXCI+XHJcbiAgICAgICAgICAgICAgJiB7eyBmb2xsb3dlcnMubGVuZ3RoIC0gMSB9fVxyXG4gICAgICAgICAgICAgIHt7IGZvbGxvd2Vycy5sZW5ndGggLSAxID09PSAxID8gJ290aGVyJyA6ICdvdGhlcnMnIH19XHJcbiAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDwhLS0gU2hvd3MgdXAgd2hlbiBmaWx0ZXJzIGFyZSBhcHBsaWVkIGZvciBhbiBlYXN5IHJldHVybiB0byBub3JtYWxpdHkgLS0+XHJcbiAgICA8ZGl2XHJcbiAgICAgIGNsYXNzPVwiei0yMCBhYnNvbHV0ZSBsZWZ0LTEvMiAtdHJhbnNsYXRlLXgtMS8yXCJcclxuICAgICAgOmNsYXNzPVwic2hvd0ZvbGxvd2VyTWVzc2FnZSA/ICd0b3AtMjQnIDogJ3RvcC0xNCdcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvQW5jaG9yZWRQb2ludHMudnVlOjEyMjo1XCJcclxuICAgID5cclxuICAgICAgPFZpZXdlckdsb2JhbEZpbHRlclJlc2V0IHYtaWY9XCJoYXNBbnlGaWx0ZXJzQXBwbGllZFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWU6MTI2OjdcIiAvPlxyXG4gICAgICA8Vmlld2VyR2xvYmFsSXNvbGF0aW9uSGlkZGVuUmVzZXRcclxuICAgICAgICB2LWVsc2UtaWY9XCJoYXNBbnlJc29sYXRpb25zQXBwbGllZCB8fCBoYXNBbnlIaWRkZW5BcHBsaWVkXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL0FuY2hvcmVkUG9pbnRzLnZ1ZToxMjc6N1wiXHJcbiAgICAgIC8+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC90ZW1wbGF0ZT5cclxuPHNjcmlwdCBzZXR1cCBsYW5nPVwidHNcIj5cclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gJ0BzcGVja2xlL3NoYXJlZCdcclxuaW1wb3J0IHsgdXNlRW1iZWQgfSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvc2V0dXAvZW1iZWQnXHJcbmltcG9ydCB7IHVzZUFjdGl2ZVVzZXIgfSBmcm9tICd+fi9saWIvYXV0aC9jb21wb3NhYmxlcy9hY3RpdmVVc2VyJ1xyXG5pbXBvcnQgdHlwZSB7IExpbWl0ZWRVc2VyIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcbmltcG9ydCB0eXBlIHsgU2V0RnVsbHlSZXF1aXJlZCB9IGZyb20gJ35+L2xpYi9jb21tb24vaGVscGVycy90eXBlJ1xyXG5pbXBvcnQgeyB1c2VNaXhwYW5lbCB9IGZyb20gJ35+L2xpYi9jb3JlL2NvbXBvc2FibGVzL21wJ1xyXG5pbXBvcnQgeyB1c2VWaWV3ZXJVc2VyQWN0aXZpdHlUcmFja2luZyB9IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvYWN0aXZpdHknXHJcbmltcG9ydCB7XHJcbiAgdXNlVmlld2VyQ29tbWVudEJ1YmJsZXNQcm9qZWN0aW9uLFxyXG4gIHVzZVZpZXdlck5ld1RocmVhZEJ1YmJsZVxyXG59IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvY29tbWVudEJ1YmJsZXMnXHJcbmltcG9ydCB0eXBlIHsgQ29tbWVudEJ1YmJsZU1vZGVsIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9jb21tZW50QnViYmxlcydcclxuaW1wb3J0IHsgdXNlQ2hlY2tWaWV3ZXJDb21tZW50aW5nQWNjZXNzIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9jb21tZW50TWFuYWdlbWVudCdcclxuaW1wb3J0IHtcclxuICB1c2VJbmplY3RlZFZpZXdlckludGVyZmFjZVN0YXRlLFxyXG4gIHVzZUluamVjdGVkVmlld2VyU3RhdGVcclxufSBmcm9tICd+fi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3NldHVwJ1xyXG5pbXBvcnQgeyB1c2VUaHJlYWRVdGlsaXRpZXMgfSBmcm9tICd+fi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3VpJ1xyXG5pbXBvcnQgeyB1c2VGaWx0ZXJVdGlsaXRpZXMgfSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvZmlsdGVyaW5nL2ZpbHRlcmluZydcclxuaW1wb3J0IHsgVGFpbHdpbmRCcmVha3BvaW50cyB9IGZyb20gJ35+L2xpYi9jb21tb24vaGVscGVycy90YWlsd2luZCdcclxuaW1wb3J0IHsgdXNlQnJlYWtwb2ludHMgfSBmcm9tICdAdnVldXNlL2NvcmUnXHJcblxyXG5jb25zdCBlbWl0ID0gZGVmaW5lRW1pdHM8e1xyXG4gIGZvcmNlQ2xvc2VQYW5lbHM6IFtdXHJcbn0+KClcclxuXHJcbmNvbnN0IHBhcmVudEVsID0gcmVmKG51bGwgYXMgTnVsbGFibGU8SFRNTEVsZW1lbnQ+KVxyXG5jb25zdCB7IGlzTG9nZ2VkSW4gfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG5jb25zdCB2aWV3ZXJTdGF0ZSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG5jb25zdCB7IHNlc3Npb25JZCB9ID0gdmlld2VyU3RhdGVcclxuY29uc3QgeyB1c2VycyB9ID0gdXNlVmlld2VyVXNlckFjdGl2aXR5VHJhY2tpbmcoeyBhbmNob3JlZFBvaW50c1BhcmVudEVsOiBwYXJlbnRFbCB9KVxyXG5jb25zdCB7IGlzT3BlblRocmVhZCwgb3BlbiwgY2xvc2VBbGxUaHJlYWRzIH0gPSB1c2VUaHJlYWRVdGlsaXRpZXMoKVxyXG5jb25zdCB7XHJcbiAgZmlsdGVyczogeyBoYXNBbnlGaWx0ZXJzQXBwbGllZCB9LFxyXG4gIGhhc0FueUlzb2xhdGlvbnNBcHBsaWVkLFxyXG4gIGhhc0FueUhpZGRlbkFwcGxpZWRcclxufSA9IHVzZUZpbHRlclV0aWxpdGllcyh7IHN0YXRlOiB2aWV3ZXJTdGF0ZSB9KVxyXG5jb25zdCBjYW5Qb3N0Q29tbWVudCA9IHVzZUNoZWNrVmlld2VyQ29tbWVudGluZ0FjY2VzcygpXHJcbmNvbnN0IGJyZWFrcG9pbnRzID0gdXNlQnJlYWtwb2ludHMoVGFpbHdpbmRCcmVha3BvaW50cylcclxuY29uc3QgaXNNb2JpbGUgPSBicmVha3BvaW50cy5zbWFsbGVyKCdzbScpXHJcblxyXG5jb25zdCB7IGlzRW5hYmxlZDogaXNFbWJlZEVuYWJsZWQgfSA9IHVzZUVtYmVkKClcclxuXHJcbmNvbnN0IGZvbGxvd2VycyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICBpZiAoIWlzTG9nZ2VkSW4udmFsdWUpIHJldHVybiBbXVxyXG4gIGNvbnN0IHJlcyA9IFtdIGFzIExpbWl0ZWRVc2VyW11cclxuICBPYmplY3QudmFsdWVzKHVzZXJzLnZhbHVlKS5mb3JFYWNoKChtb2RlbCkgPT4ge1xyXG4gICAgaWYgKG1vZGVsLnN0YXRlLnVpLnNwb3RsaWdodFVzZXJTZXNzaW9uSWQgPT09IHNlc3Npb25JZC52YWx1ZSlcclxuICAgICAgcmVzLnB1c2gobW9kZWwudXNlciBhcyBMaW1pdGVkVXNlcilcclxuICB9KVxyXG4gIHJldHVybiByZXNcclxufSlcclxuXHJcbmNvbnN0IHtcclxuICBzcG90bGlnaHRVc2VyU2Vzc2lvbklkLFxyXG4gIHRocmVhZHM6IHtcclxuICAgIG9wZW5UaHJlYWQ6IHsgdGhyZWFkOiBvcGVuVGhyZWFkIH0sXHJcbiAgICBpdGVtczogY29tbWVudFRocmVhZHMsXHJcbiAgICBoaWRlQnViYmxlc1xyXG4gIH1cclxufSA9IHVzZUluamVjdGVkVmlld2VySW50ZXJmYWNlU3RhdGUoKVxyXG5cclxuY29uc3Qgc2hvd0xvZ2luRGlhbG9nID0gcmVmKGZhbHNlKVxyXG5jb25zdCBjb250ZXh0TWVudU9wZW4gPSByZWYoZmFsc2UpXHJcblxyXG51c2VWaWV3ZXJDb21tZW50QnViYmxlc1Byb2plY3Rpb24oeyBwYXJlbnRFbCB9KVxyXG5cclxuY29uc3QgeyBidXR0b25TdGF0ZSwgY2xvc2VOZXdUaHJlYWQgfSA9IHVzZVZpZXdlck5ld1RocmVhZEJ1YmJsZSh7XHJcbiAgcGFyZW50RWxcclxufSlcclxuXHJcbmNvbnN0IHN0YXRlID0gdXNlSW5qZWN0ZWRWaWV3ZXJTdGF0ZSgpXHJcblxyXG5jb25zdCBvblRocmVhZFVwZGF0ZSA9ICh0aHJlYWQ6IENvbW1lbnRCdWJibGVNb2RlbCkgPT4ge1xyXG4gIC8vIEJlaW5nIGNhcmVmdWwgbm90IHRvIG11dGF0ZSBvbGQgdmFsdWUgZGlyZWN0bHkgdG8gZW5zdXJlIHdhdGNoZXJzIHdvcmsgcHJvcGVybHlcclxuICBjb21tZW50VGhyZWFkcy52YWx1ZSA9IHtcclxuICAgIC4uLmNvbW1lbnRUaHJlYWRzLnZhbHVlLFxyXG4gICAgW3RocmVhZC5pZF06IHRocmVhZFxyXG4gIH1cclxufVxyXG5cclxuY29uc3Qgb25UaHJlYWRFeHBhbmRlZENoYW5nZSA9IChpc0V4cGFuZGVkOiBib29sZWFuKSA9PiB7XHJcbiAgaWYgKGlzRXhwYW5kZWQpIHtcclxuICAgIGNsb3NlTmV3VGhyZWFkKClcclxuICAgIGNvbnRleHRNZW51T3Blbi52YWx1ZSA9IGZhbHNlXHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBzaG91bGRTaG93TmV3VGhyZWFkID0gY29tcHV0ZWQoXHJcbiAgKCkgPT5cclxuICAgICFpc0VtYmVkRW5hYmxlZC52YWx1ZSAmJiAhc3RhdGUudWkubWVhc3VyZW1lbnQuZW5hYmxlZC52YWx1ZSAmJiBjYW5Qb3N0Q29tbWVudC52YWx1ZVxyXG4pXHJcblxyXG5jb25zdCBhbGxUaHJlYWRzQ2hyb25vbG9naWNhbE9yZGVyID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gIGNvbnN0IHZhbHMgPSBPYmplY3QudmFsdWVzKGNvbW1lbnRUaHJlYWRzLnZhbHVlKVxyXG4gIHJldHVybiB2YWxzLnNvcnQoXHJcbiAgICAoYSwgYikgPT4gbmV3IERhdGUoYi5jcmVhdGVkQXQpLmdldFVUQ0RhdGUoKSAtIG5ldyBEYXRlKGEuY3JlYXRlZEF0KS5nZXRVVENEYXRlKClcclxuICApXHJcbn0pXHJcblxyXG5jb25zdCBvcGVuTmV4dFRocmVhZCA9IChjdXJyZW50VGhyZWFkOiBDb21tZW50QnViYmxlTW9kZWwpID0+IHtcclxuICBjb25zdCB0aHJlYWRDb3VudCA9IGFsbFRocmVhZHNDaHJvbm9sb2dpY2FsT3JkZXIudmFsdWUubGVuZ3RoXHJcbiAgbGV0IGN1cnJlbnRUaHJlYWRJbmRleCA9IGFsbFRocmVhZHNDaHJvbm9sb2dpY2FsT3JkZXIudmFsdWUuZmluZEluZGV4KFxyXG4gICAgKHQpID0+IGN1cnJlbnRUaHJlYWQuaWQgPT09IHQuaWRcclxuICApXHJcbiAgaWYgKCsrY3VycmVudFRocmVhZEluZGV4ID4gdGhyZWFkQ291bnQgLSAxKSBjdXJyZW50VGhyZWFkSW5kZXggPSAwXHJcbiAgY29uc3QgbmV4dFRocmVhZCA9IGFsbFRocmVhZHNDaHJvbm9sb2dpY2FsT3JkZXIudmFsdWVbY3VycmVudFRocmVhZEluZGV4XVxyXG4gIGlmICghbmV4dFRocmVhZCkgcmV0dXJuXHJcblxyXG4gIG9wZW4obmV4dFRocmVhZC5pZClcclxufVxyXG5cclxuY29uc3Qgb3BlblByZXZUaHJlYWQgPSAoY3VycmVudFRocmVhZDogQ29tbWVudEJ1YmJsZU1vZGVsKSA9PiB7XHJcbiAgY29uc3QgdGhyZWFkQ291bnQgPSBhbGxUaHJlYWRzQ2hyb25vbG9naWNhbE9yZGVyLnZhbHVlLmxlbmd0aFxyXG4gIGxldCBjdXJyZW50VGhyZWFkSW5kZXggPSBhbGxUaHJlYWRzQ2hyb25vbG9naWNhbE9yZGVyLnZhbHVlLmZpbmRJbmRleChcclxuICAgICh0KSA9PiBjdXJyZW50VGhyZWFkLmlkID09PSB0LmlkXHJcbiAgKVxyXG4gIGlmICgtLWN1cnJlbnRUaHJlYWRJbmRleCA8IDApIGN1cnJlbnRUaHJlYWRJbmRleCA9IHRocmVhZENvdW50IC0gMVxyXG4gIGNvbnN0IG5leHRUaHJlYWQgPSBhbGxUaHJlYWRzQ2hyb25vbG9naWNhbE9yZGVyLnZhbHVlW2N1cnJlbnRUaHJlYWRJbmRleF1cclxuICBpZiAoIW5leHRUaHJlYWQpIHJldHVyblxyXG5cclxuICBvcGVuKG5leHRUaHJlYWQuaWQpXHJcbn1cclxuXHJcbmNvbnN0IHVzZXJzV2l0aEF2YXRhcnMgPSBjb21wdXRlZCgoKSA9PlxyXG4gIE9iamVjdC52YWx1ZXModXNlcnMudmFsdWUpLmZpbHRlcihcclxuICAgICh1KTogdSBpcyBTZXRGdWxseVJlcXVpcmVkPHR5cGVvZiB1LCAndXNlcic+ID0+ICEhdS51c2VyXHJcbiAgKVxyXG4pXHJcblxyXG5jb25zdCB2aXNpYmxlVXNlcnMgPSBjb21wdXRlZCgoKSA9PlxyXG4gIC8vIEhpZGUgdXNlcnMgd2hvIGFyZSBmb2xsb3dpbmcgc29tZW9uZSBlbHNlXHJcbiAgT2JqZWN0LnZhbHVlcyh1c2Vycy52YWx1ZSkuZmlsdGVyKCh1c2VyKSA9PiAhdXNlci5zdGF0ZS51aS5zcG90bGlnaHRVc2VyU2Vzc2lvbklkKVxyXG4pXHJcblxyXG5jb25zdCBzcG90bGlnaHRVc2VyID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gIHJldHVybiBPYmplY3QudmFsdWVzKHVzZXJzLnZhbHVlKS5maW5kKFxyXG4gICAgKHUpID0+IHUuc2Vzc2lvbklkID09PSBzcG90bGlnaHRVc2VyU2Vzc2lvbklkLnZhbHVlXHJcbiAgKVxyXG59KVxyXG5cclxuY29uc3Qgc2hvd0ZvbGxvd2VyTWVzc2FnZSA9IGNvbXB1dGVkKFxyXG4gICgpID0+XHJcbiAgICAoIWlzRW1iZWRFbmFibGVkLnZhbHVlICYmIHNwb3RsaWdodFVzZXJTZXNzaW9uSWQudmFsdWUgJiYgc3BvdGxpZ2h0VXNlci52YWx1ZSkgfHxcclxuICAgIGZvbGxvd2Vycy52YWx1ZS5sZW5ndGggIT09IDBcclxuKVxyXG5cclxuY29uc3QgbXAgPSB1c2VNaXhwYW5lbCgpXHJcbmZ1bmN0aW9uIHNldFVzZXJTcG90bGlnaHQoc2Vzc2lvbklkOiBzdHJpbmcpIHtcclxuICBpZiAoc3BvdGxpZ2h0VXNlclNlc3Npb25JZC52YWx1ZSA9PT0gc2Vzc2lvbklkKSB7XHJcbiAgICBzcG90bGlnaHRVc2VyU2Vzc2lvbklkLnZhbHVlID0gbnVsbFxyXG4gICAgbXAudHJhY2soJ1ZpZXdlciBBY3Rpb24nLCB7XHJcbiAgICAgIHR5cGU6ICdhY3Rpb24nLFxyXG4gICAgICBuYW1lOiAnc3BvdGxpZ2h0LW1vZGUnLFxyXG4gICAgICBhY3Rpb246ICdzdG9wJyxcclxuICAgICAgc291cmNlOiAnbmF2YmFyJ1xyXG4gICAgfSlcclxuICAgIHJldHVyblxyXG4gIH1cclxuXHJcbiAgc3BvdGxpZ2h0VXNlclNlc3Npb25JZC52YWx1ZSA9IHNlc3Npb25JZFxyXG4gIG1wLnRyYWNrKCdWaWV3ZXIgQWN0aW9uJywge1xyXG4gICAgdHlwZTogJ2FjdGlvbicsXHJcbiAgICBuYW1lOiAnc3BvdGxpZ2h0LW1vZGUnLFxyXG4gICAgYWN0aW9uOiAnc3RhcnQnLFxyXG4gICAgc291cmNlOiAnbmF2YmFyJ1xyXG4gIH0pXHJcbn1cclxuXHJcbmNvbnN0IGZvcmNlQ2xvc2VUaHJlYWRzID0gYXN5bmMgKCkgPT4ge1xyXG4gIGF3YWl0IGNsb3NlQWxsVGhyZWFkcygpXHJcbn1cclxuXHJcbi8vIFdhdGNoIGZvciB0aHJlYWQgb3BlbmluZyBvbiBtb2JpbGUgYW5kIGVtaXQgZXZlbnRcclxud2F0Y2goXHJcbiAgKCkgPT4gb3BlblRocmVhZC52YWx1ZSxcclxuICAobmV3VGhyZWFkLCBvbGRUaHJlYWQpID0+IHtcclxuICAgIC8vIElmIGEgdGhyZWFkIG9wZW5lZCAod2Fzbid0IG9wZW4gYmVmb3JlKSBvbiBtb2JpbGUsIGVtaXQgZXZlbnRcclxuICAgIGlmIChuZXdUaHJlYWQgJiYgIW9sZFRocmVhZCAmJiBpc01vYmlsZS52YWx1ZSkge1xyXG4gICAgICBlbWl0KCdmb3JjZUNsb3NlUGFuZWxzJylcclxuICAgIH1cclxuICB9XHJcbilcclxuXHJcbndhdGNoKFxyXG4gICgpID0+IGNvbnRleHRNZW51T3Blbi52YWx1ZSxcclxuICAoaXNPcGVuKSA9PiB7XHJcbiAgICBpZiAoaXNPcGVuKSB7XHJcbiAgICAgIGNsb3NlTmV3VGhyZWFkKClcclxuICAgIH1cclxuICB9XHJcbilcclxuXHJcbmRlZmluZUV4cG9zZSh7XHJcbiAgZm9yY2VDbG9zZVRocmVhZHNcclxufSlcclxuPC9zY3JpcHQ+XHJcbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9jb21wb25lbnRzL3ZpZXdlci9BbmNob3JlZFBvaW50cy52dWUifQ==