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(' '), (_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==