react-native-scroll-to-child
Version:
Scroll a ScrollView's child into the visible viewport
381 lines (373 loc) • 62.2 kB
JavaScript
import React, { forwardRef, useRef, useCallback, useEffect, useContext, useImperativeHandle } from 'react';
import { View, Animated, findNodeHandle, UIManager, Platform } from 'react-native';
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// src/compute-scroll.tsx
var computeScrollY = /* @__PURE__ */ __name((scrollViewLayout, viewLayout, scrollY, insets, align) => {
const { height: scrollViewHeight, y: scrollViewY } = scrollViewLayout;
const { height: childHeight, y: viewY } = viewLayout;
const viewTopY = viewY - scrollViewY;
const viewBottomY = viewTopY + childHeight;
const computationData = { scrollViewHeight, scrollY, viewTopY, viewBottomY, insets };
const computeFn = alignmentsY[align];
if (!computeFn) throw new Error(`align=${align} not supported`);
return computeFn(computationData);
}, "computeScrollY");
var computeScrollYAuto = /* @__PURE__ */ __name((data) => {
const { scrollY } = data;
const scrollYTop = computeScrollYStart(data);
if (scrollY > scrollYTop) {
return scrollYTop;
}
const scrollYBottom = computeScrollYEnd(data);
if (scrollY < scrollYBottom) {
return scrollYBottom;
}
return scrollY;
}, "computeScrollYAuto");
var computeScrollYStart = /* @__PURE__ */ __name(({ scrollY, viewTopY, insets }) => {
return scrollY + viewTopY - (insets.top || 0);
}, "computeScrollYStart");
var computeScrollYEnd = /* @__PURE__ */ __name(({ scrollViewHeight, scrollY, viewBottomY, insets }) => {
return scrollY + viewBottomY - scrollViewHeight + (insets.bottom || 0);
}, "computeScrollYEnd");
var computeScrollYCenter = /* @__PURE__ */ __name((data) => {
return (computeScrollYStart(data) + computeScrollYEnd(data)) / 2;
}, "computeScrollYCenter");
var alignmentsY = {
auto: computeScrollYAuto,
start: computeScrollYStart,
end: computeScrollYEnd,
center: computeScrollYCenter
};
var computeScrollX = /* @__PURE__ */ __name((scrollViewLayout, viewLayout, scrollX, insets, align) => {
const { width: scrollViewWidth, x: scrollViewX } = scrollViewLayout;
const { width: childWidth, x: viewX } = viewLayout;
const viewLeftX = viewX - scrollViewX;
const viewRightX = viewLeftX + childWidth;
const computationData = { scrollViewWidth, scrollX, viewLeftX, viewRightX, insets };
const computeFn = alignmentsX[align];
if (!computeFn) throw new Error(`align=${align} not supported for horizontal scrolling`);
return computeFn(computationData);
}, "computeScrollX");
var computeScrollXAuto = /* @__PURE__ */ __name((data) => {
const { scrollX } = data;
const scrollXLeft = computeScrollXStart(data);
if (scrollX > scrollXLeft) {
return scrollXLeft;
}
const scrollXRight = computeScrollXEnd(data);
if (scrollX < scrollXRight) {
return scrollXRight;
}
return scrollX;
}, "computeScrollXAuto");
var computeScrollXStart = /* @__PURE__ */ __name(({ scrollX, viewLeftX, insets }) => {
return scrollX + viewLeftX - (insets.left || 0);
}, "computeScrollXStart");
var computeScrollXEnd = /* @__PURE__ */ __name(({ scrollViewWidth, scrollX, viewRightX, insets }) => {
return scrollX + viewRightX - scrollViewWidth + (insets.right || 0);
}, "computeScrollXEnd");
var computeScrollXCenter = /* @__PURE__ */ __name((data) => {
return (computeScrollXStart(data) + computeScrollXEnd(data)) / 2;
}, "computeScrollXCenter");
var alignmentsX = {
auto: computeScrollXAuto,
start: computeScrollXStart,
end: computeScrollXEnd,
center: computeScrollXCenter
};
var measureElement = /* @__PURE__ */ __name((element) => {
const node = findNodeHandle(element);
if (!node) return Promise.reject(new Error("Unable to find node handle"));
return new Promise((resolve) => {
UIManager.measureInWindow(node, (x, y, width, height) => resolve({ x, y, width, height }));
});
}, "measureElement");
var throttle = /* @__PURE__ */ __name((func, limit) => {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}, "throttle");
// src/config.tsx
var DefaultOptions = {
align: "auto",
animated: true,
immediate: false,
insets: {
top: 0,
bottom: 0,
left: 0,
right: 0
},
computeScrollY,
computeScrollX,
measureElement
};
var normalizeOptions = /* @__PURE__ */ __name((options = {}, fallbackOptions = DefaultOptions) => ({
...fallbackOptions,
...options,
insets: {
...fallbackOptions.insets,
...options.insets
}
}), "normalizeOptions");
var DefaultHOCConfig = {
// The method to extract the raw ScrollView node from the ref we got, if it's not directly the ScrollView itself
getScrollViewNode: /* @__PURE__ */ __name((scrollView) => {
const rnVersion = Platform.constants.reactNativeVersion;
const isPreRN062 = rnVersion ? rnVersion.major === 0 && rnVersion.minor < 62 : false;
if (typeof scrollView.getNode === "function" && isPreRN062) {
return scrollView.getNode();
}
return scrollView;
}, "getScrollViewNode"),
// Default value for throttling, can be overridden by user with props
scrollEventThrottle: 16,
// ScrollIntoView options, can be offered by <ScrollIntoView /> comp or imperative usage
options: DefaultOptions
};
var normalizeHOCConfig = /* @__PURE__ */ __name((config = {}) => ({
...DefaultHOCConfig,
...config,
options: normalizeOptions(config.options, DefaultOptions)
}), "normalizeHOCConfig");
// src/api.tsx
var scrollIntoView = /* @__PURE__ */ __name(async (scrollView, view, scrollY, scrollX, options) => {
if (!scrollView || !view) {
throw new Error("ScrollView and target View must be provided");
}
const { align, animated, computeScrollY: computeScrollY2, computeScrollX: computeScrollX2, measureElement: measureElement2, insets } = normalizeOptions(options);
try {
const [scrollViewLayout, viewLayout] = await Promise.all([measureElement2(scrollView), measureElement2(view)]);
const targetScrollY = computeScrollY2(scrollViewLayout, viewLayout, scrollY, insets, align);
const targetScrollX = computeScrollX2(scrollViewLayout, viewLayout, scrollX, insets, align);
const scrollParams = { x: targetScrollX, y: targetScrollY, animated };
const scrollResponder = scrollView.getScrollResponder();
if (scrollResponder.scrollResponderScrollTo) {
scrollResponder.scrollResponderScrollTo(scrollParams);
} else {
scrollView.scrollTo(scrollParams);
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Unknown error";
throw new Error(`Failed to scroll into view: ${errorMessage}`);
}
}, "scrollIntoView");
var _ScrollIntoViewAPI = class _ScrollIntoViewAPI {
constructor(dependencies) {
this.dependencies = dependencies;
this.validateDependencies(dependencies);
}
validateDependencies(deps) {
const requiredDepKeys = [
"getScrollView",
"getScrollY",
"getScrollX",
"getDefaultOptions"
];
for (const key of requiredDepKeys) {
if (typeof deps[key] !== "function") {
throw new Error(`Dependency "${key}" must be a function.`);
}
}
}
getNormalizedOptions = /* @__PURE__ */ __name((options = {}) => normalizeOptions(options, this.dependencies.getDefaultOptions()), "getNormalizedOptions");
scrollIntoView = /* @__PURE__ */ __name((view, options) => {
const normalizedOptions = this.getNormalizedOptions(options);
return normalizedOptions.immediate ? this.scrollIntoViewImmediate(view, normalizedOptions) : this.scrollIntoViewThrottled(view, normalizedOptions);
}, "scrollIntoView");
performScroll = /* @__PURE__ */ __name((view, options) => {
return scrollIntoView(
this.dependencies.getScrollView(),
view,
this.dependencies.getScrollY(),
this.dependencies.getScrollX(),
options
);
}, "performScroll");
scrollIntoViewThrottled = throttle(this.performScroll, 16);
scrollIntoViewImmediate = this.performScroll;
};
__name(_ScrollIntoViewAPI, "ScrollIntoViewAPI");
var ScrollIntoViewAPI = _ScrollIntoViewAPI;
// src/context.tsx
var Context = React.createContext(null);
var context_default = Context;
var APIConsumer = Context.Consumer;
var ProvideAPI = /* @__PURE__ */ __name(({ dependencies, children }) => {
const api = React.useMemo(() => new ScrollIntoViewAPI(dependencies), [dependencies]);
return /* @__PURE__ */ React.createElement(Context.Provider, { value: api }, children);
}, "ProvideAPI");
// src/container.tsx
var showNotInContextWarning = throttle(() => {
console.warn(
"ScrollIntoView API is not provided in React context. Make sure you wrapped your ScrollView component with wrapScrollView(ScrollView)"
);
}, 5e3);
var ContainerBase = forwardRef((props, ref) => {
const {
enabled = true,
onMount = true,
onUpdate = true,
scrollIntoViewKey,
scrollIntoViewOptions,
scrollIntoViewAPI,
children,
align,
animated,
immediate,
insets,
measureElement: measureElement2,
computeScrollY: computeScrollY2,
computeScrollX: computeScrollX2,
...rest
} = props;
const containerRef = useRef(null);
const unmounted = useRef(false);
const prevProps = useRef({ enabled, scrollIntoViewKey });
const ensureApiProvided = useCallback(() => {
if (!scrollIntoViewAPI) {
showNotInContextWarning();
return false;
}
return true;
}, [scrollIntoViewAPI]);
const getPropsOptions = useCallback(() => {
const COMPONENT_DEFAULT_ANIMATED = true;
const COMPONENT_DEFAULT_IMMEDIATE = false;
const mergedOptions = {
animated: COMPONENT_DEFAULT_ANIMATED,
immediate: COMPONENT_DEFAULT_IMMEDIATE,
...scrollIntoViewOptions
};
const optionProps = [
"animated",
"immediate",
"align",
"insets",
"measureElement",
"computeScrollY",
"computeScrollX"
];
const propsToMerge = {
animated,
immediate,
align,
insets,
measureElement: measureElement2,
computeScrollY: computeScrollY2,
computeScrollX: computeScrollX2
};
for (const key of optionProps) {
if (propsToMerge[key] !== void 0) {
mergedOptions[key] = propsToMerge[key];
}
}
return mergedOptions;
}, [scrollIntoViewOptions, animated, immediate, align, insets, measureElement2, computeScrollY2, computeScrollX2]);
const scrollIntoView2 = useCallback(
(providedOptions = {}) => {
if (unmounted.current || !ensureApiProvided()) return;
const currentContainerRef = containerRef.current;
if (!currentContainerRef) return;
const options = { ...getPropsOptions(), ...providedOptions };
if (scrollIntoViewAPI) {
scrollIntoViewAPI.scrollIntoView(currentContainerRef, options);
}
},
[ensureApiProvided, getPropsOptions, scrollIntoViewAPI]
);
useEffect(() => {
let timerId;
if (onMount && enabled) {
timerId = setTimeout(() => {
if (!unmounted.current) {
scrollIntoView2();
}
}, 0);
}
return () => {
if (timerId) {
clearTimeout(timerId);
}
};
}, [enabled, onMount, scrollIntoView2]);
useEffect(() => {
const prevEnabled = prevProps.current.enabled;
const prevKey = prevProps.current.scrollIntoViewKey;
const needsUpdateScroll = onUpdate && enabled && (!prevEnabled || scrollIntoViewKey !== prevKey);
if (needsUpdateScroll) {
scrollIntoView2();
}
if (prevEnabled !== enabled || prevKey !== scrollIntoViewKey) {
prevProps.current = { enabled, scrollIntoViewKey };
}
}, [enabled, onUpdate, scrollIntoViewKey, scrollIntoView2]);
useEffect(() => {
return () => {
unmounted.current = true;
};
}, []);
return /* @__PURE__ */ React.createElement(View, { ...rest, ref: ref || containerRef, collapsable: false }, children);
});
ContainerBase.displayName = "ContainerBase";
var Container = forwardRef((props, ref) => /* @__PURE__ */ React.createElement(APIConsumer, null, (apiFromContext) => apiFromContext && /* @__PURE__ */ React.createElement(ContainerBase, { ref, ...props, scrollIntoViewAPI: apiFromContext })));
var wrapScrollViewHOC = /* @__PURE__ */ __name((ScrollViewComp, config = {}) => {
const { getScrollViewNode, scrollEventThrottle, options } = normalizeHOCConfig(config);
const ScrollViewWrapper = forwardRef((props, ref) => {
var _a, _b;
const internalRef = useRef(null);
const scrollY = useRef(((_a = props.contentOffset) == null ? void 0 : _a.y) || 0);
const scrollX = useRef(((_b = props.contentOffset) == null ? void 0 : _b.x) || 0);
const handleScroll = useCallback((event) => {
scrollY.current = event.nativeEvent.contentOffset.y;
scrollX.current = event.nativeEvent.contentOffset.x;
}, []);
const dependencies = {
getScrollView: /* @__PURE__ */ __name(() => {
if (!internalRef.current) throw new Error("ScrollView ref is not set");
return getScrollViewNode(internalRef.current);
}, "getScrollView"),
getScrollY: /* @__PURE__ */ __name(() => scrollY.current, "getScrollY"),
getScrollX: /* @__PURE__ */ __name(() => scrollX.current, "getScrollX"),
getDefaultOptions: /* @__PURE__ */ __name(() => normalizeOptions(props.scrollIntoViewOptions, options), "getDefaultOptions")
};
useImperativeHandle(ref, () => internalRef.current, []);
const scrollViewProps = {
...props,
ref: internalRef,
scrollEventThrottle: props.scrollEventThrottle || scrollEventThrottle,
onScroll: Animated.forkEvent(props.onScroll, handleScroll)
};
return /* @__PURE__ */ React.createElement(ScrollViewComp, { ...scrollViewProps }, /* @__PURE__ */ React.createElement(ProvideAPI, { dependencies }, props.children));
});
ScrollViewWrapper.displayName = `ScrollIntoViewWrapper(${ScrollViewComp.displayName || ScrollViewComp.name || "Component"})`;
return ScrollViewWrapper;
}, "wrapScrollViewHOC");
function useScrollIntoViewContext() {
const value = useContext(context_default);
if (value === null) {
throw new Error(
"ScrollIntoView context is missing. Ensure your ScrollView is wrapped with wrapScrollView() and is an ancestor in the component tree."
);
}
return value;
}
__name(useScrollIntoViewContext, "useScrollIntoViewContext");
function useScrollIntoView() {
const { scrollIntoView: scrollIntoView2 } = useScrollIntoViewContext();
return scrollIntoView2;
}
__name(useScrollIntoView, "useScrollIntoView");
// src/index.ts
var ScrollIntoView = Container;
var wrapScrollView = /* @__PURE__ */ __name((comp, config) => wrapScrollViewHOC(comp, config), "wrapScrollView");
export { ScrollIntoView, useScrollIntoView, wrapScrollView };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wdXRlLXNjcm9sbC50c3giLCIuLi9zcmMvdXRpbHMudHN4IiwiLi4vc3JjL2NvbmZpZy50c3giLCIuLi9zcmMvYXBpLnRzeCIsIi4uL3NyYy9jb250ZXh0LnRzeCIsIi4uL3NyYy9jb250YWluZXIudHN4IiwiLi4vc3JjL2hvYy50c3giLCIuLi9zcmMvaG9va3MudHN4IiwiLi4vc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbImNvbXB1dGVTY3JvbGxZIiwiY29tcHV0ZVNjcm9sbFgiLCJtZWFzdXJlRWxlbWVudCIsInNjcm9sbEludG9WaWV3IiwiUmVhY3QiLCJmb3J3YXJkUmVmIiwidXNlUmVmIiwidXNlQ2FsbGJhY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFXTyxJQUFNLGlDQUFpQixNQUFBLENBQUEsQ0FDMUIsZ0JBQUEsRUFDQSxVQUFBLEVBQ0EsT0FBQSxFQUNBLFFBQ0EsS0FBQSxLQUNDO0FBQ0QsRUFBQSxNQUFNLEVBQUUsTUFBQSxFQUFRLGdCQUFBLEVBQWtCLENBQUEsRUFBRyxhQUFZLEdBQUksZ0JBQUE7QUFDckQsRUFBQSxNQUFNLEVBQUUsTUFBQSxFQUFRLFdBQUEsRUFBYSxDQUFBLEVBQUcsT0FBTSxHQUFJLFVBQUE7QUFFMUMsRUFBQSxNQUFNLFdBQVcsS0FBQSxHQUFRLFdBQUE7QUFDekIsRUFBQSxNQUFNLGNBQWMsUUFBQSxHQUFXLFdBQUE7QUFFL0IsRUFBQSxNQUFNLGtCQUFrQixFQUFFLGdCQUFBLEVBQWtCLE9BQUEsRUFBUyxRQUFBLEVBQVUsYUFBYSxNQUFBLEVBQU87QUFFbkYsRUFBQSxNQUFNLFNBQUEsR0FBWSxZQUFZLEtBQUssQ0FBQTtBQUNuQyxFQUFBLElBQUksQ0FBRSxTQUFBLEVBQW1CLE1BQU0sSUFBSSxLQUFBLENBQU0sQ0FBQSxNQUFBLEVBQVMsS0FBSyxDQUFBLGNBQUEsQ0FBZ0IsQ0FBQTtBQUV2RSxFQUFBLE9BQU8sVUFBVSxlQUFlLENBQUE7QUFDcEMsQ0FBQSxFQW5COEIsZ0JBQUEsQ0FB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QUEsQ0FBQTs7O0FDUlQsSUFBTSxjQUFBLEdBQWlCO0FBRXZCLElBQU0saUNBQWlCLE1BQUEsQ0FBQSxDQUFDLElBQUEsRUFBMkIsV0FBOEIsaUJBQUEsQ0FBa0IsSUFBQSxFQUFNLE1BQU0sQ0FBQSxFQUF4RixnQkFBQSIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQWxpZ24sIEluc2V0cyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB0eXBlIHsgTGF5b3V0UmVjdGFuZ2xlIH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxudHlwZSBDb21wdXRhdGlvbkRhdGEgPSB7XG4gICAgc2Nyb2xsVmlld0hlaWdodDogbnVtYmVyO1xuICAgIHNjcm9sbFk6IG51bWJlcjtcbiAgICB2aWV3VG9wWTogbnVtYmVyO1xuICAgIHZpZXdCb3R0b21ZOiBudW1iZXI7XG4gICAgaW5zZXRzOiBJbnNldHM7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFkgPSAoXG4gICAgc2Nyb2xsVmlld0xheW91dDogTGF5b3V0UmVjdGFuZ2xlLFxuICAgIHZpZXdMYXlvdXQ6IExheW91dFJlY3RhbmdsZSxcbiAgICBzY3JvbGxZOiBudW1iZXIsXG4gICAgaW5zZXRzOiBJbnNldHMsXG4gICAgYWxpZ246IEFsaWduXG4pID0+IHtcbiAgICBjb25zdCB7IGhlaWdodDogc2Nyb2xsVmlld0hlaWdodCwgeTogc2Nyb2xsVmlld1kgfSA9IHNjcm9sbFZpZXdMYXlvdXQ7XG4gICAgY29uc3QgeyBoZWlnaHQ6IGNoaWxkSGVpZ2h0LCB5OiB2aWV3WSB9ID0gdmlld0xheW91dDtcblxuICAgIGNvbnN0IHZpZXdUb3BZID0gdmlld1kgLSBzY3JvbGxWaWV3WTtcbiAgICBjb25zdCB2aWV3Qm90dG9tWSA9IHZpZXdUb3BZICsgY2hpbGRIZWlnaHQ7XG5cbiAgICBjb25zdCBjb21wdXRhdGlvbkRhdGEgPSB7IHNjcm9sbFZpZXdIZWlnaHQsIHNjcm9sbFksIHZpZXdUb3BZLCB2aWV3Qm90dG9tWSwgaW5zZXRzIH07XG5cbiAgICBjb25zdCBjb21wdXRlRm4gPSBhbGlnbm1lbnRzWVthbGlnbl07XG4gICAgaWYgKCEoY29tcHV0ZUZuIGFzIGFueSkpIHRocm93IG5ldyBFcnJvcihgYWxpZ249JHthbGlnbn0gbm90IHN1cHBvcnRlZGApO1xuXG4gICAgcmV0dXJuIGNvbXB1dGVGbihjb21wdXRhdGlvbkRhdGEpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxZQXV0byA9IChkYXRhOiBDb21wdXRhdGlvbkRhdGEpOiBudW1iZXIgPT4ge1xuICAgIGNvbnN0IHsgc2Nyb2xsWSB9ID0gZGF0YTtcbiAgICBjb25zdCBzY3JvbGxZVG9wID0gY29tcHV0ZVNjcm9sbFlTdGFydChkYXRhKTtcbiAgICBpZiAoc2Nyb2xsWSA+IHNjcm9sbFlUb3ApIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbFlUb3A7XG4gICAgfVxuICAgIGNvbnN0IHNjcm9sbFlCb3R0b20gPSBjb21wdXRlU2Nyb2xsWUVuZChkYXRhKTtcbiAgICBpZiAoc2Nyb2xsWSA8IHNjcm9sbFlCb3R0b20pIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbFlCb3R0b207XG4gICAgfVxuICAgIHJldHVybiBzY3JvbGxZO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxZU3RhcnQgPSAoeyBzY3JvbGxZLCB2aWV3VG9wWSwgaW5zZXRzIH06IENvbXB1dGF0aW9uRGF0YSk6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIHNjcm9sbFkgKyB2aWV3VG9wWSAtIChpbnNldHMudG9wIHx8IDApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxZRW5kID0gKHsgc2Nyb2xsVmlld0hlaWdodCwgc2Nyb2xsWSwgdmlld0JvdHRvbVksIGluc2V0cyB9OiBDb21wdXRhdGlvbkRhdGEpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiBzY3JvbGxZICsgdmlld0JvdHRvbVkgLSBzY3JvbGxWaWV3SGVpZ2h0ICsgKGluc2V0cy5ib3R0b20gfHwgMCk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFlDZW50ZXIgPSAoZGF0YTogQ29tcHV0YXRpb25EYXRhKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gKGNvbXB1dGVTY3JvbGxZU3RhcnQoZGF0YSkgKyBjb21wdXRlU2Nyb2xsWUVuZChkYXRhKSkgLyAyO1xufTtcblxuY29uc3QgYWxpZ25tZW50c1k6IFJlY29yZDxBbGlnbiwgKGRhdGE6IENvbXB1dGF0aW9uRGF0YSkgPT4gbnVtYmVyPiA9IHtcbiAgICBhdXRvOiBjb21wdXRlU2Nyb2xsWUF1dG8sXG4gICAgc3RhcnQ6IGNvbXB1dGVTY3JvbGxZU3RhcnQsXG4gICAgZW5kOiBjb21wdXRlU2Nyb2xsWUVuZCxcbiAgICBjZW50ZXI6IGNvbXB1dGVTY3JvbGxZQ2VudGVyXG59O1xuXG50eXBlIENvbXB1dGF0aW9uRGF0YVggPSB7XG4gICAgc2Nyb2xsVmlld1dpZHRoOiBudW1iZXI7XG4gICAgc2Nyb2xsWDogbnVtYmVyO1xuICAgIHZpZXdMZWZ0WDogbnVtYmVyO1xuICAgIHZpZXdSaWdodFg6IG51bWJlcjtcbiAgICBpbnNldHM6IEluc2V0cztcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWCA9IChcbiAgICBzY3JvbGxWaWV3TGF5b3V0OiBMYXlvdXRSZWN0YW5nbGUsXG4gICAgdmlld0xheW91dDogTGF5b3V0UmVjdGFuZ2xlLFxuICAgIHNjcm9sbFg6IG51bWJlcixcbiAgICBpbnNldHM6IEluc2V0cyxcbiAgICBhbGlnbjogQWxpZ25cbik6IG51bWJlciA9PiB7XG4gICAgY29uc3QgeyB3aWR0aDogc2Nyb2xsVmlld1dpZHRoLCB4OiBzY3JvbGxWaWV3WCB9ID0gc2Nyb2xsVmlld0xheW91dDtcbiAgICBjb25zdCB7IHdpZHRoOiBjaGlsZFdpZHRoLCB4OiB2aWV3WCB9ID0gdmlld0xheW91dDtcblxuICAgIGNvbnN0IHZpZXdMZWZ0WCA9IHZpZXdYIC0gc2Nyb2xsVmlld1g7XG4gICAgY29uc3Qgdmlld1JpZ2h0WCA9IHZpZXdMZWZ0WCArIGNoaWxkV2lkdGg7XG5cbiAgICBjb25zdCBjb21wdXRhdGlvbkRhdGE6IENvbXB1dGF0aW9uRGF0YVggPSB7IHNjcm9sbFZpZXdXaWR0aCwgc2Nyb2xsWCwgdmlld0xlZnRYLCB2aWV3UmlnaHRYLCBpbnNldHMgfTtcblxuICAgIGNvbnN0IGNvbXB1dGVGbiA9IGFsaWdubWVudHNYW2FsaWduXTtcbiAgICBpZiAoIShjb21wdXRlRm4gYXMgYW55KSkgdGhyb3cgbmV3IEVycm9yKGBhbGlnbj0ke2FsaWdufSBub3Qgc3VwcG9ydGVkIGZvciBob3Jpem9udGFsIHNjcm9sbGluZ2ApO1xuXG4gICAgcmV0dXJuIGNvbXB1dGVGbihjb21wdXRhdGlvbkRhdGEpO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxYQXV0byA9IChkYXRhOiBDb21wdXRhdGlvbkRhdGFYKTogbnVtYmVyID0+IHtcbiAgICBjb25zdCB7IHNjcm9sbFggfSA9IGRhdGE7XG4gICAgY29uc3Qgc2Nyb2xsWExlZnQgPSBjb21wdXRlU2Nyb2xsWFN0YXJ0KGRhdGEpO1xuICAgIGlmIChzY3JvbGxYID4gc2Nyb2xsWExlZnQpIHtcbiAgICAgICAgcmV0dXJuIHNjcm9sbFhMZWZ0O1xuICAgIH1cbiAgICBjb25zdCBzY3JvbGxYUmlnaHQgPSBjb21wdXRlU2Nyb2xsWEVuZChkYXRhKTtcbiAgICBpZiAoc2Nyb2xsWCA8IHNjcm9sbFhSaWdodCkge1xuICAgICAgICByZXR1cm4gc2Nyb2xsWFJpZ2h0O1xuICAgIH1cbiAgICByZXR1cm4gc2Nyb2xsWDtcbn07XG5cbmV4cG9ydCBjb25zdCBjb21wdXRlU2Nyb2xsWFN0YXJ0ID0gKHsgc2Nyb2xsWCwgdmlld0xlZnRYLCBpbnNldHMgfTogQ29tcHV0YXRpb25EYXRhWCk6IG51bWJlciA9PiB7XG4gICAgcmV0dXJuIHNjcm9sbFggKyB2aWV3TGVmdFggLSAoaW5zZXRzLmxlZnQgfHwgMCk7XG59O1xuXG5leHBvcnQgY29uc3QgY29tcHV0ZVNjcm9sbFhFbmQgPSAoeyBzY3JvbGxWaWV3V2lkdGgsIHNjcm9sbFgsIHZpZXdSaWdodFgsIGluc2V0cyB9OiBDb21wdXRhdGlvbkRhdGFYKTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gc2Nyb2xsWCArIHZpZXdSaWdodFggLSBzY3JvbGxWaWV3V2lkdGggKyAoaW5zZXRzLnJpZ2h0IHx8IDApO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXB1dGVTY3JvbGxYQ2VudGVyID0gKGRhdGE6IENvbXB1dGF0aW9uRGF0YVgpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiAoY29tcHV0ZVNjcm9sbFhTdGFydChkYXRhKSArIGNvbXB1dGVTY3JvbGxYRW5kKGRhdGEpKSAvIDI7XG59O1xuXG5jb25zdCBhbGlnbm1lbnRzWDogUmVjb3JkPEFsaWduLCAoZGF0YTogQ29tcHV0YXRpb25EYXRhWCkgPT4gbnVtYmVyPiA9IHtcbiAgICBhdXRvOiBjb21wdXRlU2Nyb2xsWEF1dG8sXG4gICAgc3RhcnQ6IGNvbXB1dGVTY3JvbGxYU3RhcnQsXG4gICAgZW5kOiBjb21wdXRlU2Nyb2xsWEVuZCxcbiAgICBjZW50ZXI6IGNvbXB1dGVTY3JvbGxYQ2VudGVyXG59O1xuIiwiaW1wb3J0IHsgZmluZE5vZGVIYW5kbGUsIFVJTWFuYWdlciB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbmltcG9ydCB0eXBlIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB0eXBlIHsgTGF5b3V0UmVjdGFuZ2xlIH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxudHlwZSBGaW5kTm9kZUhhbmRsZUFyZyA9IG51bGwgfCBudW1iZXIgfCBSZWFjdC5Db21wb25lbnQ8YW55LCBhbnk+IHwgUmVhY3QuQ29tcG9uZW50Q2xhc3M8YW55PjtcblxuZXhwb3J0IGNvbnN0IG1lYXN1cmVFbGVtZW50ID0gKGVsZW1lbnQ6IEZpbmROb2RlSGFuZGxlQXJnKTogUHJvbWlzZTxMYXlvdXRSZWN0YW5nbGU+ID0+IHtcbiAgICBjb25zdCBub2RlID0gZmluZE5vZGVIYW5kbGUoZWxlbWVudCk7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIGhhbmRsZScpKTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxMYXlvdXRSZWN0YW5nbGU+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgIFVJTWFuYWdlci5tZWFzdXJlSW5XaW5kb3cobm9kZSwgKHgsIHksIHdpZHRoLCBoZWlnaHQpID0+IHJlc29sdmUoeyB4LCB5LCB3aWR0aCwgaGVpZ2h0IH0pKTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCB0aHJvdHRsZSA9IDxUIGV4dGVuZHMgKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkPihmdW5jOiBULCBsaW1pdDogbnVtYmVyKTogVCA9PiB7XG4gICAgbGV0IGluVGhyb3R0bGUgPSBmYWxzZTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRoaXM6IHVua25vd24sIC4uLmFyZ3M6IFBhcmFtZXRlcnM8VD4pIHtcbiAgICAgICAgaWYgKCFpblRocm90dGxlKSB7XG4gICAgICAgICAgICBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgaW5UaHJvdHRsZSA9IHRydWU7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IChpblRocm90dGxlID0gZmFsc2UpLCBsaW1pdCk7XG4gICAgICAgIH1cbiAgICB9IGFzIFQ7XG59O1xuIiwiaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdyZWFjdC1uYXRpdmUnO1xuXG5pbXBvcnQgeyBjb21wdXRlU2Nyb2xsWCwgY29tcHV0ZVNjcm9sbFkgfSBmcm9tICcuL2NvbXB1dGUtc2Nyb2xsJztcbmltcG9ydCB7IG1lYXN1cmVFbGVtZW50IH0gZnJvbSAnLi91dGlscyc7XG5cbmltcG9ydCB0eXBlIHsgU2Nyb2xsVmlldyB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbmV4cG9ydCB0eXBlIEluc2V0cyA9IHtcbiAgICB0b3A/OiBudW1iZXI7XG4gICAgYm90dG9tPzogbnVtYmVyO1xuICAgIGxlZnQ/OiBudW1iZXI7XG4gICAgcmlnaHQ/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBBbGlnbiA9ICdhdXRvJyB8ICdzdGFydCcgfCAnZW5kJyB8ICdjZW50ZXInO1xuXG5leHBvcnQgdHlwZSBGdWxsT3B0aW9ucyA9IHtcbiAgICBhbGlnbjogQWxpZ247XG4gICAgYW5pbWF0ZWQ6IGJvb2xlYW47XG4gICAgaW1tZWRpYXRlOiBib29sZWFuO1xuICAgIGluc2V0czogSW5zZXRzO1xuICAgIGNvbXB1dGVTY3JvbGxZOiB0eXBlb2YgY29tcHV0ZVNjcm9sbFk7XG4gICAgY29tcHV0ZVNjcm9sbFg6IHR5cGVvZiBjb21wdXRlU2Nyb2xsWDtcbiAgICBtZWFzdXJlRWxlbWVudDogdHlwZW9mIG1lYXN1cmVFbGVtZW50O1xufTtcblxuZXhwb3J0IHR5cGUgUGFydGlhbE9wdGlvbnMgPSBQYXJ0aWFsPEZ1bGxPcHRpb25zPjtcblxuZXhwb3J0IGNvbnN0IERlZmF1bHRPcHRpb25zOiBGdWxsT3B0aW9ucyA9IHtcbiAgICBhbGlnbjogJ2F1dG8nLFxuICAgIGFuaW1hdGVkOiB0cnVlLFxuICAgIGltbWVkaWF0ZTogZmFsc2UsXG4gICAgaW5zZXRzOiB7XG4gICAgICAgIHRvcDogMCxcbiAgICAgICAgYm90dG9tOiAwLFxuICAgICAgICBsZWZ0OiAwLFxuICAgICAgICByaWdodDogMFxuICAgIH0sXG4gICAgY29tcHV0ZVNjcm9sbFksXG4gICAgY29tcHV0ZVNjcm9sbFgsXG4gICAgbWVhc3VyZUVsZW1lbnRcbn07XG5cbmV4cG9ydCB0eXBlIE9wdGlvbktleSA9IGtleW9mIEZ1bGxPcHRpb25zO1xuZXhwb3J0IGNvbnN0IE9wdGlvbktleXM6IE9wdGlvbktleVtdID0gT2JqZWN0LmtleXMoRGVmYXVsdE9wdGlvbnMpIGFzIE9wdGlvbktleVtdO1xuXG5leHBvcnQgY29uc3Qgbm9ybWFsaXplT3B0aW9ucyA9IChvcHRpb25zOiBQYXJ0aWFsT3B0aW9ucyA9IHt9LCBmYWxsYmFja09wdGlvbnM6IEZ1bGxPcHRpb25zID0gRGVmYXVsdE9wdGlvbnMpID0+ICh7XG4gICAgLi4uZmFsbGJhY2tPcHRpb25zLFxuICAgIC4uLm9wdGlvbnMsXG4gICAgaW5zZXRzOiB7XG4gICAgICAgIC4uLmZhbGxiYWNrT3B0aW9ucy5pbnNldHMsXG4gICAgICAgIC4uLm9wdGlvbnMuaW5zZXRzXG4gICAgfVxufSk7XG5cbmV4cG9ydCB0eXBlIEZ1bGxIT0NDb25maWcgPSB7XG4gICAgZ2V0U2Nyb2xsVmlld05vZGU6IChzY3JvbGxWaWV3OiBTY3JvbGxWaWV3KSA9PiBTY3JvbGxWaWV3O1xuICAgIHNjcm9sbEV2ZW50VGhyb3R0bGU6IDE2O1xuICAgIG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zO1xufTtcbmV4cG9ydCB0eXBlIFBhcnRpYWxIT0NDb25maWcgPSBQYXJ0aWFsPEZ1bGxIT0NDb25maWc+O1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdEhPQ0NvbmZpZzogRnVsbEhPQ0NvbmZpZyA9IHtcbiAgICAvLyBUaGUgbWV0aG9kIHRvIGV4dHJhY3QgdGhlIHJhdyBTY3JvbGxWaWV3IG5vZGUgZnJvbSB0aGUgcmVmIHdlIGdvdCwgaWYgaXQncyBub3QgZGlyZWN0bHkgdGhlIFNjcm9sbFZpZXcgaXRzZWxmXG4gICAgZ2V0U2Nyb2xsVmlld05vZGU6IChzY3JvbGxWaWV3OiBTY3JvbGxWaWV3KSA9PiB7XG4gICAgICAgIC8vIHNjcm9sbFZpZXcuZ2V0Tm9kZSgpIHdhcyB1c2VkIGZvciBBbmltYXRlZC5TY3JvbGxWaWV3IGNvbXBvbmVudHMgYnV0IGlzIGRlcHJlY2F0ZWQgc2luY2UgUk4gMC42Mi5cbiAgICAgICAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QtbmF0aXZlL2NvbW1pdC82NmU3MmJiNGUwMGFhZmJjYjlmNDUwZWQ1ZGIyNjFkOThmOTlmODJhXG4gICAgICAgIC8vIFdlIG9ubHkgYXR0ZW1wdCB0byBjYWxsIGl0IGlmIGl0IGV4aXN0cyBhbmQgd2UncmUgb24gYW4gb2xkZXIgUk4gdmVyc2lvbi5cbiAgICAgICAgY29uc3Qgcm5WZXJzaW9uID0gUGxhdGZvcm0uY29uc3RhbnRzLnJlYWN0TmF0aXZlVmVyc2lvbjtcbiAgICAgICAgY29uc3QgaXNQcmVSTjA2MiA9IChyblZlcnNpb24gYXMgYW55KSA/IHJuVmVyc2lvbi5tYWpvciA9PT0gMCAmJiByblZlcnNpb24ubWlub3IgPCA2MiA6IGZhbHNlO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIGdldE5vZGUgZXhpc3RzIG9uIHRoZSBzY3JvbGxWaWV3IG9iamVjdCAoY29tbW9uIGZvciBBbmltYXRlZC5TY3JvbGxWaWV3KVxuICAgICAgICAvLyBhbmQgaWYgd2UgYXJlIG9uIGEgUmVhY3QgTmF0aXZlIHZlcnNpb24gd2hlcmUgaXQgd2FzIHJlY29tbWVuZGVkLlxuICAgICAgICBpZiAodHlwZW9mIChzY3JvbGxWaWV3IGFzIGFueSkuZ2V0Tm9kZSA9PT0gJ2Z1bmN0aW9uJyAmJiBpc1ByZVJOMDYyKSB7XG4gICAgICAgICAgICByZXR1cm4gKHNjcm9sbFZpZXcgYXMgYW55KS5nZXROb2RlKCk7IC8vIENhbGwgZ2V0Tm9kZSBpZiBhcHBsaWNhYmxlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNjcm9sbFZpZXc7IC8vIE90aGVyd2lzZSwgcmV0dXJuIHRoZSBzY3JvbGxWaWV3IGRpcmVjdGx5XG4gICAgfSxcbiAgICAvLyBEZWZhdWx0IHZhbHVlIGZvciB0aHJvdHRsaW5nLCBjYW4gYmUgb3ZlcnJpZGRlbiBieSB1c2VyIHdpdGggcHJvcHNcbiAgICBzY3JvbGxFdmVudFRocm90dGxlOiAxNixcbiAgICAvLyBTY3JvbGxJbnRvVmlldyBvcHRpb25zLCBjYW4gYmUgb2ZmZXJlZCBieSA8U2Nyb2xsSW50b1ZpZXcgLz4gY29tcCBvciBpbXBlcmF0aXZlIHVzYWdlXG4gICAgb3B0aW9uczogRGVmYXVsdE9wdGlvbnNcbn07XG5cbmV4cG9ydCBjb25zdCBub3JtYWxpemVIT0NDb25maWcgPSAoY29uZmlnOiBQYXJ0aWFsSE9DQ29uZmlnID0ge30pID0+ICh7XG4gICAgLi4uRGVmYXVsdEhPQ0NvbmZpZyxcbiAgICAuLi5jb25maWcsXG4gICAgb3B0aW9uczogbm9ybWFsaXplT3B0aW9ucyhjb25maWcub3B0aW9ucywgRGVmYXVsdE9wdGlvbnMpXG59KTtcbiIsImltcG9ydCB7IG5vcm1hbGl6ZU9wdGlvbnMgfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyB0aHJvdHRsZSB9IGZyb20gJy4vdXRpbHMnO1xuXG5pbXBvcnQgdHlwZSB7IEZ1bGxPcHRpb25zLCBQYXJ0aWFsT3B0aW9ucyB9IGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB0eXBlIHsgU2Nyb2xsVmlldywgVmlldyB9IGZyb20gJ3JlYWN0LW5hdGl2ZSc7XG5cbnR5cGUgU2Nyb2xsUGFyYW1zID0geyB4OiBudW1iZXI7IHk6IG51bWJlcjsgYW5pbWF0ZWQ6IGJvb2xlYW4gfTtcblxuZXhwb3J0IGNvbnN0IHNjcm9sbEludG9WaWV3ID0gYXN5bmMgKFxuICAgIHNjcm9sbFZpZXc6IFNjcm9sbFZpZXcsXG4gICAgdmlldzogVmlldyxcbiAgICBzY3JvbGxZOiBudW1iZXIsXG4gICAgc2Nyb2xsWDogbnVtYmVyLFxuICAgIG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAoIShzY3JvbGxWaWV3IGFzIGFueSkgfHwgISh2aWV3IGFzIGFueSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY3JvbGxWaWV3IGFuZCB0YXJnZXQgVmlldyBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhbGlnbiwgYW5pbWF0ZWQsIGNvbXB1dGVTY3JvbGxZLCBjb21wdXRlU2Nyb2xsWCwgbWVhc3VyZUVsZW1lbnQsIGluc2V0cyB9ID0gbm9ybWFsaXplT3B0aW9ucyhvcHRpb25zKTtcblxuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IFtzY3JvbGxWaWV3TGF5b3V0LCB2aWV3TGF5b3V0XSA9IGF3YWl0IFByb21pc2UuYWxsKFttZWFzdXJlRWxlbWVudChzY3JvbGxWaWV3KSwgbWVhc3VyZUVsZW1lbnQodmlldyldKTtcblxuICAgICAgICBjb25zdCB0YXJnZXRTY3JvbGxZID0gY29tcHV0ZVNjcm9sbFkoc2Nyb2xsVmlld0xheW91dCwgdmlld0xheW91dCwgc2Nyb2xsWSwgaW5zZXRzLCBhbGlnbik7XG4gICAgICAgIGNvbnN0IHRhcmdldFNjcm9sbFggPSBjb21wdXRlU2Nyb2xsWChzY3JvbGxWaWV3TGF5b3V0LCB2aWV3TGF5b3V0LCBzY3JvbGxYLCBpbnNldHMsIGFsaWduKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsUGFyYW1zOiBTY3JvbGxQYXJhbXMgPSB7IHg6IHRhcmdldFNjcm9sbFgsIHk6IHRhcmdldFNjcm9sbFksIGFuaW1hdGVkIH07XG5cbiAgICAgICAgY29uc3Qgc2Nyb2xsUmVzcG9uZGVyID0gc2Nyb2xsVmlldy5nZXRTY3JvbGxSZXNwb25kZXIoKTtcbiAgICAgICAgaWYgKChzY3JvbGxSZXNwb25kZXIgYXMgYW55KS5zY3JvbGxSZXNwb25kZXJTY3JvbGxUbykge1xuICAgICAgICAgICAgc2Nyb2xsUmVzcG9uZGVyLnNjcm9sbFJlc3BvbmRlclNjcm9sbFRvKHNjcm9sbFBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzY3JvbGxWaWV3LnNjcm9sbFRvKHNjcm9sbFBhcmFtcyk7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmtub3duIGVycm9yJztcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gc2Nyb2xsIGludG8gdmlldzogJHtlcnJvck1lc3NhZ2V9YCk7XG4gICAgfVxufTtcblxudHlwZSBHZXRTY3JvbGxWaWV3ID0gKCkgPT4gU2Nyb2xsVmlldztcbnR5cGUgR2V0U2Nyb2xsWSA9ICgpID0+IG51bWJlcjtcbnR5cGUgR2V0U2Nyb2xsWCA9ICgpID0+IG51bWJlcjtcbnR5cGUgR2V0RGVmYXVsdE9wdGlvbnMgPSAoKSA9PiBGdWxsT3B0aW9ucztcblxuZXhwb3J0IHR5cGUgU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMgPSB7XG4gICAgcmVhZG9ubHkgZ2V0U2Nyb2xsVmlldzogR2V0U2Nyb2xsVmlldztcbiAgICByZWFkb25seSBnZXRTY3JvbGxZOiBHZXRTY3JvbGxZO1xuICAgIHJlYWRvbmx5IGdldFNjcm9sbFg6IEdldFNjcm9sbFg7XG4gICAgcmVhZG9ubHkgZ2V0RGVmYXVsdE9wdGlvbnM6IEdldERlZmF1bHRPcHRpb25zO1xufTtcblxuZXhwb3J0IGNsYXNzIFNjcm9sbEludG9WaWV3QVBJIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlcGVuZGVuY2llczogU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZURlcGVuZGVuY2llcyhkZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdmFsaWRhdGVEZXBlbmRlbmNpZXMoZGVwczogU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgcmVxdWlyZWREZXBLZXlzOiAoa2V5b2YgU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMpW10gPSBbXG4gICAgICAgICAgICAnZ2V0U2Nyb2xsVmlldycsXG4gICAgICAgICAgICAnZ2V0U2Nyb2xsWScsXG4gICAgICAgICAgICAnZ2V0U2Nyb2xsWCcsXG4gICAgICAgICAgICAnZ2V0RGVmYXVsdE9wdGlvbnMnXG4gICAgICAgIF07XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHJlcXVpcmVkRGVwS2V5cykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBkZXBzW2tleV0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERlcGVuZGVuY3kgXCIke2tleX1cIiBtdXN0IGJlIGEgZnVuY3Rpb24uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE5vcm1hbGl6ZWRPcHRpb25zID0gKG9wdGlvbnM6IFBhcnRpYWxPcHRpb25zID0ge30pOiBGdWxsT3B0aW9ucyA9PlxuICAgICAgICBub3JtYWxpemVPcHRpb25zKG9wdGlvbnMsIHRoaXMuZGVwZW5kZW5jaWVzLmdldERlZmF1bHRPcHRpb25zKCkpO1xuXG4gICAgcHVibGljIHNjcm9sbEludG9WaWV3ID0gKHZpZXc6IFZpZXcsIG9wdGlvbnM/OiBQYXJ0aWFsT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBjb25zdCBub3JtYWxpemVkT3B0aW9ucyA9IHRoaXMuZ2V0Tm9ybWFsaXplZE9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBub3JtYWxpemVkT3B0aW9ucy5pbW1lZGlhdGVcbiAgICAgICAgICAgID8gdGhpcy5zY3JvbGxJbnRvVmlld0ltbWVkaWF0ZSh2aWV3LCBub3JtYWxpemVkT3B0aW9ucylcbiAgICAgICAgICAgIDogdGhpcy5zY3JvbGxJbnRvVmlld1Rocm90dGxlZCh2aWV3LCBub3JtYWxpemVkT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgcGVyZm9ybVNjcm9sbCA9ICh2aWV3OiBWaWV3LCBvcHRpb25zOiBQYXJ0aWFsT3B0aW9ucyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICByZXR1cm4gc2Nyb2xsSW50b1ZpZXcoXG4gICAgICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5nZXRTY3JvbGxWaWV3KCksXG4gICAgICAgICAgICB2aWV3LFxuICAgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZ2V0U2Nyb2xsWSgpLFxuICAgICAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZ2V0U2Nyb2xsWCgpLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICApO1xuICAgIH07XG5cbiAgICBwcml2YXRlIHNjcm9sbEludG9WaWV3VGhyb3R0bGVkID0gdGhyb3R0bGUodGhpcy5wZXJmb3JtU2Nyb2xsLCAxNik7XG5cbiAgICBwcml2YXRlIHNjcm9sbEludG9WaWV3SW1tZWRpYXRlID0gdGhpcy5wZXJmb3JtU2Nyb2xsO1xufVxuIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuaW1wb3J0IHsgU2Nyb2xsSW50b1ZpZXdBUEkgfSBmcm9tICcuL2FwaSc7XG5cbmltcG9ydCB0eXBlIHsgU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXMgfSBmcm9tICcuL2FwaSc7XG5cbmNvbnN0IENvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PFNjcm9sbEludG9WaWV3QVBJIHwgbnVsbD4obnVsbCk7XG5cbmV4cG9ydCBkZWZhdWx0IENvbnRleHQ7XG5cbmV4cG9ydCBjb25zdCBBUElDb25zdW1lciA9IENvbnRleHQuQ29uc3VtZXI7XG5cbmludGVyZmFjZSBQcm92aWRlQVBJUHJvcHMge1xuICAgIGRlcGVuZGVuY2llczogU2Nyb2xsSW50b1ZpZXdEZXBlbmRlbmNpZXM7XG4gICAgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZTtcbn1cblxuZXhwb3J0IGNvbnN0IFByb3ZpZGVBUEk6IFJlYWN0LkZDPFByb3ZpZGVBUElQcm9wcz4gPSAoeyBkZXBlbmRlbmNpZXMsIGNoaWxkcmVuIH0pID0+IHtcbiAgICBjb25zdCBhcGkgPSBSZWFjdC51c2VNZW1vKCgpID0+IG5ldyBTY3JvbGxJbnRvVmlld0FQSShkZXBlbmRlbmNpZXMpLCBbZGVwZW5kZW5jaWVzXSk7XG4gICAgcmV0dXJuIDxDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXthcGl9PntjaGlsZHJlbn08L0NvbnRleHQuUHJvdmlkZXI+O1xufTtcbiIsImltcG9ydCBSZWFjdCwgeyBmb3J3YXJkUmVmLCB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSAncmVhY3QtbmF0aXZlJztcblxuaW1wb3J0IHsgQVBJQ29uc3VtZXIgfSBmcm9tICcuL2NvbnRleHQnO1xuaW1wb3J0IHsgdGhyb3R0bGUgfSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHR5cGUgeyBTY3JvbGxJbnRvVmlld0FQSSB9IGZyb20gJy4vYXBpJztcbmltcG9ydCB0eXBlIHsgUGFydGlhbE9wdGlvbnMgfSBmcm9tICcuL2NvbmZpZyc7XG5p