444 lines
43 KiB
Plaintext
444 lines
43 KiB
Plaintext
import { createHotContext as __vite__createHotContext } from "/_nuxt/@vite/client";import.meta.hot = __vite__createHotContext("/components/viewer/filters/property-selection/Panel.vue");import { default as __nuxt_component_0 } from "/_nuxt/components/viewer/filters/property-selection/Search.vue";
|
|
import { CommonLoadingIcon as __nuxt_component_1 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js";
|
|
import { FormButton as __nuxt_component_2 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js";
|
|
import { default as __nuxt_component_3 } from "/_nuxt/components/viewer/filters/property-selection/Header.vue";
|
|
import { default as __nuxt_component_4 } from "/_nuxt/components/viewer/filters/property-selection/Item.vue";
|
|
/* Injection by vite-plugin-vue-inspector Start */
|
|
import { createVNode as __createVNode,createElementBlock as __createElementBlock,createElementVNode as __createElementVNode,createBlock as __createBlock } 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 _createVNode(...args) { return _interopVNode(__createVNode(...args)) }
|
|
function _createElementBlock(...args) { return _interopVNode(__createElementBlock(...args)) }
|
|
function _createElementVNode(...args) { return _interopVNode(__createElementVNode(...args)) }
|
|
function _createBlock(...args) { return _interopVNode(__createBlock(...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 { useVirtualList, useDebounceFn, onKeyStroke } from "/_nuxt/node_modules/@vueuse/core/index.mjs?v=e4f18c29";
|
|
import {
|
|
FILTERS_POPULAR_PROPERTIES,
|
|
PROPERTY_SELECTION_ITEM_HEIGHT,
|
|
PROPERTY_SELECTION_MAX_HEIGHT,
|
|
PROPERTY_SELECTION_OVERSCAN
|
|
} from "/_nuxt/lib/viewer/helpers/filters/constants.ts";
|
|
import { useFilteringDataStore } from "/_nuxt/lib/viewer/composables/filtering/dataStore.ts";
|
|
|
|
import { ref, computed, nextTick, watch } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
|
|
const _sfc_main = /* @__PURE__ */ _defineComponent({
|
|
__name: "ViewerFiltersPropertySelectionPanel",
|
|
props: {
|
|
options: { type: Array, required: true }
|
|
},
|
|
emits: ["selectProperty", "close"],
|
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
__expose();
|
|
const props = __props;
|
|
const emit = __emit;
|
|
const dataStore = useFilteringDataStore();
|
|
const searchQuery = ref("");
|
|
const listContainer = ref();
|
|
const searchComponent = ref();
|
|
const focusedIndex = ref(-1);
|
|
const debouncedSearchQuery = ref("");
|
|
const updateDebouncedSearch = useDebounceFn((query) => {
|
|
debouncedSearchQuery.value = query;
|
|
}, 200);
|
|
const isLoading = computed(() => {
|
|
return dataStore.dataSources.value.length === 0;
|
|
});
|
|
const optionsWithLowercase = computed(() => {
|
|
return props.options.map((option) => ({
|
|
...option,
|
|
_searchLabel: option.label.toLowerCase(),
|
|
_searchValue: option.value.toLowerCase(),
|
|
_searchParentPath: option.parentPath.toLowerCase(),
|
|
_searchType: option.type.toLowerCase()
|
|
}));
|
|
});
|
|
const filteredOptions = computed(() => {
|
|
if (!debouncedSearchQuery.value.trim()) {
|
|
return props.options;
|
|
}
|
|
const searchTerm = debouncedSearchQuery.value.toLowerCase().trim();
|
|
return optionsWithLowercase.value.filter(
|
|
(option) => option._searchLabel.includes(searchTerm) || option._searchValue.includes(searchTerm) || option._searchParentPath.includes(searchTerm) || option._searchType.includes(searchTerm)
|
|
).map(
|
|
({ _searchLabel, _searchValue, _searchParentPath, _searchType, ...option }) => option
|
|
);
|
|
});
|
|
const listItems = computed(() => {
|
|
const items = [];
|
|
if (debouncedSearchQuery.value.trim()) {
|
|
const searchResults = filteredOptions.value.map((property) => ({
|
|
type: "property",
|
|
property
|
|
}));
|
|
return searchResults;
|
|
}
|
|
const optionsMap = new Map(filteredOptions.value.map((opt) => [opt.value, opt]));
|
|
const availablePopular = FILTERS_POPULAR_PROPERTIES.map(
|
|
(filterKey) => optionsMap.get(filterKey)
|
|
).filter(Boolean).slice(0, 6);
|
|
if (availablePopular.length > 0) {
|
|
items.push({ type: "header", title: "Popular properties" });
|
|
const popularItems = availablePopular.map((property) => ({
|
|
type: "property",
|
|
property
|
|
}));
|
|
items.push(...popularItems);
|
|
}
|
|
items.push({
|
|
type: "header",
|
|
title: `All properties (${filteredOptions.value.length})`
|
|
});
|
|
const allPropertyItems = filteredOptions.value.map((property) => ({
|
|
type: "property",
|
|
property
|
|
}));
|
|
items.push(...allPropertyItems);
|
|
return items;
|
|
});
|
|
const itemHeight = computed(() => PROPERTY_SELECTION_ITEM_HEIGHT);
|
|
const maxHeight = computed(() => PROPERTY_SELECTION_MAX_HEIGHT - 28);
|
|
const { list, containerProps, wrapperProps } = useVirtualList(listItems, {
|
|
itemHeight: PROPERTY_SELECTION_ITEM_HEIGHT,
|
|
overscan: PROPERTY_SELECTION_OVERSCAN
|
|
});
|
|
const hasSearchQuery = computed(() => debouncedSearchQuery.value.trim().length > 0);
|
|
const propertyItems = computed(() => {
|
|
return listItems.value.filter((item) => item.type === "property" && item.property);
|
|
});
|
|
const isItemFocused = (index) => {
|
|
const propertyItemIndex = getPropertyItemIndex(index);
|
|
return propertyItemIndex === focusedIndex.value;
|
|
};
|
|
const getPropertyItemIndex = (virtualIndex) => {
|
|
let propertyIndex = -1;
|
|
for (let i = 0; i <= virtualIndex; i++) {
|
|
const item = listItems.value[i];
|
|
if (item && item.type === "property" && item.property) {
|
|
propertyIndex++;
|
|
}
|
|
}
|
|
return propertyIndex;
|
|
};
|
|
const getVirtualIndex = (propertyIndex) => {
|
|
let currentPropertyIndex = -1;
|
|
for (let i = 0; i < listItems.value.length; i++) {
|
|
const item = listItems.value[i];
|
|
if (item && item.type === "property" && item.property) {
|
|
currentPropertyIndex++;
|
|
if (currentPropertyIndex === propertyIndex) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
const handleSearchKeydown = (event) => {
|
|
switch (event.key) {
|
|
case "ArrowDown":
|
|
event.preventDefault();
|
|
if (propertyItems.value.length > 0) {
|
|
focusedIndex.value = 0;
|
|
scrollToFocusedItem();
|
|
nextTick(() => {
|
|
listContainer.value?.focus();
|
|
});
|
|
}
|
|
break;
|
|
case "Enter":
|
|
event.preventDefault();
|
|
if (focusedIndex.value >= 0 && focusedIndex.value < propertyItems.value.length) {
|
|
const property = propertyItems.value[focusedIndex.value].property;
|
|
if (property) {
|
|
emit("selectProperty", property.value);
|
|
}
|
|
}
|
|
break;
|
|
case "Escape":
|
|
event.preventDefault();
|
|
emit("close");
|
|
break;
|
|
}
|
|
};
|
|
const handleListKeydown = (event) => {
|
|
if (propertyItems.value.length === 0) return;
|
|
switch (event.key) {
|
|
case "ArrowDown":
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
if (focusedIndex.value < propertyItems.value.length - 1) {
|
|
focusedIndex.value++;
|
|
scrollToFocusedItem();
|
|
}
|
|
break;
|
|
case "ArrowUp":
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
if (focusedIndex.value > 0) {
|
|
focusedIndex.value--;
|
|
scrollToFocusedItem();
|
|
}
|
|
break;
|
|
case "Enter":
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
if (focusedIndex.value >= 0 && focusedIndex.value < propertyItems.value.length) {
|
|
const property = propertyItems.value[focusedIndex.value].property;
|
|
if (property) {
|
|
emit("selectProperty", property.value);
|
|
}
|
|
}
|
|
break;
|
|
case "Escape": {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
emit("close");
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
const handleItemHover = (virtualIndex) => {
|
|
const propertyItemIndex = getPropertyItemIndex(virtualIndex);
|
|
if (propertyItemIndex >= 0) {
|
|
focusedIndex.value = propertyItemIndex;
|
|
}
|
|
};
|
|
const scrollToFocusedItem = () => {
|
|
if (focusedIndex.value >= 0) {
|
|
const virtualIndex = getVirtualIndex(focusedIndex.value);
|
|
if (virtualIndex >= 0) {
|
|
nextTick(() => {
|
|
const container = containerProps.ref.value;
|
|
if (container) {
|
|
const containerHeight = container.clientHeight;
|
|
const itemHeight2 = PROPERTY_SELECTION_ITEM_HEIGHT;
|
|
const totalOffset = virtualIndex * itemHeight2;
|
|
const centerOffset = containerHeight / 2 - itemHeight2 / 2;
|
|
const scrollPosition = Math.max(0, totalOffset - centerOffset);
|
|
container.scrollTo({
|
|
top: scrollPosition,
|
|
behavior: "smooth"
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
const resetScrollPosition = () => {
|
|
nextTick(() => {
|
|
const container = containerProps.ref.value;
|
|
if (container) {
|
|
container.scrollTo({
|
|
top: 0,
|
|
behavior: "smooth"
|
|
});
|
|
}
|
|
});
|
|
};
|
|
const clearSearch = () => {
|
|
searchQuery.value = "";
|
|
focusedIndex.value = -1;
|
|
resetScrollPosition();
|
|
};
|
|
watch(
|
|
searchQuery,
|
|
(newQuery) => {
|
|
updateDebouncedSearch(newQuery);
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
watch(listItems, () => {
|
|
focusedIndex.value = -1;
|
|
resetScrollPosition();
|
|
});
|
|
watch(debouncedSearchQuery, () => {
|
|
focusedIndex.value = -1;
|
|
resetScrollPosition();
|
|
});
|
|
onKeyStroke((event) => {
|
|
event.preventDefault();
|
|
if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
const searchInput = document.getElementById("property-search");
|
|
searchInput?.focus();
|
|
}
|
|
});
|
|
const __returned__ = { props, emit, dataStore, searchQuery, listContainer, searchComponent, focusedIndex, debouncedSearchQuery, updateDebouncedSearch, isLoading, optionsWithLowercase, filteredOptions, listItems, itemHeight, maxHeight, list, containerProps, wrapperProps, hasSearchQuery, propertyItems, isItemFocused, getPropertyItemIndex, getVirtualIndex, handleSearchKeydown, handleListKeydown, handleItemHover, scrollToFocusedItem, resetScrollPosition, clearSearch };
|
|
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
|
return __returned__;
|
|
}
|
|
});
|
|
import { resolveComponent as _resolveComponent, openBlock as _openBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, withCtx as _withCtx, Fragment as _Fragment, renderList as _renderList, normalizeStyle as _normalizeStyle, mergeProps as _mergeProps } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
|
|
const _hoisted_1 = {
|
|
key: 0,
|
|
class: "flex-1 flex items-center justify-center py-8",
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:17:5"
|
|
};
|
|
const _hoisted_2 = {
|
|
class: "flex-1 flex flex-col items-center justify-center p-6 gap-2",
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:22:5"
|
|
};
|
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
const _component_ViewerFiltersPropertySelectionSearch = __nuxt_component_0;
|
|
const _component_CommonLoadingIcon = __nuxt_component_1;
|
|
const _component_FormButton = __nuxt_component_2;
|
|
const _component_ViewerFiltersPropertySelectionHeader = __nuxt_component_3;
|
|
const _component_ViewerFiltersPropertySelectionItem = __nuxt_component_4;
|
|
return _openBlock(), _createElementBlock(
|
|
"div",
|
|
{
|
|
ref: "listContainer",
|
|
class: "h-full flex flex-col select-none focus-visible:outline-none border border-outline-2 rounded-lg",
|
|
tabindex: "0",
|
|
role: "listbox",
|
|
onKeydown: $setup.handleListKeydown,
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:2:3"
|
|
},
|
|
[
|
|
_createVNode(_component_ViewerFiltersPropertySelectionSearch, {
|
|
ref: "searchComponent",
|
|
modelValue: $setup.searchQuery,
|
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.searchQuery = $event),
|
|
placeholder: "Search for a property...",
|
|
"input-id": "property-search",
|
|
onKeydown: $setup.handleSearchKeydown,
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:9:5"
|
|
}, null, 8, ["modelValue"]),
|
|
$setup.isLoading ? (_openBlock(), _createElementBlock("div", _hoisted_1, [
|
|
_createVNode(_component_CommonLoadingIcon, {
|
|
class: "h-6 w-6 text-foreground-2",
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:18:7"
|
|
})
|
|
])) : $setup.hasSearchQuery && $setup.filteredOptions.length === 0 ? (_openBlock(), _createElementBlock(
|
|
_Fragment,
|
|
{ key: 1 },
|
|
[
|
|
_createCommentVNode(" Empty state for no search results "),
|
|
_createElementVNode("div", _hoisted_2, [
|
|
_cache[3] || (_cache[3] = _createElementVNode(
|
|
"p",
|
|
{
|
|
class: "text-body-2xs text-center",
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:26:7"
|
|
},
|
|
"No properties found",
|
|
-1
|
|
/* CACHED */
|
|
)),
|
|
_createVNode(_component_FormButton, {
|
|
color: "outline",
|
|
size: "sm",
|
|
onClick: $setup.clearSearch,
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:28:7"
|
|
}, {
|
|
default: _withCtx(() => [..._cache[2] || (_cache[2] = [
|
|
_createTextVNode(
|
|
" Clear search ",
|
|
-1
|
|
/* CACHED */
|
|
)
|
|
])]),
|
|
_: 1
|
|
/* STABLE */
|
|
})
|
|
])
|
|
],
|
|
2112
|
|
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
|
)) : (_openBlock(), _createElementBlock(
|
|
_Fragment,
|
|
{ key: 2 },
|
|
[
|
|
_createCommentVNode(" Property list "),
|
|
_createElementVNode(
|
|
"div",
|
|
_mergeProps($setup.containerProps, {
|
|
class: "simple-scrollbar py-1",
|
|
style: { maxHeight: `${$setup.maxHeight}px` },
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:34:5"
|
|
}),
|
|
[
|
|
_createElementVNode(
|
|
"div",
|
|
_mergeProps($setup.wrapperProps, {
|
|
class: "relative",
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:40:7"
|
|
}),
|
|
[
|
|
(_openBlock(true), _createElementBlock(
|
|
_Fragment,
|
|
null,
|
|
_renderList($setup.list, ({ data: item, index }) => {
|
|
return _openBlock(), _createElementBlock(
|
|
"div",
|
|
{
|
|
key: index,
|
|
style: _normalizeStyle({
|
|
height: `${$setup.itemHeight}px`,
|
|
overflow: "hidden"
|
|
}),
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:41:9"
|
|
},
|
|
[
|
|
item.type === "header" ? (_openBlock(), _createBlock(_component_ViewerFiltersPropertySelectionHeader, {
|
|
key: 0,
|
|
title: item.title,
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:49:11"
|
|
}, null, 8, ["title"])) : item.type === "property" && item.property ? (_openBlock(), _createBlock(_component_ViewerFiltersPropertySelectionItem, {
|
|
key: 1,
|
|
property: item.property,
|
|
"is-focused": $setup.isItemFocused(index),
|
|
onSelectProperty: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("selectProperty", $event)),
|
|
onMouseenter: ($event) => $setup.handleItemHover(index),
|
|
onFocus: ($event) => $setup.handleItemHover(index),
|
|
"data-v-inspector": "components/viewer/filters/property-selection/Panel.vue:54:11"
|
|
}, null, 8, ["property", "is-focused", "onMouseenter", "onFocus"])) : _createCommentVNode("v-if", true)
|
|
],
|
|
4
|
|
/* STYLE */
|
|
);
|
|
}),
|
|
128
|
|
/* KEYED_FRAGMENT */
|
|
))
|
|
],
|
|
16
|
|
/* FULL_PROPS */
|
|
)
|
|
],
|
|
16
|
|
/* FULL_PROPS */
|
|
)
|
|
],
|
|
2112
|
|
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
|
))
|
|
],
|
|
544
|
|
/* NEED_HYDRATION, NEED_PATCH */
|
|
);
|
|
}
|
|
_sfc_main.__hmrId = "59d339f1";
|
|
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/filters/property-selection/Panel.vue"]]);
|
|
|
|
//# sourceMappingURL=data:application/json;base64,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QjtBQUFBLG9EQUkzQixLQUFLLFNBQUksY0FBbUIsS0FBSywwQkFEOUMsYUFPRTtBQUFBOzRCQUxDLFVBQVUsS0FBSztBQUFBLDRCQUNmLGNBQVkscUJBQWMsS0FBSztBQUFBLDRCQUMvQixrQkFBZSxzQ0FBRSxXQUFLLGtCQUFtQixNQUFNO0FBQUEsNEJBQy9DLGNBQVUsWUFBRSx1QkFBZ0IsS0FBSztBQUFBLDRCQUNqQyxTQUFLLFlBQUUsdUJBQWdCLEtBQUs7QUFBQSw0QkFBRyxvQkFBaUI7QUFBQSIsIm5hbWVzIjpbIml0ZW1IZWlnaHQiXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsiUGFuZWwudnVlIl0sInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cclxuICA8ZGl2XHJcbiAgICByZWY9XCJsaXN0Q29udGFpbmVyXCJcclxuICAgIGNsYXNzPVwiaC1mdWxsIGZsZXggZmxleC1jb2wgc2VsZWN0LW5vbmUgZm9jdXMtdmlzaWJsZTpvdXRsaW5lLW5vbmUgYm9yZGVyIGJvcmRlci1vdXRsaW5lLTIgcm91bmRlZC1sZ1wiXHJcbiAgICB0YWJpbmRleD1cIjBcIlxyXG4gICAgcm9sZT1cImxpc3Rib3hcIlxyXG4gICAgQGtleWRvd249XCJoYW5kbGVMaXN0S2V5ZG93blwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6MjozXCJcclxuICA+XHJcbiAgICA8Vmlld2VyRmlsdGVyc1Byb3BlcnR5U2VsZWN0aW9uU2VhcmNoXHJcbiAgICAgIHJlZj1cInNlYXJjaENvbXBvbmVudFwiXHJcbiAgICAgIHYtbW9kZWw9XCJzZWFyY2hRdWVyeVwiXHJcbiAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGZvciBhIHByb3BlcnR5Li4uXCJcclxuICAgICAgaW5wdXQtaWQ9XCJwcm9wZXJ0eS1zZWFyY2hcIlxyXG4gICAgICBAa2V5ZG93bj1cImhhbmRsZVNlYXJjaEtleWRvd25cIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZmlsdGVycy9wcm9wZXJ0eS1zZWxlY3Rpb24vUGFuZWwudnVlOjk6NVwiXHJcbiAgICAvPlxyXG5cclxuICAgIDxkaXYgdi1pZj1cImlzTG9hZGluZ1wiIGNsYXNzPVwiZmxleC0xIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHB5LThcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZmlsdGVycy9wcm9wZXJ0eS1zZWxlY3Rpb24vUGFuZWwudnVlOjE3OjVcIj5cclxuICAgICAgPENvbW1vbkxvYWRpbmdJY29uIGNsYXNzPVwiaC02IHctNiB0ZXh0LWZvcmVncm91bmQtMlwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6MTg6N1wiIC8+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIEVtcHR5IHN0YXRlIGZvciBubyBzZWFyY2ggcmVzdWx0cyAtLT5cclxuICAgIDxkaXZcclxuICAgICAgdi1lbHNlLWlmPVwiaGFzU2VhcmNoUXVlcnkgJiYgZmlsdGVyZWRPcHRpb25zLmxlbmd0aCA9PT0gMFwiXHJcbiAgICAgIGNsYXNzPVwiZmxleC0xIGZsZXggZmxleC1jb2wgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHAtNiBnYXAtMlwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6MjI6NVwiXHJcbiAgICA+XHJcbiAgICAgIDxwIGNsYXNzPVwidGV4dC1ib2R5LTJ4cyB0ZXh0LWNlbnRlclwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6MjY6N1wiPk5vIHByb3BlcnRpZXMgZm91bmQ8L3A+XHJcblxyXG4gICAgICA8Rm9ybUJ1dHRvbiBjb2xvcj1cIm91dGxpbmVcIiBzaXplPVwic21cIiBAY2xpY2s9XCJjbGVhclNlYXJjaFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6Mjg6N1wiPlxyXG4gICAgICAgIENsZWFyIHNlYXJjaFxyXG4gICAgICA8L0Zvcm1CdXR0b24+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIFByb3BlcnR5IGxpc3QgLS0+XHJcbiAgICA8ZGl2XHJcbiAgICAgIHYtZWxzZVxyXG4gICAgICB2LWJpbmQ9XCJjb250YWluZXJQcm9wc1wiXHJcbiAgICAgIGNsYXNzPVwic2ltcGxlLXNjcm9sbGJhciBweS0xXCJcclxuICAgICAgOnN0eWxlPVwieyBtYXhIZWlnaHQ6IGAke21heEhlaWdodH1weGAgfVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6MzQ6NVwiXHJcbiAgICA+XHJcbiAgICAgIDxkaXYgdi1iaW5kPVwid3JhcHBlclByb3BzXCIgY2xhc3M9XCJyZWxhdGl2ZVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6NDA6N1wiPlxyXG4gICAgICAgIDxkaXZcclxuICAgICAgICAgIHYtZm9yPVwieyBkYXRhOiBpdGVtLCBpbmRleCB9IGluIGxpc3RcIlxyXG4gICAgICAgICAgOmtleT1cImluZGV4XCJcclxuICAgICAgICAgIDpzdHlsZT1cIntcclxuICAgICAgICAgICAgaGVpZ2h0OiBgJHtpdGVtSGVpZ2h0fXB4YCxcclxuICAgICAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nXHJcbiAgICAgICAgICB9XCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2ZpbHRlcnMvcHJvcGVydHktc2VsZWN0aW9uL1BhbmVsLnZ1ZTo0MTo5XCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8Vmlld2VyRmlsdGVyc1Byb3BlcnR5U2VsZWN0aW9uSGVhZGVyXHJcbiAgICAgICAgICAgIHYtaWY9XCJpdGVtLnR5cGUgPT09ICdoZWFkZXInXCJcclxuICAgICAgICAgICAgOnRpdGxlPVwiaXRlbS50aXRsZSFcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZmlsdGVycy9wcm9wZXJ0eS1zZWxlY3Rpb24vUGFuZWwudnVlOjQ5OjExXCJcclxuICAgICAgICAgIC8+XHJcblxyXG4gICAgICAgICAgPFZpZXdlckZpbHRlcnNQcm9wZXJ0eVNlbGVjdGlvbkl0ZW1cclxuICAgICAgICAgICAgdi1lbHNlLWlmPVwiaXRlbS50eXBlID09PSAncHJvcGVydHknICYmIGl0ZW0ucHJvcGVydHlcIlxyXG4gICAgICAgICAgICA6cHJvcGVydHk9XCJpdGVtLnByb3BlcnR5XCJcclxuICAgICAgICAgICAgOmlzLWZvY3VzZWQ9XCJpc0l0ZW1Gb2N1c2VkKGluZGV4KVwiXHJcbiAgICAgICAgICAgIEBzZWxlY3QtcHJvcGVydHk9XCIkZW1pdCgnc2VsZWN0UHJvcGVydHknLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgQG1vdXNlZW50ZXI9XCJoYW5kbGVJdGVtSG92ZXIoaW5kZXgpXCJcclxuICAgICAgICAgICAgQGZvY3VzPVwiaGFuZGxlSXRlbUhvdmVyKGluZGV4KVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9maWx0ZXJzL3Byb3BlcnR5LXNlbGVjdGlvbi9QYW5lbC52dWU6NTQ6MTFcIlxyXG4gICAgICAgICAgLz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC90ZW1wbGF0ZT5cclxuXHJcbjxzY3JpcHQgc2V0dXAgbGFuZz1cInRzXCI+XHJcbmltcG9ydCB7IHVzZVZpcnR1YWxMaXN0LCB1c2VEZWJvdW5jZUZuLCBvbktleVN0cm9rZSB9IGZyb20gJ0B2dWV1c2UvY29yZSdcclxuaW1wb3J0IHR5cGUge1xyXG4gIFByb3BlcnR5T3B0aW9uLFxyXG4gIFByb3BlcnR5U2VsZWN0aW9uTGlzdEl0ZW1cclxufSBmcm9tICd+L2xpYi92aWV3ZXIvaGVscGVycy9maWx0ZXJzL3R5cGVzJ1xyXG5pbXBvcnQge1xyXG4gIEZJTFRFUlNfUE9QVUxBUl9QUk9QRVJUSUVTLFxyXG4gIFBST1BFUlRZX1NFTEVDVElPTl9JVEVNX0hFSUdIVCxcclxuICBQUk9QRVJUWV9TRUxFQ1RJT05fTUFYX0hFSUdIVCxcclxuICBQUk9QRVJUWV9TRUxFQ1RJT05fT1ZFUlNDQU5cclxufSBmcm9tICd+L2xpYi92aWV3ZXIvaGVscGVycy9maWx0ZXJzL2NvbnN0YW50cydcclxuaW1wb3J0IHsgdXNlRmlsdGVyaW5nRGF0YVN0b3JlIH0gZnJvbSAnfi9saWIvdmlld2VyL2NvbXBvc2FibGVzL2ZpbHRlcmluZy9kYXRhU3RvcmUnXHJcblxyXG5jb25zdCBwcm9wcyA9IGRlZmluZVByb3BzPHtcclxuICBvcHRpb25zOiBQcm9wZXJ0eU9wdGlvbltdXHJcbn0+KClcclxuXHJcbmNvbnN0IGVtaXQgPSBkZWZpbmVFbWl0czx7XHJcbiAgc2VsZWN0UHJvcGVydHk6IFtwcm9wZXJ0eUtleTogc3RyaW5nXVxyXG4gIGNsb3NlOiBbXVxyXG59PigpXHJcblxyXG5jb25zdCBkYXRhU3RvcmUgPSB1c2VGaWx0ZXJpbmdEYXRhU3RvcmUoKVxyXG5cclxuY29uc3Qgc2VhcmNoUXVlcnkgPSByZWYoJycpXHJcbmNvbnN0IGxpc3RDb250YWluZXIgPSByZWY8SFRNTEVsZW1lbnQ+KClcclxuY29uc3Qgc2VhcmNoQ29tcG9uZW50ID0gcmVmKClcclxuY29uc3QgZm9jdXNlZEluZGV4ID0gcmVmKC0xKVxyXG5jb25zdCBkZWJvdW5jZWRTZWFyY2hRdWVyeSA9IHJlZignJylcclxuXHJcbmNvbnN0IHVwZGF0ZURlYm91bmNlZFNlYXJjaCA9IHVzZURlYm91bmNlRm4oKHF1ZXJ5OiBzdHJpbmcpID0+IHtcclxuICBkZWJvdW5jZWRTZWFyY2hRdWVyeS52YWx1ZSA9IHF1ZXJ5XHJcbn0sIDIwMClcclxuXHJcbmNvbnN0IGlzTG9hZGluZyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICByZXR1cm4gZGF0YVN0b3JlLmRhdGFTb3VyY2VzLnZhbHVlLmxlbmd0aCA9PT0gMFxyXG59KVxyXG5cclxuY29uc3Qgb3B0aW9uc1dpdGhMb3dlcmNhc2UgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgcmV0dXJuIHByb3BzLm9wdGlvbnMubWFwKChvcHRpb24pID0+ICh7XHJcbiAgICAuLi5vcHRpb24sXHJcbiAgICBfc2VhcmNoTGFiZWw6IG9wdGlvbi5sYWJlbC50b0xvd2VyQ2FzZSgpLFxyXG4gICAgX3NlYXJjaFZhbHVlOiBvcHRpb24udmFsdWUudG9Mb3dlckNhc2UoKSxcclxuICAgIF9zZWFyY2hQYXJlbnRQYXRoOiBvcHRpb24ucGFyZW50UGF0aC50b0xvd2VyQ2FzZSgpLFxyXG4gICAgX3NlYXJjaFR5cGU6IG9wdGlvbi50eXBlLnRvTG93ZXJDYXNlKClcclxuICB9KSlcclxufSlcclxuXHJcbmNvbnN0IGZpbHRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICBpZiAoIWRlYm91bmNlZFNlYXJjaFF1ZXJ5LnZhbHVlLnRyaW0oKSkge1xyXG4gICAgcmV0dXJuIHByb3BzLm9wdGlvbnNcclxuICB9XHJcblxyXG4gIGNvbnN0IHNlYXJjaFRlcm0gPSBkZWJvdW5jZWRTZWFyY2hRdWVyeS52YWx1ZS50b0xvd2VyQ2FzZSgpLnRyaW0oKVxyXG4gIHJldHVybiBvcHRpb25zV2l0aExvd2VyY2FzZS52YWx1ZVxyXG4gICAgLmZpbHRlcihcclxuICAgICAgKG9wdGlvbikgPT5cclxuICAgICAgICBvcHRpb24uX3NlYXJjaExhYmVsLmluY2x1ZGVzKHNlYXJjaFRlcm0pIHx8XHJcbiAgICAgICAgb3B0aW9uLl9zZWFyY2hWYWx1ZS5pbmNsdWRlcyhzZWFyY2hUZXJtKSB8fFxyXG4gICAgICAgIG9wdGlvbi5fc2VhcmNoUGFyZW50UGF0aC5pbmNsdWRlcyhzZWFyY2hUZXJtKSB8fFxyXG4gICAgICAgIG9wdGlvbi5fc2VhcmNoVHlwZS5pbmNsdWRlcyhzZWFyY2hUZXJtKVxyXG4gICAgKVxyXG4gICAgLm1hcChcclxuICAgICAgKHsgX3NlYXJjaExhYmVsLCBfc2VhcmNoVmFsdWUsIF9zZWFyY2hQYXJlbnRQYXRoLCBfc2VhcmNoVHlwZSwgLi4ub3B0aW9uIH0pID0+XHJcbiAgICAgICAgb3B0aW9uXHJcbiAgICApXHJcbn0pXHJcblxyXG5jb25zdCBsaXN0SXRlbXMgPSBjb21wdXRlZCgoKTogUHJvcGVydHlTZWxlY3Rpb25MaXN0SXRlbVtdID0+IHtcclxuICBjb25zdCBpdGVtczogUHJvcGVydHlTZWxlY3Rpb25MaXN0SXRlbVtdID0gW11cclxuXHJcbiAgaWYgKGRlYm91bmNlZFNlYXJjaFF1ZXJ5LnZhbHVlLnRyaW0oKSkge1xyXG4gICAgY29uc3Qgc2VhcmNoUmVzdWx0cyA9IGZpbHRlcmVkT3B0aW9ucy52YWx1ZS5tYXAoKHByb3BlcnR5KSA9PiAoe1xyXG4gICAgICB0eXBlOiAncHJvcGVydHknIGFzIGNvbnN0LFxyXG4gICAgICBwcm9wZXJ0eVxyXG4gICAgfSkpXHJcbiAgICByZXR1cm4gc2VhcmNoUmVzdWx0c1xyXG4gIH1cclxuXHJcbiAgY29uc3Qgb3B0aW9uc01hcCA9IG5ldyBNYXAoZmlsdGVyZWRPcHRpb25zLnZhbHVlLm1hcCgob3B0KSA9PiBbb3B0LnZhbHVlLCBvcHRdKSlcclxuICBjb25zdCBhdmFpbGFibGVQb3B1bGFyID0gRklMVEVSU19QT1BVTEFSX1BST1BFUlRJRVMubWFwKChmaWx0ZXJLZXkpID0+XHJcbiAgICBvcHRpb25zTWFwLmdldChmaWx0ZXJLZXkpXHJcbiAgKVxyXG4gICAgLmZpbHRlcihCb29sZWFuKVxyXG4gICAgLnNsaWNlKDAsIDYpIC8vIFNob3cgbWF4IDYgcG9wdWxhciBmaWx0ZXJzXHJcblxyXG4gIGlmIChhdmFpbGFibGVQb3B1bGFyLmxlbmd0aCA+IDApIHtcclxuICAgIGl0ZW1zLnB1c2goeyB0eXBlOiAnaGVhZGVyJywgdGl0bGU6ICdQb3B1bGFyIHByb3BlcnRpZXMnIH0pXHJcbiAgICBjb25zdCBwb3B1bGFySXRlbXMgPSBhdmFpbGFibGVQb3B1bGFyLm1hcCgocHJvcGVydHkpID0+ICh7XHJcbiAgICAgIHR5cGU6ICdwcm9wZXJ0eScgYXMgY29uc3QsXHJcbiAgICAgIHByb3BlcnR5OiBwcm9wZXJ0eSFcclxuICAgIH0pKVxyXG4gICAgaXRlbXMucHVzaCguLi5wb3B1bGFySXRlbXMpXHJcbiAgfVxyXG5cclxuICBpdGVtcy5wdXNoKHtcclxuICAgIHR5cGU6ICdoZWFkZXInLFxyXG4gICAgdGl0bGU6IGBBbGwgcHJvcGVydGllcyAoJHtmaWx0ZXJlZE9wdGlvbnMudmFsdWUubGVuZ3RofSlgXHJcbiAgfSlcclxuXHJcbiAgY29uc3QgYWxsUHJvcGVydHlJdGVtcyA9IGZpbHRlcmVkT3B0aW9ucy52YWx1ZS5tYXAoKHByb3BlcnR5KSA9PiAoe1xyXG4gICAgdHlwZTogJ3Byb3BlcnR5JyBhcyBjb25zdCxcclxuICAgIHByb3BlcnR5XHJcbiAgfSkpXHJcbiAgaXRlbXMucHVzaCguLi5hbGxQcm9wZXJ0eUl0ZW1zKVxyXG5cclxuICByZXR1cm4gaXRlbXNcclxufSlcclxuXHJcbmNvbnN0IGl0ZW1IZWlnaHQgPSBjb21wdXRlZCgoKSA9PiBQUk9QRVJUWV9TRUxFQ1RJT05fSVRFTV9IRUlHSFQpXHJcbmNvbnN0IG1heEhlaWdodCA9IGNvbXB1dGVkKCgpID0+IFBST1BFUlRZX1NFTEVDVElPTl9NQVhfSEVJR0hUIC0gMjgpXHJcblxyXG5jb25zdCB7IGxpc3QsIGNvbnRhaW5lclByb3BzLCB3cmFwcGVyUHJvcHMgfSA9IHVzZVZpcnR1YWxMaXN0KGxpc3RJdGVtcywge1xyXG4gIGl0ZW1IZWlnaHQ6IFBST1BFUlRZX1NFTEVDVElPTl9JVEVNX0hFSUdIVCxcclxuICBvdmVyc2NhbjogUFJPUEVSVFlfU0VMRUNUSU9OX09WRVJTQ0FOXHJcbn0pXHJcblxyXG5jb25zdCBoYXNTZWFyY2hRdWVyeSA9IGNvbXB1dGVkKCgpID0+IGRlYm91bmNlZFNlYXJjaFF1ZXJ5LnZhbHVlLnRyaW0oKS5sZW5ndGggPiAwKVxyXG5cclxuY29uc3QgcHJvcGVydHlJdGVtcyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICByZXR1cm4gbGlzdEl0ZW1zLnZhbHVlLmZpbHRlcigoaXRlbSkgPT4gaXRlbS50eXBlID09PSAncHJvcGVydHknICYmIGl0ZW0ucHJvcGVydHkpXHJcbn0pXHJcblxyXG5jb25zdCBpc0l0ZW1Gb2N1c2VkID0gKGluZGV4OiBudW1iZXIpID0+IHtcclxuICBjb25zdCBwcm9wZXJ0eUl0ZW1JbmRleCA9IGdldFByb3BlcnR5SXRlbUluZGV4KGluZGV4KVxyXG4gIHJldHVybiBwcm9wZXJ0eUl0ZW1JbmRleCA9PT0gZm9jdXNlZEluZGV4LnZhbHVlXHJcbn1cclxuXHJcbmNvbnN0IGdldFByb3BlcnR5SXRlbUluZGV4ID0gKHZpcnR1YWxJbmRleDogbnVtYmVyKSA9PiB7XHJcbiAgbGV0IHByb3BlcnR5SW5kZXggPSAtMVxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDw9IHZpcnR1YWxJbmRleDsgaSsrKSB7XHJcbiAgICBjb25zdCBpdGVtID0gbGlzdEl0ZW1zLnZhbHVlW2ldXHJcbiAgICBpZiAoaXRlbSAmJiBpdGVtLnR5cGUgPT09ICdwcm9wZXJ0eScgJiYgaXRlbS5wcm9wZXJ0eSkge1xyXG4gICAgICBwcm9wZXJ0eUluZGV4KytcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHByb3BlcnR5SW5kZXhcclxufVxyXG5cclxuY29uc3QgZ2V0VmlydHVhbEluZGV4ID0gKHByb3BlcnR5SW5kZXg6IG51bWJlcikgPT4ge1xyXG4gIGxldCBjdXJyZW50UHJvcGVydHlJbmRleCA9IC0xXHJcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaXN0SXRlbXMudmFsdWUubGVuZ3RoOyBpKyspIHtcclxuICAgIGNvbnN0IGl0ZW0gPSBsaXN0SXRlbXMudmFsdWVbaV1cclxuICAgIGlmIChpdGVtICYmIGl0ZW0udHlwZSA9PT0gJ3Byb3BlcnR5JyAmJiBpdGVtLnByb3BlcnR5KSB7XHJcbiAgICAgIGN1cnJlbnRQcm9wZXJ0eUluZGV4KytcclxuICAgICAgaWYgKGN1cnJlbnRQcm9wZXJ0eUluZGV4ID09PSBwcm9wZXJ0eUluZGV4KSB7XHJcbiAgICAgICAgcmV0dXJuIGlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gLTFcclxufVxyXG5cclxuLy8gSGFuZGxlIGtleWJvYXJkIGV2ZW50cyBmcm9tIHNlYXJjaCBpbnB1dFxyXG5jb25zdCBoYW5kbGVTZWFyY2hLZXlkb3duID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XHJcbiAgc3dpdGNoIChldmVudC5rZXkpIHtcclxuICAgIGNhc2UgJ0Fycm93RG93bic6XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcclxuICAgICAgaWYgKHByb3BlcnR5SXRlbXMudmFsdWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGZvY3VzZWRJbmRleC52YWx1ZSA9IDBcclxuICAgICAgICBzY3JvbGxUb0ZvY3VzZWRJdGVtKClcclxuICAgICAgICBuZXh0VGljaygoKSA9PiB7XHJcbiAgICAgICAgICBsaXN0Q29udGFpbmVyLnZhbHVlPy5mb2N1cygpXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgICBicmVha1xyXG4gICAgY2FzZSAnRW50ZXInOlxyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXHJcbiAgICAgIGlmIChmb2N1c2VkSW5kZXgudmFsdWUgPj0gMCAmJiBmb2N1c2VkSW5kZXgudmFsdWUgPCBwcm9wZXJ0eUl0ZW1zLnZhbHVlLmxlbmd0aCkge1xyXG4gICAgICAgIGNvbnN0IHByb3BlcnR5ID0gcHJvcGVydHlJdGVtcy52YWx1ZVtmb2N1c2VkSW5kZXgudmFsdWVdLnByb3BlcnR5XHJcbiAgICAgICAgaWYgKHByb3BlcnR5KSB7XHJcbiAgICAgICAgICBlbWl0KCdzZWxlY3RQcm9wZXJ0eScsIHByb3BlcnR5LnZhbHVlKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBicmVha1xyXG4gICAgY2FzZSAnRXNjYXBlJzpcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gICAgICBlbWl0KCdjbG9zZScpXHJcbiAgICAgIGJyZWFrXHJcbiAgfVxyXG59XHJcblxyXG5jb25zdCBoYW5kbGVMaXN0S2V5ZG93biA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xyXG4gIGlmIChwcm9wZXJ0eUl0ZW1zLnZhbHVlLmxlbmd0aCA9PT0gMCkgcmV0dXJuXHJcblxyXG4gIHN3aXRjaCAoZXZlbnQua2V5KSB7XHJcbiAgICBjYXNlICdBcnJvd0Rvd24nOlxyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXHJcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXHJcbiAgICAgIGlmIChmb2N1c2VkSW5kZXgudmFsdWUgPCBwcm9wZXJ0eUl0ZW1zLnZhbHVlLmxlbmd0aCAtIDEpIHtcclxuICAgICAgICBmb2N1c2VkSW5kZXgudmFsdWUrK1xyXG4gICAgICAgIHNjcm9sbFRvRm9jdXNlZEl0ZW0oKVxyXG4gICAgICB9XHJcbiAgICAgIGJyZWFrXHJcbiAgICBjYXNlICdBcnJvd1VwJzpcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKVxyXG4gICAgICBpZiAoZm9jdXNlZEluZGV4LnZhbHVlID4gMCkge1xyXG4gICAgICAgIGZvY3VzZWRJbmRleC52YWx1ZS0tXHJcbiAgICAgICAgc2Nyb2xsVG9Gb2N1c2VkSXRlbSgpXHJcbiAgICAgIH1cclxuICAgICAgYnJlYWtcclxuICAgIGNhc2UgJ0VudGVyJzpcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gICAgICBpZiAoZm9jdXNlZEluZGV4LnZhbHVlID49IDAgJiYgZm9jdXNlZEluZGV4LnZhbHVlIDwgcHJvcGVydHlJdGVtcy52YWx1ZS5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBwcm9wZXJ0eSA9IHByb3BlcnR5SXRlbXMudmFsdWVbZm9jdXNlZEluZGV4LnZhbHVlXS5wcm9wZXJ0eVxyXG4gICAgICAgIGlmIChwcm9wZXJ0eSkge1xyXG4gICAgICAgICAgZW1pdCgnc2VsZWN0UHJvcGVydHknLCBwcm9wZXJ0eS52YWx1ZSlcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgYnJlYWtcclxuICAgIGNhc2UgJ0VzY2FwZSc6IHtcclxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gICAgICBlbWl0KCdjbG9zZScpXHJcbiAgICAgIGJyZWFrXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG4vLyBIYW5kbGUgaXRlbSBob3ZlciB0byB1cGRhdGUgZm9jdXNlZCBpbmRleFxyXG5jb25zdCBoYW5kbGVJdGVtSG92ZXIgPSAodmlydHVhbEluZGV4OiBudW1iZXIpID0+IHtcclxuICBjb25zdCBwcm9wZXJ0eUl0ZW1JbmRleCA9IGdldFByb3BlcnR5SXRlbUluZGV4KHZpcnR1YWxJbmRleClcclxuICBpZiAocHJvcGVydHlJdGVtSW5kZXggPj0gMCkge1xyXG4gICAgZm9jdXNlZEluZGV4LnZhbHVlID0gcHJvcGVydHlJdGVtSW5kZXhcclxuICB9XHJcbn1cclxuXHJcbmNvbnN0IHNjcm9sbFRvRm9jdXNlZEl0ZW0gPSAoKSA9PiB7XHJcbiAgaWYgKGZvY3VzZWRJbmRleC52YWx1ZSA+PSAwKSB7XHJcbiAgICBjb25zdCB2aXJ0dWFsSW5kZXggPSBnZXRWaXJ0dWFsSW5kZXgoZm9jdXNlZEluZGV4LnZhbHVlKVxyXG4gICAgaWYgKHZpcnR1YWxJbmRleCA+PSAwKSB7XHJcbiAgICAgIG5leHRUaWNrKCgpID0+IHtcclxuICAgICAgICBjb25zdCBjb250YWluZXIgPSBjb250YWluZXJQcm9wcy5yZWYudmFsdWVcclxuICAgICAgICBpZiAoY29udGFpbmVyKSB7XHJcbiAgICAgICAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0XHJcbiAgICAgICAgICBjb25zdCBpdGVtSGVpZ2h0ID0gUFJPUEVSVFlfU0VMRUNUSU9OX0lURU1fSEVJR0hUXHJcbiAgICAgICAgICBjb25zdCB0b3RhbE9mZnNldCA9IHZpcnR1YWxJbmRleCAqIGl0ZW1IZWlnaHRcclxuICAgICAgICAgIGNvbnN0IGNlbnRlck9mZnNldCA9IGNvbnRhaW5lckhlaWdodCAvIDIgLSBpdGVtSGVpZ2h0IC8gMlxyXG4gICAgICAgICAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSBNYXRoLm1heCgwLCB0b3RhbE9mZnNldCAtIGNlbnRlck9mZnNldClcclxuXHJcbiAgICAgICAgICBjb250YWluZXIuc2Nyb2xsVG8oe1xyXG4gICAgICAgICAgICB0b3A6IHNjcm9sbFBvc2l0aW9uLFxyXG4gICAgICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8gUmVzZXQgc2Nyb2xsIHBvc2l0aW9uIHRvIHRvcCB3aGVuIHNlYXJjaCByZXN1bHRzIGNoYW5nZVxyXG5jb25zdCByZXNldFNjcm9sbFBvc2l0aW9uID0gKCkgPT4ge1xyXG4gIG5leHRUaWNrKCgpID0+IHtcclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGNvbnRhaW5lclByb3BzLnJlZi52YWx1ZVxyXG4gICAgaWYgKGNvbnRhaW5lcikge1xyXG4gICAgICBjb250YWluZXIuc2Nyb2xsVG8oe1xyXG4gICAgICAgIHRvcDogMCxcclxuICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcclxuICAgICAgfSlcclxuICAgIH1cclxuICB9KVxyXG59XHJcblxyXG5jb25zdCBjbGVhclNlYXJjaCA9ICgpID0+IHtcclxuICBzZWFyY2hRdWVyeS52YWx1ZSA9ICcnXHJcbiAgZm9jdXNlZEluZGV4LnZhbHVlID0gLTFcclxuICByZXNldFNjcm9sbFBvc2l0aW9uKClcclxufVxyXG5cclxud2F0Y2goXHJcbiAgc2VhcmNoUXVlcnksXHJcbiAgKG5ld1F1ZXJ5KSA9PiB7XHJcbiAgICB1cGRhdGVEZWJvdW5jZWRTZWFyY2gobmV3UXVlcnkpXHJcbiAgfSxcclxuICB7IGltbWVkaWF0ZTogdHJ1ZSB9XHJcbilcclxuXHJcbi8vIFJlc2V0IGZvY3VzZWQgaW5kZXggYW5kIHNjcm9sbCBwb3NpdGlvbiB3aGVuIGxpc3QgY2hhbmdlc1xyXG53YXRjaChsaXN0SXRlbXMsICgpID0+IHtcclxuICBmb2N1c2VkSW5kZXgudmFsdWUgPSAtMVxyXG4gIHJlc2V0U2Nyb2xsUG9zaXRpb24oKVxyXG59KVxyXG5cclxuLy8gUmVzZXQgZm9jdXNlZCBpbmRleCBhbmQgc2Nyb2xsIHBvc2l0aW9uIHdoZW4gc2VhcmNoIGNoYW5nZXNcclxud2F0Y2goZGVib3VuY2VkU2VhcmNoUXVlcnksICgpID0+IHtcclxuICBmb2N1c2VkSW5kZXgudmFsdWUgPSAtMVxyXG4gIHJlc2V0U2Nyb2xsUG9zaXRpb24oKVxyXG59KVxyXG5cclxuLy8gSGFuZGxlIHR5cGluZyB0byBmb2N1cyBzZWFyY2ggaW5wdXRcclxub25LZXlTdHJva2UoKGV2ZW50KSA9PiB7XHJcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKVxyXG4gIGlmIChldmVudC5rZXkubGVuZ3RoID09PSAxICYmICFldmVudC5jdHJsS2V5ICYmICFldmVudC5tZXRhS2V5ICYmICFldmVudC5hbHRLZXkpIHtcclxuICAgIGNvbnN0IHNlYXJjaElucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Byb3BlcnR5LXNlYXJjaCcpIGFzIEhUTUxJbnB1dEVsZW1lbnRcclxuICAgIHNlYXJjaElucHV0Py5mb2N1cygpXHJcbiAgfVxyXG59KVxyXG48L3NjcmlwdD5cclxuIl0sImZpbGUiOiJEOi9zcGVja2xlLXNlcnZlci9wYWNrYWdlcy9mcm9udGVuZC0yL2NvbXBvbmVudHMvdmlld2VyL2ZpbHRlcnMvcHJvcGVydHktc2VsZWN0aW9uL1BhbmVsLnZ1ZSJ9 |