import { createHotContext as __vite__createHotContext } from "/_nuxt/@vite/client";import.meta.hot = __vite__createHotContext("/components/viewer/models/Panel.vue");import { default as __nuxt_component_0 } from "/_nuxt/components/viewer/compare-changes/Panel.vue"; import { default as __nuxt_component_1 } from "/_nuxt/components/viewer/models/versions/Versions.vue"; import { default as __nuxt_component_2 } from "/_nuxt/components/viewer/models/Actions.vue"; import { default as __nuxt_component_3 } from "/_nuxt/components/viewer/models/Card.vue"; import { default as __nuxt_component_4 } from "/_nuxt/components/viewer/models/DetachedObjectHeader.vue"; import { default as __nuxt_component_5 } from "/_nuxt/components/viewer/models/VirtualTreeItem.vue"; import { CommonLoadingIcon as __nuxt_component_6 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js"; import { default as __nuxt_component_7 } from "/_nuxt/components/global/illustration/emptystate/Models.vue"; import { FormButton as __nuxt_component_8 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js"; import { default as __nuxt_component_9 } from "/_nuxt/components/viewer/layout/SidePanel.vue"; import { default as __nuxt_component_10 } from "/_nuxt/components/viewer/models/add/Dialog.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 { useModel as _useModel, defineComponent as _defineComponent } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; import { useInjectedViewerLoadedResources, useInjectedViewer, useInjectedViewerState } from "/_nuxt/lib/viewer/composables/setup.ts"; import { ModelsSubView } from "/_nuxt/lib/viewer/helpers/sceneExplorer.ts"; import { useDiffUtilities, useSelectionUtilities } from "/_nuxt/lib/viewer/composables/ui.ts"; import { useTreeManagement } from "/_nuxt/lib/viewer/composables/tree.ts"; import { useVirtualList, useDebounceFn, useThrottleFn } from "/_nuxt/node_modules/@vueuse/core/index.mjs?v=e4f18c29"; import { ref, computed, nextTick, watch } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; const _sfc_main = /* @__PURE__ */ _defineComponent({ __name: "ViewerModelsPanel", props: { "subView": { type: String, ...{ default: ModelsSubView.Main } }, "subViewModifiers": {} }, emits: ["update:subView"], setup(__props, { expose: __expose }) { __expose(); const subView = _useModel(__props, "subView"); const expandedModelId = ref(null); const showAddModel = ref(false); const expandedNodes = ref(/* @__PURE__ */ new Set()); const expandedModels = ref(/* @__PURE__ */ new Set()); const disableScrollOnNextSelection = ref(false); const stickyHeader = ref(null); const scrollTop = ref(0); const { resourceItems, modelsAndVersionIds, objects, resourcesLoading } = useInjectedViewerLoadedResources(); const { metadata: { worldTree } } = useInjectedViewer(); const { resources: { response: { resourceItems: stateResourceItems } }, ui: { diff: diffState } } = useInjectedViewerState(); const { objects: selectedObjects, addToSelection, clearSelection, removeFromSelection } = useSelectionUtilities(); const { diffModelVersions, endDiff } = useDiffUtilities(); const { flattenModelTree, getRootNodesForModel, findObjectInNodes, expandNodesToShowObject, treeStateManager } = useTreeManagement(); const hasObjects = computed(() => objects.value.length > 0); const unifiedVirtualItems = computed(() => { return treeStateManager.getUnifiedVirtualItems( modelsAndVersionIds.value, expandedModels.value, expandedNodes.value, selectedObjects.value, worldTree.value || null, stateResourceItems.value, objects.value, getRootNodesForModel, flattenModelTree ); }); const { list: virtualList, containerProps, wrapperProps } = useVirtualList(unifiedVirtualItems, { itemHeight: (index) => { const item = unifiedVirtualItems.value[index]; return item?.type === "model-header" || item?.type === "detached-object-header" ? 64 : 40; }, overscan: 20 }); const modelHeaderPositions = computed(() => { const headers = []; let cumulativeHeight = 0; for (let i = 0; i < unifiedVirtualItems.value.length; i++) { const item = unifiedVirtualItems.value[i]; const itemHeight = item.type === "model-header" || item.type === "detached-object-header" ? 64 : 40; if (item.type === "model-header") { const data = item.data; headers.push({ index: i, model: data.model, versionId: data.versionId, position: cumulativeHeight }); } else if (item.type === "detached-object-header") { const data = item.data; const detachedObjectHeader = { id: data.objectId, name: "Detached Object", displayName: "Detached Object" }; headers.push({ index: i, model: detachedObjectHeader, versionId: data.objectId, position: cumulativeHeight }); } cumulativeHeight += itemHeight; } return headers; }); const hasDiffActive = computed(() => { return !!(diffState.oldVersion.value && diffState.newVersion.value); }); const isDetachedObjectSticky = computed(() => { if (!stickyHeader.value) return false; return objects.value.some((obj) => obj.objectId === stickyHeader.value?.model.id); }); const handleShowVersions = (modelId) => { expandedModelId.value = modelId; subView.value = ModelsSubView.Versions; }; const handleShowDiff = async (modelId, versionA, versionB) => { await diffModelVersions(modelId, versionA, versionB); expandedModelId.value = modelId; subView.value = ModelsSubView.Diff; }; const handleVersionsClose = () => { subView.value = ModelsSubView.Main; expandedModelId.value = null; }; const handleDiffClose = async () => { await endDiff(); subView.value = ModelsSubView.Versions; }; const toggleModelExpansion = (modelId) => { if (expandedModels.value.has(modelId)) { expandedModels.value.delete(modelId); } else { expandedModels.value.add(modelId); } }; const toggleTreeItemExpansion = (itemId) => { if (expandedNodes.value.has(itemId)) { expandedNodes.value.delete(itemId); } else { expandedNodes.value.add(itemId); } }; const handleItemClick = (item, event) => { if (item.type !== "tree-item") return; const node = item.data; const speckleData = node.raw; if (!speckleData?.id) return; const isCurrentlySelected = selectedObjects.value.find((o) => o.id === speckleData.id); if (isCurrentlySelected && !event.shiftKey) { if (item.hasChildren && !item.isExpanded) { toggleTreeItemExpansion(item.id); } return; } if (isCurrentlySelected && event.shiftKey) { disableScrollOnNextSelection.value = true; removeFromSelection(speckleData); return; } disableScrollOnNextSelection.value = true; if (!event.shiftKey) clearSelection(); addToSelection(speckleData); if (item.hasChildren && !item.isExpanded) { toggleTreeItemExpansion(item.id); } }; const getModelFromItem = (item) => { if (item.type === "model-header") { return item.data.model; } return {}; }; const getVersionIdFromItem = (item) => { if (item.type === "model-header") { return item.data.versionId; } return ""; }; const getObjectIdFromItem = (item) => { if (item.type === "detached-object-header") { return item.data.objectId; } return ""; }; const scrollToSelectedItem = (objectId) => { nextTick(() => { const itemIndex = unifiedVirtualItems.value.findIndex( (item) => item.type === "tree-item" && item.data.raw?.id === objectId ); if (itemIndex !== -1) { const container = containerProps.ref.value; if (container) { const containerHeight = container.clientHeight; const itemHeight = 40; const totalOffset = itemIndex * itemHeight; const centerOffset = containerHeight / 2 - itemHeight / 2; const scrollPosition = Math.max(0, totalOffset - centerOffset); container.scrollTo({ top: scrollPosition }); } } }); }; const handleSelectionChange = useDebounceFn( (newSelection) => { if (newSelection.length > 0 && !disableScrollOnNextSelection.value) { for (const selectedObj of newSelection) { for (const { model } of modelsAndVersionIds.value) { const modelRootNodes = getRootNodesForModel( model.id, worldTree.value || null, stateResourceItems.value, modelsAndVersionIds.value ); const containsObject = findObjectInNodes(modelRootNodes, selectedObj.id); if (containsObject) { expandedModels.value.add(model.id); const result = expandNodesToShowObject( modelRootNodes, selectedObj.id, model.id, expandedNodes.value ); if (result.found && result.nodesToExpand.length > 0) { result.nodesToExpand.forEach((nodeId) => expandedNodes.value.add(nodeId)); } scrollToSelectedItem(selectedObj.id); break; } } break; } } disableScrollOnNextSelection.value = false; }, 100 ); const handleScroll = useThrottleFn((e) => { const container = e.target; if (!container) return; scrollTop.value = container.scrollTop; const modelHeaders = modelHeaderPositions.value; if (modelHeaders.length === 0) return; let currentHeaderIndex = 0; for (let i = modelHeaders.length - 1; i >= 0; i--) { if (modelHeaders[i].position <= scrollTop.value) { currentHeaderIndex = i; break; } } const currentHeader = modelHeaders[currentHeaderIndex]; if (currentHeader) { stickyHeader.value = { model: currentHeader.model, versionId: currentHeader.versionId }; } }, 16); watch(selectedObjects, handleSelectionChange, { deep: true }); watch(subView, (newSubView) => { if (newSubView === ModelsSubView.Main) { expandedModelId.value = null; } }); watch(hasDiffActive, (isActive) => { if (isActive && subView.value !== ModelsSubView.Diff) { subView.value = ModelsSubView.Diff; } }); watch( unifiedVirtualItems, (items) => { if (items.length > 0) { const firstHeader = items.find( (item) => item.type === "model-header" || item.type === "detached-object-header" ); if (firstHeader) { if (firstHeader.type === "model-header") { const data = firstHeader.data; stickyHeader.value = { model: data.model, versionId: data.versionId }; } else if (firstHeader.type === "detached-object-header") { const data = firstHeader.data; const detachedObjectHeader = { id: data.objectId, name: "Detached Object", displayName: "Detached Object" }; stickyHeader.value = { model: detachedObjectHeader, versionId: data.objectId }; } } } else { stickyHeader.value = null; } }, { immediate: true } ); const __returned__ = { subView, expandedModelId, showAddModel, expandedNodes, expandedModels, disableScrollOnNextSelection, stickyHeader, scrollTop, resourceItems, modelsAndVersionIds, objects, resourcesLoading, worldTree, stateResourceItems, diffState, selectedObjects, addToSelection, clearSelection, removeFromSelection, diffModelVersions, endDiff, flattenModelTree, getRootNodesForModel, findObjectInNodes, expandNodesToShowObject, treeStateManager, hasObjects, unifiedVirtualItems, virtualList, containerProps, wrapperProps, modelHeaderPositions, hasDiffActive, isDetachedObjectSticky, handleShowVersions, handleShowDiff, handleVersionsClose, handleDiffClose, toggleModelExpansion, toggleTreeItemExpansion, handleItemClick, getModelFromItem, getVersionIdFromItem, getObjectIdFromItem, scrollToSelectedItem, handleSelectionChange, handleScroll, get ModelsSubView() { return ModelsSubView; } }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; } }); import { resolveComponent as _resolveComponent, openBlock as _openBlock, createCommentVNode as _createCommentVNode, renderList as _renderList, Fragment as _Fragment, mergeProps as _mergeProps, createTextVNode as _createTextVNode, withCtx as _withCtx } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; const _hoisted_1 = { class: "select-none h-full", "data-v-inspector": "components/viewer/models/Panel.vue:2:3" }; const _hoisted_2 = { key: 0, "data-v-inspector": "components/viewer/models/Panel.vue:15:9" }; const _hoisted_3 = { key: 1, "data-v-inspector": "components/viewer/models/Panel.vue:16:9" }; const _hoisted_4 = { key: 2, "data-v-inspector": "components/viewer/models/Panel.vue:17:9" }; const _hoisted_5 = { class: "flex flex-col h-full", "data-v-inspector": "components/viewer/models/Panel.vue:28:7" }; const _hoisted_6 = { key: 0, class: "sticky top-0 z-20 h-16", "data-v-inspector": "components/viewer/models/Panel.vue:31:11" }; const _hoisted_7 = ["data-item-id", "data-item-type"]; const _hoisted_8 = { key: 0, class: "bg-foundation h-16 model-header", "data-v-inspector": "components/viewer/models/Panel.vue:65:19" }; const _hoisted_9 = { class: "bg-foundation h-16 model-header", "data-v-inspector": "components/viewer/models/Panel.vue:79:19" }; const _hoisted_10 = { class: "flex items-center justify-center h-full -mt-8 opacity-60", "data-v-inspector": "components/viewer/models/Panel.vue:102:9" }; const _hoisted_11 = { class: "flex flex-col items-center justify-center gap-4 h-full -mt-8", "data-v-inspector": "components/viewer/models/Panel.vue:110:9" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_ViewerCompareChangesPanel = __nuxt_component_0; const _component_ViewerModelsVersions = __nuxt_component_1; const _component_ViewerModelsActions = __nuxt_component_2; const _component_ViewerModelsCard = __nuxt_component_3; const _component_ViewerModelsDetachedObjectHeader = __nuxt_component_4; const _component_ViewerModelsVirtualTreeItem = __nuxt_component_5; const _component_CommonLoadingIcon = __nuxt_component_6; const _component_IllustrationEmptystateModels = __nuxt_component_7; const _component_FormButton = __nuxt_component_8; const _component_ViewerLayoutSidePanel = __nuxt_component_9; const _component_ViewerModelsAddDialog = __nuxt_component_10; return _openBlock(), _createElementBlock("div", _hoisted_1, [ $setup.subView === "diff" ? (_openBlock(), _createBlock(_component_ViewerCompareChangesPanel, { key: 0, "clear-on-back": false, onClose: $setup.handleDiffClose, "data-v-inspector": "components/viewer/models/Panel.vue:3:5" })) : $setup.subView === "versions" ? (_openBlock(), _createBlock(_component_ViewerModelsVersions, { key: 1, "expanded-model-id": $setup.expandedModelId, onClose: $setup.handleVersionsClose, "data-v-inspector": "components/viewer/models/Panel.vue:8:5" }, null, 8, ["expanded-model-id"])) : (_openBlock(), _createBlock(_component_ViewerLayoutSidePanel, { key: 2, "data-v-inspector": "components/viewer/models/Panel.vue:13:5" }, { title: _withCtx(() => [ $setup.objects.length === 1 ? (_openBlock(), _createElementBlock("span", _hoisted_2, "Detached object")) : $setup.objects.length > 1 ? (_openBlock(), _createElementBlock("span", _hoisted_3, "Detached objects")) : (_openBlock(), _createElementBlock("span", _hoisted_4, "Models")) ]), actions: _withCtx(() => [ !$setup.hasObjects ? (_openBlock(), _createBlock(_component_ViewerModelsActions, { key: 0, "hide-versions": $setup.resourceItems.length === 0 && $setup.objects.length === 0, onShowVersions: _cache[0] || (_cache[0] = ($event) => $setup.subView = $setup.ModelsSubView.Versions), onAddModel: _cache[1] || (_cache[1] = ($event) => $setup.showAddModel = true), "data-v-inspector": "components/viewer/models/Panel.vue:20:9" }, null, 8, ["hide-versions"])) : _createCommentVNode("v-if", true) ]), default: _withCtx(() => [ _createElementVNode("div", _hoisted_5, [ $setup.resourceItems.length || $setup.objects.length ? (_openBlock(), _createElementBlock( _Fragment, { key: 0 }, [ _createCommentVNode(" Sticky Header Area (outside virtual list) "), $setup.stickyHeader ? (_openBlock(), _createElementBlock("div", _hoisted_6, [ !$setup.isDetachedObjectSticky ? (_openBlock(), _createBlock(_component_ViewerModelsCard, { key: 0, model: $setup.stickyHeader.model, "version-id": $setup.stickyHeader.versionId, "is-expanded": $setup.expandedModels.has($setup.stickyHeader.model.id), onToggleExpansion: _cache[2] || (_cache[2] = ($event) => $setup.toggleModelExpansion($setup.stickyHeader.model.id)), onShowVersions: $setup.handleShowVersions, onShowDiff: $setup.handleShowDiff, "data-v-inspector": "components/viewer/models/Panel.vue:32:13" }, null, 8, ["model", "version-id", "is-expanded"])) : (_openBlock(), _createBlock(_component_ViewerModelsDetachedObjectHeader, { key: 1, "object-id": $setup.stickyHeader.versionId, "is-expanded": $setup.expandedModels.has($setup.stickyHeader.model.id), onToggleExpansion: $setup.toggleModelExpansion, "data-v-inspector": "components/viewer/models/Panel.vue:41:13" }, null, 8, ["object-id", "is-expanded"])) ])) : _createCommentVNode("v-if", true), _createElementVNode( "div", _mergeProps({ class: "flex-1 simple-scrollbar overflow-x-hidden", "data-virtual-list-container": "" }, $setup.containerProps, { onScroll: _cache[3] || (_cache[3] = (...args) => $setup.handleScroll && $setup.handleScroll(...args)), "data-v-inspector": "components/viewer/models/Panel.vue:49:11" }), [ _createElementVNode( "div", _mergeProps($setup.wrapperProps, { class: "model-list", "data-v-inspector": "components/viewer/models/Panel.vue:55:13" }), [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList($setup.virtualList, ({ data: item }) => { return _openBlock(), _createElementBlock("div", { key: item.id, "data-item-id": item.id, "data-item-type": item.type, class: "group first:hidden", "data-v-inspector": "components/viewer/models/Panel.vue:56:15" }, [ _createCommentVNode(" Model Header "), item.type === "model-header" ? (_openBlock(), _createElementBlock("div", _hoisted_8, [ _createVNode(_component_ViewerModelsCard, { model: $setup.getModelFromItem(item), "version-id": $setup.getVersionIdFromItem(item), "is-expanded": $setup.expandedModels.has(item.modelId), onToggleExpansion: ($event) => $setup.toggleModelExpansion(item.modelId), onShowVersions: $setup.handleShowVersions, onShowDiff: $setup.handleShowDiff, "data-v-inspector": "components/viewer/models/Panel.vue:66:21" }, null, 8, ["model", "version-id", "is-expanded", "onToggleExpansion"]) ])) : item.type === "detached-object-header" ? (_openBlock(), _createElementBlock( _Fragment, { key: 1 }, [ _createCommentVNode(" Detached Object Header "), _createElementVNode("div", _hoisted_9, [ _createVNode(_component_ViewerModelsDetachedObjectHeader, { "object-id": $setup.getObjectIdFromItem(item), "is-expanded": $setup.expandedModels.has(item.modelId), onToggleExpansion: ($event) => $setup.toggleModelExpansion(item.modelId), "data-v-inspector": "components/viewer/models/Panel.vue:80:21" }, null, 8, ["object-id", "is-expanded", "onToggleExpansion"]) ]) ], 64 /* STABLE_FRAGMENT */ )) : item.type === "tree-item" ? (_openBlock(), _createElementBlock( _Fragment, { key: 2 }, [ _createCommentVNode(" Tree Item "), _createVNode(_component_ViewerModelsVirtualTreeItem, { item, onToggleExpansion: $setup.toggleTreeItemExpansion, onItemClick: $setup.handleItemClick, "data-v-inspector": "components/viewer/models/Panel.vue:90:19" }, null, 8, ["item"]) ], 64 /* STABLE_FRAGMENT */ )) : _createCommentVNode("v-if", true) ], 8, _hoisted_7); }), 128 /* KEYED_FRAGMENT */ )) ], 16 /* FULL_PROPS */ ) ], 16 /* FULL_PROPS */ ) ], 64 /* STABLE_FRAGMENT */ )) : $setup.resourcesLoading ? (_openBlock(), _createElementBlock( _Fragment, { key: 1 }, [ _createCommentVNode(" Loading State "), _createElementVNode("div", _hoisted_10, [ _createVNode(_component_CommonLoadingIcon, { "data-v-inspector": "components/viewer/models/Panel.vue:106:11" }) ]) ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */ )) : (_openBlock(), _createElementBlock( _Fragment, { key: 2 }, [ _createCommentVNode(" Empty State "), _createElementVNode("div", _hoisted_11, [ _createVNode(_component_IllustrationEmptystateModels, { "data-v-inspector": "components/viewer/models/Panel.vue:114:11" }), _cache[7] || (_cache[7] = _createElementVNode( "span", { class: "text-body-xs text-foreground-2", "data-v-inspector": "components/viewer/models/Panel.vue:115:11" }, "No models loaded, yet.", -1 /* CACHED */ )), _createVNode(_component_FormButton, { onClick: _cache[4] || (_cache[4] = ($event) => $setup.showAddModel = true), "data-v-inspector": "components/viewer/models/Panel.vue:116:11" }, { default: _withCtx(() => [..._cache[6] || (_cache[6] = [ _createTextVNode( "Add model", -1 /* CACHED */ ) ])]), _: 1 /* STABLE */ }) ]) ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */ )) ]) ]), _: 1 /* STABLE */ })), _createVNode(_component_ViewerModelsAddDialog, { open: $setup.showAddModel, "onUpdate:open": _cache[5] || (_cache[5] = ($event) => $setup.showAddModel = $event), "data-v-inspector": "components/viewer/models/Panel.vue:121:5" }, null, 8, ["open"]) ]); } import "/_nuxt/components/viewer/models/Panel.vue?vue&type=style&index=0&scoped=b1ece4d8&lang.css"; _sfc_main.__hmrId = "b1ece4d8"; 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], ["__scopeId", "data-v-b1ece4d8"], ["__file", "D:/speckle-server/packages/frontend-2/components/viewer/models/Panel.vue"]]); //# sourceMappingURL=data:application/json;base64,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aUI7QUFBQSIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsiUGFuZWwudnVlIl0sInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICA8ZGl2IGNsYXNzPVwic2VsZWN0LW5vbmUgaC1mdWxsXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MjozXCI+XHJcbiAgICA8Vmlld2VyQ29tcGFyZUNoYW5nZXNQYW5lbFxyXG4gICAgICB2LWlmPVwic3ViVmlldyA9PT0gJ2RpZmYnXCJcclxuICAgICAgOmNsZWFyLW9uLWJhY2s9XCJmYWxzZVwiXHJcbiAgICAgIEBjbG9zZT1cImhhbmRsZURpZmZDbG9zZVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjM6NVwiXHJcbiAgICAvPlxyXG4gICAgPFZpZXdlck1vZGVsc1ZlcnNpb25zXHJcbiAgICAgIHYtZWxzZS1pZj1cInN1YlZpZXcgPT09ICd2ZXJzaW9ucydcIlxyXG4gICAgICA6ZXhwYW5kZWQtbW9kZWwtaWQ9XCJleHBhbmRlZE1vZGVsSWRcIlxyXG4gICAgICBAY2xvc2U9XCJoYW5kbGVWZXJzaW9uc0Nsb3NlXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6ODo1XCJcclxuICAgIC8+XHJcbiAgICA8Vmlld2VyTGF5b3V0U2lkZVBhbmVsIHYtZWxzZSBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvbW9kZWxzL1BhbmVsLnZ1ZToxMzo1XCI+XHJcbiAgICAgIDx0ZW1wbGF0ZSAjdGl0bGU+XHJcbiAgICAgICAgPHNwYW4gdi1pZj1cIm9iamVjdHMubGVuZ3RoID09PSAxXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MTU6OVwiPkRldGFjaGVkIG9iamVjdDwvc3Bhbj5cclxuICAgICAgICA8c3BhbiB2LWVsc2UtaWY9XCJvYmplY3RzLmxlbmd0aCA+IDFcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvbW9kZWxzL1BhbmVsLnZ1ZToxNjo5XCI+RGV0YWNoZWQgb2JqZWN0czwvc3Bhbj5cclxuICAgICAgICA8c3BhbiB2LWVsc2UgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MTc6OVwiPk1vZGVsczwvc3Bhbj5cclxuICAgICAgPC90ZW1wbGF0ZT5cclxuICAgICAgPHRlbXBsYXRlICNhY3Rpb25zPlxyXG4gICAgICAgIDxWaWV3ZXJNb2RlbHNBY3Rpb25zXHJcbiAgICAgICAgICB2LWlmPVwiIWhhc09iamVjdHNcIlxyXG4gICAgICAgICAgOmhpZGUtdmVyc2lvbnM9XCJyZXNvdXJjZUl0ZW1zLmxlbmd0aCA9PT0gMCAmJiBvYmplY3RzLmxlbmd0aCA9PT0gMFwiXHJcbiAgICAgICAgICBAc2hvdy12ZXJzaW9ucz1cInN1YlZpZXcgPSBNb2RlbHNTdWJWaWV3LlZlcnNpb25zXCJcclxuICAgICAgICAgIEBhZGQtbW9kZWw9XCJzaG93QWRkTW9kZWwgPSB0cnVlXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MjA6OVwiXHJcbiAgICAgICAgLz5cclxuICAgICAgPC90ZW1wbGF0ZT5cclxuXHJcbiAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGgtZnVsbFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjI4OjdcIj5cclxuICAgICAgICA8dGVtcGxhdGUgdi1pZj1cInJlc291cmNlSXRlbXMubGVuZ3RoIHx8IG9iamVjdHMubGVuZ3RoXCI+XHJcbiAgICAgICAgICA8IS0tIFN0aWNreSBIZWFkZXIgQXJlYSAob3V0c2lkZSB2aXJ0dWFsIGxpc3QpIC0tPlxyXG4gICAgICAgICAgPGRpdiB2LWlmPVwic3RpY2t5SGVhZGVyXCIgY2xhc3M9XCJzdGlja3kgdG9wLTAgei0yMCBoLTE2XCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MzE6MTFcIj5cclxuICAgICAgICAgICAgPFZpZXdlck1vZGVsc0NhcmRcclxuICAgICAgICAgICAgICB2LWlmPVwiIWlzRGV0YWNoZWRPYmplY3RTdGlja3lcIlxyXG4gICAgICAgICAgICAgIDptb2RlbD1cInN0aWNreUhlYWRlciEubW9kZWxcIlxyXG4gICAgICAgICAgICAgIDp2ZXJzaW9uLWlkPVwic3RpY2t5SGVhZGVyIS52ZXJzaW9uSWRcIlxyXG4gICAgICAgICAgICAgIDppcy1leHBhbmRlZD1cImV4cGFuZGVkTW9kZWxzLmhhcyhzdGlja3lIZWFkZXIhLm1vZGVsLmlkKVwiXHJcbiAgICAgICAgICAgICAgQHRvZ2dsZS1leHBhbnNpb249XCJ0b2dnbGVNb2RlbEV4cGFuc2lvbihzdGlja3lIZWFkZXIhLm1vZGVsLmlkKVwiXHJcbiAgICAgICAgICAgICAgQHNob3ctdmVyc2lvbnM9XCJoYW5kbGVTaG93VmVyc2lvbnNcIlxyXG4gICAgICAgICAgICAgIEBzaG93LWRpZmY9XCJoYW5kbGVTaG93RGlmZlwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjMyOjEzXCJcclxuICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPFZpZXdlck1vZGVsc0RldGFjaGVkT2JqZWN0SGVhZGVyXHJcbiAgICAgICAgICAgICAgdi1lbHNlXHJcbiAgICAgICAgICAgICAgOm9iamVjdC1pZD1cInN0aWNreUhlYWRlciEudmVyc2lvbklkXCJcclxuICAgICAgICAgICAgICA6aXMtZXhwYW5kZWQ9XCJleHBhbmRlZE1vZGVscy5oYXMoc3RpY2t5SGVhZGVyIS5tb2RlbC5pZClcIlxyXG4gICAgICAgICAgICAgIEB0b2dnbGUtZXhwYW5zaW9uPVwidG9nZ2xlTW9kZWxFeHBhbnNpb25cIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvbW9kZWxzL1BhbmVsLnZ1ZTo0MToxM1wiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgIGNsYXNzPVwiZmxleC0xIHNpbXBsZS1zY3JvbGxiYXIgb3ZlcmZsb3cteC1oaWRkZW5cIlxyXG4gICAgICAgICAgICBkYXRhLXZpcnR1YWwtbGlzdC1jb250YWluZXJcclxuICAgICAgICAgICAgdi1iaW5kPVwiY29udGFpbmVyUHJvcHNcIlxyXG4gICAgICAgICAgICBAc2Nyb2xsPVwiaGFuZGxlU2Nyb2xsXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6NDk6MTFcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8ZGl2IHYtYmluZD1cIndyYXBwZXJQcm9wc1wiIGNsYXNzPVwibW9kZWwtbGlzdFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjU1OjEzXCI+XHJcbiAgICAgICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgICAgdi1mb3I9XCJ7IGRhdGE6IGl0ZW0gfSBpbiB2aXJ0dWFsTGlzdFwiXHJcbiAgICAgICAgICAgICAgICA6a2V5PVwiaXRlbS5pZFwiXHJcbiAgICAgICAgICAgICAgICA6ZGF0YS1pdGVtLWlkPVwiaXRlbS5pZFwiXHJcbiAgICAgICAgICAgICAgICA6ZGF0YS1pdGVtLXR5cGU9XCJpdGVtLnR5cGVcIlxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJncm91cCBmaXJzdDpoaWRkZW5cIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvbW9kZWxzL1BhbmVsLnZ1ZTo1NjoxNVwiXHJcbiAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgPCEtLSBNb2RlbCBIZWFkZXIgLS0+XHJcbiAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1pZj1cIml0ZW0udHlwZSA9PT0gJ21vZGVsLWhlYWRlcidcIj5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJnLWZvdW5kYXRpb24gaC0xNiBtb2RlbC1oZWFkZXJcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvbW9kZWxzL1BhbmVsLnZ1ZTo2NToxOVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxWaWV3ZXJNb2RlbHNDYXJkXHJcbiAgICAgICAgICAgICAgICAgICAgICA6bW9kZWw9XCJnZXRNb2RlbEZyb21JdGVtKGl0ZW0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgIDp2ZXJzaW9uLWlkPVwiZ2V0VmVyc2lvbklkRnJvbUl0ZW0oaXRlbSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgOmlzLWV4cGFuZGVkPVwiZXhwYW5kZWRNb2RlbHMuaGFzKGl0ZW0ubW9kZWxJZClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgQHRvZ2dsZS1leHBhbnNpb249XCJ0b2dnbGVNb2RlbEV4cGFuc2lvbihpdGVtLm1vZGVsSWQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgIEBzaG93LXZlcnNpb25zPVwiaGFuZGxlU2hvd1ZlcnNpb25zXCJcclxuICAgICAgICAgICAgICAgICAgICAgIEBzaG93LWRpZmY9XCJoYW5kbGVTaG93RGlmZlwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjY2OjIxXCJcclxuICAgICAgICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBEZXRhY2hlZCBPYmplY3QgSGVhZGVyIC0tPlxyXG4gICAgICAgICAgICAgICAgPHRlbXBsYXRlIHYtZWxzZS1pZj1cIml0ZW0udHlwZSA9PT0gJ2RldGFjaGVkLW9iamVjdC1oZWFkZXInXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiZy1mb3VuZGF0aW9uIGgtMTYgbW9kZWwtaGVhZGVyXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6Nzk6MTlcIj5cclxuICAgICAgICAgICAgICAgICAgICA8Vmlld2VyTW9kZWxzRGV0YWNoZWRPYmplY3RIZWFkZXJcclxuICAgICAgICAgICAgICAgICAgICAgIDpvYmplY3QtaWQ9XCJnZXRPYmplY3RJZEZyb21JdGVtKGl0ZW0pXCJcclxuICAgICAgICAgICAgICAgICAgICAgIDppcy1leHBhbmRlZD1cImV4cGFuZGVkTW9kZWxzLmhhcyhpdGVtLm1vZGVsSWQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgIEB0b2dnbGUtZXhwYW5zaW9uPVwidG9nZ2xlTW9kZWxFeHBhbnNpb24oaXRlbS5tb2RlbElkKVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjgwOjIxXCJcclxuICAgICAgICAgICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvdGVtcGxhdGU+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBUcmVlIEl0ZW0gLS0+XHJcbiAgICAgICAgICAgICAgICA8dGVtcGxhdGUgdi1lbHNlLWlmPVwiaXRlbS50eXBlID09PSAndHJlZS1pdGVtJ1wiPlxyXG4gICAgICAgICAgICAgICAgICA8Vmlld2VyTW9kZWxzVmlydHVhbFRyZWVJdGVtXHJcbiAgICAgICAgICAgICAgICAgICAgOml0ZW09XCJpdGVtXCJcclxuICAgICAgICAgICAgICAgICAgICBAdG9nZ2xlLWV4cGFuc2lvbj1cInRvZ2dsZVRyZWVJdGVtRXhwYW5zaW9uXCJcclxuICAgICAgICAgICAgICAgICAgICBAaXRlbS1jbGljaz1cImhhbmRsZUl0ZW1DbGlja1wiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjkwOjE5XCJcclxuICAgICAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgICAgIDwvdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZW1wbGF0ZT5cclxuXHJcbiAgICAgICAgPCEtLSBMb2FkaW5nIFN0YXRlIC0tPlxyXG4gICAgICAgIDxkaXZcclxuICAgICAgICAgIHYtZWxzZS1pZj1cInJlc291cmNlc0xvYWRpbmdcIlxyXG4gICAgICAgICAgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBoLWZ1bGwgLW10LTggb3BhY2l0eS02MFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjEwMjo5XCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8Q29tbW9uTG9hZGluZ0ljb24gZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MTA2OjExXCIgLz5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPCEtLSBFbXB0eSBTdGF0ZSAtLT5cclxuICAgICAgICA8ZGl2XHJcbiAgICAgICAgICB2LWVsc2VcclxuICAgICAgICAgIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgZ2FwLTQgaC1mdWxsIC1tdC04XCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MTEwOjlcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxJbGx1c3RyYXRpb25FbXB0eXN0YXRlTW9kZWxzIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjExNDoxMVwiIC8+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtYm9keS14cyB0ZXh0LWZvcmVncm91bmQtMlwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9tb2RlbHMvUGFuZWwudnVlOjExNToxMVwiPk5vIG1vZGVscyBsb2FkZWQsIHlldC48L3NwYW4+XHJcbiAgICAgICAgICA8Rm9ybUJ1dHRvbiBAY2xpY2s9XCJzaG93QWRkTW9kZWwgPSB0cnVlXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MTE2OjExXCI+QWRkIG1vZGVsPC9Gb3JtQnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvVmlld2VyTGF5b3V0U2lkZVBhbmVsPlxyXG5cclxuICAgIDxWaWV3ZXJNb2RlbHNBZGREaWFsb2cgdi1tb2RlbDpvcGVuPVwic2hvd0FkZE1vZGVsXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWU6MTIxOjVcIiAvPlxyXG4gIDwvZGl2PlxyXG48L3RlbXBsYXRlPlxyXG5cclxuPHNjcmlwdCBzZXR1cCBsYW5nPVwidHNcIj5cclxuaW1wb3J0IHtcclxuICB1c2VJbmplY3RlZFZpZXdlckxvYWRlZFJlc291cmNlcyxcclxuICB1c2VJbmplY3RlZFZpZXdlcixcclxuICB1c2VJbmplY3RlZFZpZXdlclN0YXRlXHJcbn0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cCdcclxuaW1wb3J0IHsgTW9kZWxzU3ViVmlldywgdHlwZSBFeHBsb3Jlck5vZGUgfSBmcm9tICd+fi9saWIvdmlld2VyL2hlbHBlcnMvc2NlbmVFeHBsb3JlcidcclxuaW1wb3J0IHR5cGUgeyBWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeSB9IGZyb20gJ35+L2xpYi9jb21tb24vZ2VuZXJhdGVkL2dxbC9ncmFwaHFsJ1xyXG5pbXBvcnQgdHlwZSB7IEdldCB9IGZyb20gJ3R5cGUtZmVzdCdcclxuaW1wb3J0IHsgdXNlRGlmZlV0aWxpdGllcywgdXNlU2VsZWN0aW9uVXRpbGl0aWVzIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy91aSdcclxuaW1wb3J0IHtcclxuICB1c2VUcmVlTWFuYWdlbWVudCxcclxuICB0eXBlIFVuaWZpZWRWaXJ0dWFsSXRlbVxyXG59IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvdHJlZSdcclxuaW1wb3J0IHsgdXNlVmlydHVhbExpc3QsIHVzZURlYm91bmNlRm4sIHVzZVRocm90dGxlRm4gfSBmcm9tICdAdnVldXNlL2NvcmUnXHJcblxyXG50eXBlIE1vZGVsSXRlbSA9IE5vbk51bGxhYmxlPEdldDxWaWV3ZXJMb2FkZWRSZXNvdXJjZXNRdWVyeSwgJ3Byb2plY3QubW9kZWxzLml0ZW1zWzBdJz4+XHJcblxyXG5jb25zdCBzdWJWaWV3ID0gZGVmaW5lTW9kZWw8TW9kZWxzU3ViVmlldz4oJ3N1YlZpZXcnLCB7IGRlZmF1bHQ6IE1vZGVsc1N1YlZpZXcuTWFpbiB9KVxyXG5jb25zdCBleHBhbmRlZE1vZGVsSWQgPSByZWY8c3RyaW5nIHwgbnVsbD4obnVsbClcclxuXHJcbmNvbnN0IHNob3dBZGRNb2RlbCA9IHJlZihmYWxzZSlcclxuXHJcbmNvbnN0IGV4cGFuZGVkTm9kZXMgPSByZWY8U2V0PHN0cmluZz4+KG5ldyBTZXQoKSlcclxuY29uc3QgZXhwYW5kZWRNb2RlbHMgPSByZWY8U2V0PHN0cmluZz4+KG5ldyBTZXQoKSlcclxuY29uc3QgZGlzYWJsZVNjcm9sbE9uTmV4dFNlbGVjdGlvbiA9IHJlZihmYWxzZSlcclxuXHJcbmNvbnN0IHN0aWNreUhlYWRlciA9IHJlZjx7IG1vZGVsOiBNb2RlbEl0ZW07IHZlcnNpb25JZDogc3RyaW5nIH0gfCBudWxsPihudWxsKVxyXG5jb25zdCBzY3JvbGxUb3AgPSByZWYoMClcclxuXHJcbmNvbnN0IHsgcmVzb3VyY2VJdGVtcywgbW9kZWxzQW5kVmVyc2lvbklkcywgb2JqZWN0cywgcmVzb3VyY2VzTG9hZGluZyB9ID1cclxuICB1c2VJbmplY3RlZFZpZXdlckxvYWRlZFJlc291cmNlcygpXHJcbmNvbnN0IHtcclxuICBtZXRhZGF0YTogeyB3b3JsZFRyZWUgfVxyXG59ID0gdXNlSW5qZWN0ZWRWaWV3ZXIoKVxyXG5jb25zdCB7XHJcbiAgcmVzb3VyY2VzOiB7XHJcbiAgICByZXNwb25zZTogeyByZXNvdXJjZUl0ZW1zOiBzdGF0ZVJlc291cmNlSXRlbXMgfVxyXG4gIH0sXHJcbiAgdWk6IHsgZGlmZjogZGlmZlN0YXRlIH1cclxufSA9IHVzZUluamVjdGVkVmlld2VyU3RhdGUoKVxyXG5jb25zdCB7XHJcbiAgb2JqZWN0czogc2VsZWN0ZWRPYmplY3RzLFxyXG4gIGFkZFRvU2VsZWN0aW9uLFxyXG4gIGNsZWFyU2VsZWN0aW9uLFxyXG4gIHJlbW92ZUZyb21TZWxlY3Rpb25cclxufSA9IHVzZVNlbGVjdGlvblV0aWxpdGllcygpXHJcbmNvbnN0IHsgZGlmZk1vZGVsVmVyc2lvbnMsIGVuZERpZmYgfSA9IHVzZURpZmZVdGlsaXRpZXMoKVxyXG5jb25zdCB7XHJcbiAgZmxhdHRlbk1vZGVsVHJlZSxcclxuICBnZXRSb290Tm9kZXNGb3JNb2RlbCxcclxuICBmaW5kT2JqZWN0SW5Ob2RlcyxcclxuICBleHBhbmROb2Rlc1RvU2hvd09iamVjdCxcclxuICB0cmVlU3RhdGVNYW5hZ2VyXHJcbn0gPSB1c2VUcmVlTWFuYWdlbWVudCgpXHJcblxyXG5jb25zdCBoYXNPYmplY3RzID0gY29tcHV0ZWQoKCkgPT4gb2JqZWN0cy52YWx1ZS5sZW5ndGggPiAwKVxyXG5cclxuY29uc3QgdW5pZmllZFZpcnR1YWxJdGVtcyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICByZXR1cm4gdHJlZVN0YXRlTWFuYWdlci5nZXRVbmlmaWVkVmlydHVhbEl0ZW1zKFxyXG4gICAgbW9kZWxzQW5kVmVyc2lvbklkcy52YWx1ZSxcclxuICAgIGV4cGFuZGVkTW9kZWxzLnZhbHVlLFxyXG4gICAgZXhwYW5kZWROb2Rlcy52YWx1ZSxcclxuICAgIHNlbGVjdGVkT2JqZWN0cy52YWx1ZSxcclxuICAgIHdvcmxkVHJlZS52YWx1ZSB8fCBudWxsLFxyXG4gICAgc3RhdGVSZXNvdXJjZUl0ZW1zLnZhbHVlIGFzIHsgb2JqZWN0SWQ6IHN0cmluZzsgbW9kZWxJZD86IHN0cmluZyB9W10sXHJcbiAgICBvYmplY3RzLnZhbHVlLFxyXG4gICAgZ2V0Um9vdE5vZGVzRm9yTW9kZWwsXHJcbiAgICBmbGF0dGVuTW9kZWxUcmVlXHJcbiAgKVxyXG59KVxyXG5cclxuY29uc3Qge1xyXG4gIGxpc3Q6IHZpcnR1YWxMaXN0LFxyXG4gIGNvbnRhaW5lclByb3BzLFxyXG4gIHdyYXBwZXJQcm9wc1xyXG59ID0gdXNlVmlydHVhbExpc3QodW5pZmllZFZpcnR1YWxJdGVtcywge1xyXG4gIGl0ZW1IZWlnaHQ6IChpbmRleCkgPT4ge1xyXG4gICAgY29uc3QgaXRlbSA9IHVuaWZpZWRWaXJ0dWFsSXRlbXMudmFsdWVbaW5kZXhdXHJcbiAgICByZXR1cm4gaXRlbT8udHlwZSA9PT0gJ21vZGVsLWhlYWRlcicgfHwgaXRlbT8udHlwZSA9PT0gJ2RldGFjaGVkLW9iamVjdC1oZWFkZXInXHJcbiAgICAgID8gNjRcclxuICAgICAgOiA0MFxyXG4gIH0sXHJcbiAgb3ZlcnNjYW46IDIwXHJcbn0pXHJcblxyXG4vLyBDYWxjdWxhdGUgaGVhZGVyIHBvc2l0aW9ucyBwcmVjaXNlbHkgLSBtZW1vaXplZCBmb3IgcGVyZm9ybWFuY2VcclxuY29uc3QgbW9kZWxIZWFkZXJQb3NpdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgY29uc3QgaGVhZGVyczogQXJyYXk8e1xyXG4gICAgaW5kZXg6IG51bWJlclxyXG4gICAgbW9kZWw6IE1vZGVsSXRlbVxyXG4gICAgdmVyc2lvbklkOiBzdHJpbmdcclxuICAgIHBvc2l0aW9uOiBudW1iZXJcclxuICB9PiA9IFtdXHJcblxyXG4gIGxldCBjdW11bGF0aXZlSGVpZ2h0ID0gMFxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdW5pZmllZFZpcnR1YWxJdGVtcy52YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgY29uc3QgaXRlbSA9IHVuaWZpZWRWaXJ0dWFsSXRlbXMudmFsdWVbaV1cclxuICAgIGNvbnN0IGl0ZW1IZWlnaHQgPVxyXG4gICAgICBpdGVtLnR5cGUgPT09ICdtb2RlbC1oZWFkZXInIHx8IGl0ZW0udHlwZSA9PT0gJ2RldGFjaGVkLW9iamVjdC1oZWFkZXInID8gNjQgOiA0MFxyXG5cclxuICAgIGlmIChpdGVtLnR5cGUgPT09ICdtb2RlbC1oZWFkZXInKSB7XHJcbiAgICAgIGNvbnN0IGRhdGEgPSBpdGVtLmRhdGEgYXMgeyBtb2RlbDogTW9kZWxJdGVtOyB2ZXJzaW9uSWQ6IHN0cmluZyB9XHJcbiAgICAgIGhlYWRlcnMucHVzaCh7XHJcbiAgICAgICAgaW5kZXg6IGksXHJcbiAgICAgICAgbW9kZWw6IGRhdGEubW9kZWwsXHJcbiAgICAgICAgdmVyc2lvbklkOiBkYXRhLnZlcnNpb25JZCxcclxuICAgICAgICBwb3NpdGlvbjogY3VtdWxhdGl2ZUhlaWdodFxyXG4gICAgICB9KVxyXG4gICAgfSBlbHNlIGlmIChpdGVtLnR5cGUgPT09ICdkZXRhY2hlZC1vYmplY3QtaGVhZGVyJykge1xyXG4gICAgICBjb25zdCBkYXRhID0gaXRlbS5kYXRhIGFzIHsgb2JqZWN0SWQ6IHN0cmluZyB9XHJcbiAgICAgIC8vIENyZWF0ZSBhIGRldGFjaGVkIG9iamVjdCBoZWFkZXIgaXRlbSBpbiB0aGUgdmlydHVhbCBsaXN0XHJcbiAgICAgIGNvbnN0IGRldGFjaGVkT2JqZWN0SGVhZGVyID0ge1xyXG4gICAgICAgIGlkOiBkYXRhLm9iamVjdElkLFxyXG4gICAgICAgIG5hbWU6ICdEZXRhY2hlZCBPYmplY3QnLFxyXG4gICAgICAgIGRpc3BsYXlOYW1lOiAnRGV0YWNoZWQgT2JqZWN0J1xyXG4gICAgICB9IGFzIHVua25vd24gYXMgTW9kZWxJdGVtXHJcbiAgICAgIGhlYWRlcnMucHVzaCh7XHJcbiAgICAgICAgaW5kZXg6IGksXHJcbiAgICAgICAgbW9kZWw6IGRldGFjaGVkT2JqZWN0SGVhZGVyLFxyXG4gICAgICAgIHZlcnNpb25JZDogZGF0YS5vYmplY3RJZCxcclxuICAgICAgICBwb3NpdGlvbjogY3VtdWxhdGl2ZUhlaWdodFxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gICAgY3VtdWxhdGl2ZUhlaWdodCArPSBpdGVtSGVpZ2h0XHJcbiAgfVxyXG4gIHJldHVybiBoZWFkZXJzXHJcbn0pXHJcblxyXG5jb25zdCBoYXNEaWZmQWN0aXZlID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gIHJldHVybiAhIShkaWZmU3RhdGUub2xkVmVyc2lvbi52YWx1ZSAmJiBkaWZmU3RhdGUubmV3VmVyc2lvbi52YWx1ZSlcclxufSlcclxuXHJcbmNvbnN0IGlzRGV0YWNoZWRPYmplY3RTdGlja3kgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgaWYgKCFzdGlja3lIZWFkZXIudmFsdWUpIHJldHVybiBmYWxzZVxyXG4gIHJldHVybiBvYmplY3RzLnZhbHVlLnNvbWUoKG9iaikgPT4gb2JqLm9iamVjdElkID09PSBzdGlja3lIZWFkZXIudmFsdWU/Lm1vZGVsLmlkKVxyXG59KVxyXG5cclxuY29uc3QgaGFuZGxlU2hvd1ZlcnNpb25zID0gKG1vZGVsSWQ6IHN0cmluZykgPT4ge1xyXG4gIGV4cGFuZGVkTW9kZWxJZC52YWx1ZSA9IG1vZGVsSWRcclxuICBzdWJWaWV3LnZhbHVlID0gTW9kZWxzU3ViVmlldy5WZXJzaW9uc1xyXG59XHJcblxyXG5jb25zdCBoYW5kbGVTaG93RGlmZiA9IGFzeW5jIChtb2RlbElkOiBzdHJpbmcsIHZlcnNpb25BOiBzdHJpbmcsIHZlcnNpb25COiBzdHJpbmcpID0+IHtcclxuICBhd2FpdCBkaWZmTW9kZWxWZXJzaW9ucyhtb2RlbElkLCB2ZXJzaW9uQSwgdmVyc2lvbkIpXHJcbiAgZXhwYW5kZWRNb2RlbElkLnZhbHVlID0gbW9kZWxJZFxyXG4gIHN1YlZpZXcudmFsdWUgPSBNb2RlbHNTdWJWaWV3LkRpZmZcclxufVxyXG5cclxuY29uc3QgaGFuZGxlVmVyc2lvbnNDbG9zZSA9ICgpID0+IHtcclxuICBzdWJWaWV3LnZhbHVlID0gTW9kZWxzU3ViVmlldy5NYWluXHJcbiAgZXhwYW5kZWRNb2RlbElkLnZhbHVlID0gbnVsbFxyXG59XHJcblxyXG5jb25zdCBoYW5kbGVEaWZmQ2xvc2UgPSBhc3luYyAoKSA9PiB7XHJcbiAgYXdhaXQgZW5kRGlmZigpXHJcbiAgc3ViVmlldy52YWx1ZSA9IE1vZGVsc1N1YlZpZXcuVmVyc2lvbnNcclxufVxyXG5cclxuY29uc3QgdG9nZ2xlTW9kZWxFeHBhbnNpb24gPSAobW9kZWxJZDogc3RyaW5nKSA9PiB7XHJcbiAgaWYgKGV4cGFuZGVkTW9kZWxzLnZhbHVlLmhhcyhtb2RlbElkKSkge1xyXG4gICAgZXhwYW5kZWRNb2RlbHMudmFsdWUuZGVsZXRlKG1vZGVsSWQpXHJcbiAgfSBlbHNlIHtcclxuICAgIGV4cGFuZGVkTW9kZWxzLnZhbHVlLmFkZChtb2RlbElkKVxyXG4gIH1cclxufVxyXG5cclxuY29uc3QgdG9nZ2xlVHJlZUl0ZW1FeHBhbnNpb24gPSAoaXRlbUlkOiBzdHJpbmcpID0+IHtcclxuICBpZiAoZXhwYW5kZWROb2Rlcy52YWx1ZS5oYXMoaXRlbUlkKSkge1xyXG4gICAgZXhwYW5kZWROb2Rlcy52YWx1ZS5kZWxldGUoaXRlbUlkKVxyXG4gIH0gZWxzZSB7XHJcbiAgICBleHBhbmRlZE5vZGVzLnZhbHVlLmFkZChpdGVtSWQpXHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBoYW5kbGVJdGVtQ2xpY2sgPSAoXHJcbiAgaXRlbTogVW5pZmllZFZpcnR1YWxJdGVtLFxyXG4gIGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudFxyXG4pID0+IHtcclxuICBpZiAoaXRlbS50eXBlICE9PSAndHJlZS1pdGVtJykgcmV0dXJuXHJcblxyXG4gIGNvbnN0IG5vZGUgPSBpdGVtLmRhdGEgYXMgRXhwbG9yZXJOb2RlXHJcbiAgY29uc3Qgc3BlY2tsZURhdGEgPSBub2RlLnJhd1xyXG4gIGlmICghc3BlY2tsZURhdGE/LmlkKSByZXR1cm5cclxuXHJcbiAgY29uc3QgaXNDdXJyZW50bHlTZWxlY3RlZCA9IHNlbGVjdGVkT2JqZWN0cy52YWx1ZS5maW5kKChvKSA9PiBvLmlkID09PSBzcGVja2xlRGF0YS5pZClcclxuXHJcbiAgaWYgKGlzQ3VycmVudGx5U2VsZWN0ZWQgJiYgIWV2ZW50LnNoaWZ0S2V5KSB7XHJcbiAgICBpZiAoaXRlbS5oYXNDaGlsZHJlbiAmJiAhaXRlbS5pc0V4cGFuZGVkKSB7XHJcbiAgICAgIHRvZ2dsZVRyZWVJdGVtRXhwYW5zaW9uKGl0ZW0uaWQpXHJcbiAgICB9XHJcbiAgICByZXR1cm5cclxuICB9XHJcblxyXG4gIGlmIChpc0N1cnJlbnRseVNlbGVjdGVkICYmIGV2ZW50LnNoaWZ0S2V5KSB7XHJcbiAgICBkaXNhYmxlU2Nyb2xsT25OZXh0U2VsZWN0aW9uLnZhbHVlID0gdHJ1ZVxyXG4gICAgcmVtb3ZlRnJvbVNlbGVjdGlvbihzcGVja2xlRGF0YSlcclxuICAgIHJldHVyblxyXG4gIH1cclxuXHJcbiAgLy8gRGlzYWJsZSBzY3JvbGwgZm9yIHRoaXMgdXNlci1pbml0aWF0ZWQgc2VsZWN0aW9uXHJcbiAgZGlzYWJsZVNjcm9sbE9uTmV4dFNlbGVjdGlvbi52YWx1ZSA9IHRydWVcclxuXHJcbiAgaWYgKCFldmVudC5zaGlmdEtleSkgY2xlYXJTZWxlY3Rpb24oKVxyXG4gIGFkZFRvU2VsZWN0aW9uKHNwZWNrbGVEYXRhKVxyXG5cclxuICBpZiAoaXRlbS5oYXNDaGlsZHJlbiAmJiAhaXRlbS5pc0V4cGFuZGVkKSB7XHJcbiAgICB0b2dnbGVUcmVlSXRlbUV4cGFuc2lvbihpdGVtLmlkKVxyXG4gIH1cclxufVxyXG5cclxuY29uc3QgZ2V0TW9kZWxGcm9tSXRlbSA9IChpdGVtOiBVbmlmaWVkVmlydHVhbEl0ZW0pOiBNb2RlbEl0ZW0gPT4ge1xyXG4gIGlmIChpdGVtLnR5cGUgPT09ICdtb2RlbC1oZWFkZXInKSB7XHJcbiAgICByZXR1cm4gKGl0ZW0uZGF0YSBhcyB7IG1vZGVsOiBNb2RlbEl0ZW07IHZlcnNpb25JZDogc3RyaW5nIH0pLm1vZGVsXHJcbiAgfVxyXG4gIHJldHVybiB7fSBhcyBNb2RlbEl0ZW1cclxufVxyXG5cclxuY29uc3QgZ2V0VmVyc2lvbklkRnJvbUl0ZW0gPSAoaXRlbTogVW5pZmllZFZpcnR1YWxJdGVtKTogc3RyaW5nID0+IHtcclxuICBpZiAoaXRlbS50eXBlID09PSAnbW9kZWwtaGVhZGVyJykge1xyXG4gICAgcmV0dXJuIChpdGVtLmRhdGEgYXMgeyBtb2RlbDogTW9kZWxJdGVtOyB2ZXJzaW9uSWQ6IHN0cmluZyB9KS52ZXJzaW9uSWRcclxuICB9XHJcbiAgcmV0dXJuICcnXHJcbn1cclxuXHJcbmNvbnN0IGdldE9iamVjdElkRnJvbUl0ZW0gPSAoaXRlbTogVW5pZmllZFZpcnR1YWxJdGVtKTogc3RyaW5nID0+IHtcclxuICBpZiAoaXRlbS50eXBlID09PSAnZGV0YWNoZWQtb2JqZWN0LWhlYWRlcicpIHtcclxuICAgIHJldHVybiAoaXRlbS5kYXRhIGFzIHsgb2JqZWN0SWQ6IHN0cmluZyB9KS5vYmplY3RJZFxyXG4gIH1cclxuICByZXR1cm4gJydcclxufVxyXG5cclxuY29uc3Qgc2Nyb2xsVG9TZWxlY3RlZEl0ZW0gPSAob2JqZWN0SWQ6IHN0cmluZykgPT4ge1xyXG4gIG5leHRUaWNrKCgpID0+IHtcclxuICAgIGNvbnN0IGl0ZW1JbmRleCA9IHVuaWZpZWRWaXJ0dWFsSXRlbXMudmFsdWUuZmluZEluZGV4KFxyXG4gICAgICAoaXRlbSkgPT5cclxuICAgICAgICBpdGVtLnR5cGUgPT09ICd0cmVlLWl0ZW0nICYmIChpdGVtLmRhdGEgYXMgRXhwbG9yZXJOb2RlKS5yYXc/LmlkID09PSBvYmplY3RJZFxyXG4gICAgKVxyXG4gICAgaWYgKGl0ZW1JbmRleCAhPT0gLTEpIHtcclxuICAgICAgY29uc3QgY29udGFpbmVyID0gY29udGFpbmVyUHJvcHMucmVmLnZhbHVlXHJcbiAgICAgIGlmIChjb250YWluZXIpIHtcclxuICAgICAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0XHJcbiAgICAgICAgY29uc3QgaXRlbUhlaWdodCA9IDQwXHJcbiAgICAgICAgY29uc3QgdG90YWxPZmZzZXQgPSBpdGVtSW5kZXggKiBpdGVtSGVpZ2h0XHJcbiAgICAgICAgY29uc3QgY2VudGVyT2Zmc2V0ID0gY29udGFpbmVySGVpZ2h0IC8gMiAtIGl0ZW1IZWlnaHQgLyAyXHJcbiAgICAgICAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSBNYXRoLm1heCgwLCB0b3RhbE9mZnNldCAtIGNlbnRlck9mZnNldClcclxuXHJcbiAgICAgICAgY29udGFpbmVyLnNjcm9sbFRvKHtcclxuICAgICAgICAgIHRvcDogc2Nyb2xsUG9zaXRpb25cclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSlcclxufVxyXG5cclxuY29uc3QgaGFuZGxlU2VsZWN0aW9uQ2hhbmdlID0gdXNlRGVib3VuY2VGbihcclxuICAobmV3U2VsZWN0aW9uOiB0eXBlb2Ygc2VsZWN0ZWRPYmplY3RzLnZhbHVlKSA9PiB7XHJcbiAgICBpZiAobmV3U2VsZWN0aW9uLmxlbmd0aCA+IDAgJiYgIWRpc2FibGVTY3JvbGxPbk5leHRTZWxlY3Rpb24udmFsdWUpIHtcclxuICAgICAgZm9yIChjb25zdCBzZWxlY3RlZE9iaiBvZiBuZXdTZWxlY3Rpb24pIHtcclxuICAgICAgICBmb3IgKGNvbnN0IHsgbW9kZWwgfSBvZiBtb2RlbHNBbmRWZXJzaW9uSWRzLnZhbHVlKSB7XHJcbiAgICAgICAgICBjb25zdCBtb2RlbFJvb3ROb2RlcyA9IGdldFJvb3ROb2Rlc0Zvck1vZGVsKFxyXG4gICAgICAgICAgICBtb2RlbC5pZCxcclxuICAgICAgICAgICAgd29ybGRUcmVlLnZhbHVlIHx8IG51bGwsXHJcbiAgICAgICAgICAgIHN0YXRlUmVzb3VyY2VJdGVtcy52YWx1ZSBhcyB7IG9iamVjdElkOiBzdHJpbmc7IG1vZGVsSWQ/OiBzdHJpbmcgfVtdLFxyXG4gICAgICAgICAgICBtb2RlbHNBbmRWZXJzaW9uSWRzLnZhbHVlXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgICBjb25zdCBjb250YWluc09iamVjdCA9IGZpbmRPYmplY3RJbk5vZGVzKG1vZGVsUm9vdE5vZGVzLCBzZWxlY3RlZE9iai5pZClcclxuXHJcbiAgICAgICAgICBpZiAoY29udGFpbnNPYmplY3QpIHtcclxuICAgICAgICAgICAgZXhwYW5kZWRNb2RlbHMudmFsdWUuYWRkKG1vZGVsLmlkKVxyXG5cclxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gZXhwYW5kTm9kZXNUb1Nob3dPYmplY3QoXHJcbiAgICAgICAgICAgICAgbW9kZWxSb290Tm9kZXMsXHJcbiAgICAgICAgICAgICAgc2VsZWN0ZWRPYmouaWQsXHJcbiAgICAgICAgICAgICAgbW9kZWwuaWQsXHJcbiAgICAgICAgICAgICAgZXhwYW5kZWROb2Rlcy52YWx1ZVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQuZm91bmQgJiYgcmVzdWx0Lm5vZGVzVG9FeHBhbmQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgIHJlc3VsdC5ub2Rlc1RvRXhwYW5kLmZvckVhY2goKG5vZGVJZCkgPT4gZXhwYW5kZWROb2Rlcy52YWx1ZS5hZGQobm9kZUlkKSlcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgc2Nyb2xsVG9TZWxlY3RlZEl0ZW0oc2VsZWN0ZWRPYmouaWQpXHJcbiAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrXHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBkaXNhYmxlU2Nyb2xsT25OZXh0U2VsZWN0aW9uLnZhbHVlID0gZmFsc2VcclxuICB9LFxyXG4gIDEwMFxyXG4pXHJcblxyXG4vLyBTaW1wbGUgc2Nyb2xsIHRyYWNraW5nIC0ganVzdCBzd2l0Y2ggaGVhZGVyc1xyXG5jb25zdCBoYW5kbGVTY3JvbGwgPSB1c2VUaHJvdHRsZUZuKChlOiBFdmVudCkgPT4ge1xyXG4gIGNvbnN0IGNvbnRhaW5lciA9IGUudGFyZ2V0IGFzIEhUTUxFbGVtZW50XHJcbiAgaWYgKCFjb250YWluZXIpIHJldHVyblxyXG5cclxuICBzY3JvbGxUb3AudmFsdWUgPSBjb250YWluZXIuc2Nyb2xsVG9wXHJcblxyXG4gIGNvbnN0IG1vZGVsSGVhZGVycyA9IG1vZGVsSGVhZGVyUG9zaXRpb25zLnZhbHVlXHJcbiAgaWYgKG1vZGVsSGVhZGVycy5sZW5ndGggPT09IDApIHJldHVyblxyXG5cclxuICAvLyBGaW5kIHRoZSBjdXJyZW50IGFjdGl2ZSBoZWFkZXJcclxuICBsZXQgY3VycmVudEhlYWRlckluZGV4ID0gMFxyXG4gIGZvciAobGV0IGkgPSBtb2RlbEhlYWRlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgIGlmIChtb2RlbEhlYWRlcnNbaV0ucG9zaXRpb24gPD0gc2Nyb2xsVG9wLnZhbHVlKSB7XHJcbiAgICAgIGN1cnJlbnRIZWFkZXJJbmRleCA9IGlcclxuICAgICAgYnJlYWtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbnN0IGN1cnJlbnRIZWFkZXIgPSBtb2RlbEhlYWRlcnNbY3VycmVudEhlYWRlckluZGV4XVxyXG5cclxuICAvLyBTaW1wbHkgdXBkYXRlIHN0aWNreSBoZWFkZXJcclxuICBpZiAoY3VycmVudEhlYWRlcikge1xyXG4gICAgc3RpY2t5SGVhZGVyLnZhbHVlID0ge1xyXG4gICAgICBtb2RlbDogY3VycmVudEhlYWRlci5tb2RlbCxcclxuICAgICAgdmVyc2lvbklkOiBjdXJyZW50SGVhZGVyLnZlcnNpb25JZFxyXG4gICAgfVxyXG4gIH1cclxufSwgMTYpXHJcblxyXG53YXRjaChzZWxlY3RlZE9iamVjdHMsIGhhbmRsZVNlbGVjdGlvbkNoYW5nZSwgeyBkZWVwOiB0cnVlIH0pXHJcblxyXG53YXRjaChzdWJWaWV3LCAobmV3U3ViVmlldykgPT4ge1xyXG4gIGlmIChuZXdTdWJWaWV3ID09PSBNb2RlbHNTdWJWaWV3Lk1haW4pIHtcclxuICAgIGV4cGFuZGVkTW9kZWxJZC52YWx1ZSA9IG51bGxcclxuICB9XHJcbn0pXHJcblxyXG53YXRjaChoYXNEaWZmQWN0aXZlLCAoaXNBY3RpdmUpID0+IHtcclxuICBpZiAoaXNBY3RpdmUgJiYgc3ViVmlldy52YWx1ZSAhPT0gTW9kZWxzU3ViVmlldy5EaWZmKSB7XHJcbiAgICBzdWJWaWV3LnZhbHVlID0gTW9kZWxzU3ViVmlldy5EaWZmXHJcbiAgfVxyXG59KVxyXG5cclxuLy8gSW5pdGlhbGl6ZSBhbmQgdXBkYXRlIHN0aWNreSBoZWFkZXIgd2hlbiBtb2RlbHMgY2hhbmdlXHJcbndhdGNoKFxyXG4gIHVuaWZpZWRWaXJ0dWFsSXRlbXMsXHJcbiAgKGl0ZW1zKSA9PiB7XHJcbiAgICBpZiAoaXRlbXMubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb25zdCBmaXJzdEhlYWRlciA9IGl0ZW1zLmZpbmQoXHJcbiAgICAgICAgKGl0ZW0pID0+IGl0ZW0udHlwZSA9PT0gJ21vZGVsLWhlYWRlcicgfHwgaXRlbS50eXBlID09PSAnZGV0YWNoZWQtb2JqZWN0LWhlYWRlcidcclxuICAgICAgKVxyXG4gICAgICBpZiAoZmlyc3RIZWFkZXIpIHtcclxuICAgICAgICBpZiAoZmlyc3RIZWFkZXIudHlwZSA9PT0gJ21vZGVsLWhlYWRlcicpIHtcclxuICAgICAgICAgIGNvbnN0IGRhdGEgPSBmaXJzdEhlYWRlci5kYXRhIGFzIHsgbW9kZWw6IE1vZGVsSXRlbTsgdmVyc2lvbklkOiBzdHJpbmcgfVxyXG4gICAgICAgICAgc3RpY2t5SGVhZGVyLnZhbHVlID0ge1xyXG4gICAgICAgICAgICBtb2RlbDogZGF0YS5tb2RlbCxcclxuICAgICAgICAgICAgdmVyc2lvbklkOiBkYXRhLnZlcnNpb25JZFxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoZmlyc3RIZWFkZXIudHlwZSA9PT0gJ2RldGFjaGVkLW9iamVjdC1oZWFkZXInKSB7XHJcbiAgICAgICAgICBjb25zdCBkYXRhID0gZmlyc3RIZWFkZXIuZGF0YSBhcyB7IG9iamVjdElkOiBzdHJpbmcgfVxyXG4gICAgICAgICAgY29uc3QgZGV0YWNoZWRPYmplY3RIZWFkZXIgPSB7XHJcbiAgICAgICAgICAgIGlkOiBkYXRhLm9iamVjdElkLFxyXG4gICAgICAgICAgICBuYW1lOiAnRGV0YWNoZWQgT2JqZWN0JyxcclxuICAgICAgICAgICAgZGlzcGxheU5hbWU6ICdEZXRhY2hlZCBPYmplY3QnXHJcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgTW9kZWxJdGVtXHJcbiAgICAgICAgICBzdGlja3lIZWFkZXIudmFsdWUgPSB7XHJcbiAgICAgICAgICAgIG1vZGVsOiBkZXRhY2hlZE9iamVjdEhlYWRlcixcclxuICAgICAgICAgICAgdmVyc2lvbklkOiBkYXRhLm9iamVjdElkXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzdGlja3lIZWFkZXIudmFsdWUgPSBudWxsXHJcbiAgICB9XHJcbiAgfSxcclxuICB7IGltbWVkaWF0ZTogdHJ1ZSB9XHJcbilcclxuPC9zY3JpcHQ+XHJcblxyXG48c3R5bGUgc2NvcGVkPlxyXG4vKiBBZGQgYm9yZGVyLXRvcCB0byBtb2RlbC9kZXRhY2hlZCBvYmplY3QgaGVhZGVycyB0aGF0IGZvbGxvdyB0cmVlIGl0ZW1zIHVzaW5nIGNzcyAqL1xyXG4ubW9kZWwtbGlzdFxyXG4gIC5ncm91cFtkYXRhLWl0ZW0tdHlwZT0ndHJlZS1pdGVtJ11cclxuICArIC5ncm91cFtkYXRhLWl0ZW0tdHlwZT0nbW9kZWwtaGVhZGVyJ11cclxuICAubW9kZWwtaGVhZGVyLFxyXG4ubW9kZWwtbGlzdFxyXG4gIC5ncm91cFtkYXRhLWl0ZW0tdHlwZT0ndHJlZS1pdGVtJ11cclxuICArIC5ncm91cFtkYXRhLWl0ZW0tdHlwZT0nZGV0YWNoZWQtb2JqZWN0LWhlYWRlciddXHJcbiAgLm1vZGVsLWhlYWRlciB7XHJcbiAgQGFwcGx5IGJvcmRlci10IGJvcmRlci1vdXRsaW5lLTM7XHJcbn1cclxuPC9zdHlsZT5cclxuIl0sImZpbGUiOiJEOi9zcGVja2xlLXNlcnZlci9wYWNrYWdlcy9mcm9udGVuZC0yL2NvbXBvbmVudHMvdmlld2VyL21vZGVscy9QYW5lbC52dWUifQ==