scrollscene
Version:
ScrollScene is an extra layer on top of ScrollMagic as well as using IntersectionObserver to achieve similar effects.
334 lines (267 loc) • 40.7 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
import { errorLog, isFunc, isObject, scrollAnimationInit, createArray, isString, stringContains } from "./helpers";
var nameSpace = 'ScrollObserver';
var state = function state(visible, alreadyFired) {
this.visible = false;
this.alreadyFired = false;
};
var setClassName = function setClassName(options) {
var toggle = _objectSpread({
element: null,
className: null
}, options);
if (!toggle.element) {
errorLog(nameSpace, "Be sure to set a const toggleElement = (reactRef.current or document.querySelector) in the new ".concat(nameSpace, "({ toggle: { element: toggleElement } })"));
}
if (!toggle.className) {
errorLog(nameSpace, "Be sure to set the className you want to toggle in the new ".concat(nameSpace, "({ toggle: { className: \"my-class\" } })"));
}
this.add = function () {
!toggle.element.classList.contains(toggle.className) && toggle.element.classList.add(toggle.className);
};
this.remove = function () {
toggle.element.classList.contains(toggle.className) && toggle.element.classList.remove(toggle.className);
};
this.update = function (setState) {
if (!setState.alreadyFired && setState.visible) {
this.add();
}
if (setState.alreadyFired && !setState.visible) {
this.remove();
}
};
};
var setTween = function setTween(options) {
var gsap = _objectSpread({
timeline: null,
yoyo: false,
speed: 1,
reverseSpeed: 1,
delay: 2
}, options);
if (!gsap.timeline) {
errorLog(nameSpace, "Be sure to set a const tl = gsap.timeline({ paused: true }) in the new ".concat(nameSpace, "({ gsap: { timeline: tl } })"));
}
var tl = gsap.timeline;
if (gsap.yoyo) {
tl.repeat(-1).yoyo(gsap.yoyo).repeatDelay(gsap.delay);
}
this.play = function () {
tl.timeScale(gsap.speed).play();
};
this.pause = function () {
tl.pause();
};
this.reverse = function () {
tl.timeScale(gsap.reverseSpeed).reverse();
};
this.kill = function () {
if (tl) {
tl.pause(0);
tl.kill();
}
};
this.update = function (setState) {
if (!setState.alreadyFired && setState.visible) {
this.play();
}
if (setState.alreadyFired && !setState.visible) {
gsap.yoyo ? this.pause() : this.reverse();
}
};
this.scrub = function (intersectionRatio) {
tl.progress(intersectionRatio);
};
};
var setPlayer = function setPlayer(options) {
var video = _objectSpread({
element: null,
playingClassName: null,
pausedClassName: null
}, options);
if (!video.element) {
errorLog(nameSpace, "Be sure to set a video element in the new ".concat(nameSpace, "({ video: { element: videoRef.current } })"));
}
function handlePlay() {
if (video.element.src) {
video.element.play();
video.playingClassName && video.element.classList.add(video.playingClassName);
video.pausedClassName && video.element.classList.remove(video.pausedClassName);
}
}
function handlePause() {
if (video.element.src) {
video.element.pause();
video.pausedClassName && video.element.classList.add(video.pausedClassName);
video.playingClassName && video.element.classList.remove(video.playingClassName);
}
}
function tryPlay() {
try {
handlePlay();
} catch (error) {
handlePause();
}
}
function tryPause() {
try {
handlePause();
} catch (error) {}
}
this.play = function () {
tryPlay();
};
this.pause = function () {
tryPause();
};
this.kill = function () {
tryPause();
};
this.update = function (setState) {
if (!setState.alreadyFired && setState.visible) {
this.play();
}
if (setState.alreadyFired && !setState.visible) {
this.pause();
}
};
};
var setFunction = function setFunction(options) {
var callback = _objectSpread({
active: null,
notActive: null
}, options);
if (!callback.active && !callback.notActive) {
errorLog(nameSpace, "Be sure to set a callback active or notActive function in the new ".concat(nameSpace, "({ callback: { active: () => () } })"));
}
if (callback.active && !isFunc(callback.active) || callback.notActive && !isFunc(callback.notActive)) {
errorLog(nameSpace, "Be sure to set the callback as a function ");
}
this.update = function (setState) {
if (!setState.alreadyFired && setState.visible && callback.active) {
callback.active();
}
if (setState.alreadyFired && !setState.visible && callback.notActive) {
callback.notActive();
}
};
};
var ScrollObserver = function ScrollObserver(_ref) {
var breakpoints = _ref.breakpoints,
callback = _ref.callback,
destroyImmediately = _ref.destroyImmediately,
gsap = _ref.gsap,
observer = _ref.observer,
offset = _ref.offset,
whenVisible = _ref.whenVisible,
thresholds = _ref.thresholds,
toggle = _ref.toggle,
triggerElement = _ref.triggerElement,
useDuration = _ref.useDuration,
video = _ref.video;
if (!triggerElement) {
errorLog(nameSpace, 'Be sure to set a const triggerElement = (reactRef.current or document.querySelector) in the new ScrollScene({ triggerElement: triggerElement })');
}
var $this = this;
var setToggle;
var setGsap;
var setVideo;
var setCallback;
var ratio;
var setRootMargin = '0% 0%';
var setState = new state(false, false);
if (typeof offset === 'number') {
setRootMargin = "-".concat(Math.abs(offset), "px 0%");
} else if (typeof offset === 'string') {
setRootMargin = "-".concat(Math.abs(parseFloat(offset)), "% 0%");
}
if (toggle && isObject(toggle)) {
setToggle = new setClassName(toggle);
}
if (gsap && isObject(gsap)) {
setGsap = new setTween(gsap);
}
if (video && isObject(video)) {
setVideo = new setPlayer(video);
}
if (callback && isObject(callback)) {
setCallback = new setFunction(callback);
}
var observerCallback = function observerCallback(entries) {
entries.forEach(function (_ref2) {
var isIntersecting = _ref2.isIntersecting,
intersectionRatio = _ref2.intersectionRatio;
if (ratio) {
setState.visible = intersectionRatio >= ratio;
} else if (isIntersecting && !setState.visible) {
setState.visible = true;
} else if (!isIntersecting && setState.visible) {
setState.visible = false;
}
setToggle && setToggle.update(setState);
setGsap && (!useDuration ? setGsap.update(setState) : setGsap.scrub(intersectionRatio));
setVideo && setVideo.update(setState);
setCallback && setCallback.update(setState);
if (!setState.alreadyFired && setState.visible) {
setState.alreadyFired = true;
}
if (setState.alreadyFired && !setState.visible) {
setState.alreadyFired = false;
}
if (isIntersecting && destroyImmediately) {
$this.destroy();
}
});
};
var getPercentage = function getPercentage(value) {
if (!isString(whenVisible) && !stringContains(whenVisible, '%')) {
errorLog(nameSpace, 'Be sure to set a percentage as a string. { whenVisible: "50%" }');
}
var parsed = parseInt(value.replace('%', '')) / 100;
ratio = parsed;
return parsed;
};
var getThresolds = function getThresolds() {
var defaults = {
one: [0, 1],
gsap: createArray(199)
};
var returnedThresholds = defaults.one;
if (whenVisible) {
returnedThresholds = getPercentage(whenVisible);
}
if (useDuration) {
returnedThresholds = defaults.gsap;
}
if (thresholds) {
returnedThresholds = createArray(thresholds);
}
return returnedThresholds;
};
var Observer = new IntersectionObserver(observerCallback, _objectSpread({
threshold: getThresolds(),
rootMargin: setRootMargin
}, observer));
this.init = function () {
Observer.observe(triggerElement);
};
this.destroy = function () {
if (triggerElement && Observer) {
if (setToggle) {
setToggle.remove();
}
if (setGsap) {
setGsap.kill();
}
if (setVideo) {
setVideo.kill();
}
Observer.unobserve(triggerElement);
}
};
scrollAnimationInit(breakpoints, this.init, this.destroy);
};
export { ScrollObserver };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TY3JvbGxPYnNlcnZlci50cyJdLCJuYW1lcyI6WyJlcnJvckxvZyIsImlzRnVuYyIsImlzT2JqZWN0Iiwic2Nyb2xsQW5pbWF0aW9uSW5pdCIsImNyZWF0ZUFycmF5IiwiaXNTdHJpbmciLCJzdHJpbmdDb250YWlucyIsIm5hbWVTcGFjZSIsInN0YXRlIiwidmlzaWJsZSIsImFscmVhZHlGaXJlZCIsInNldENsYXNzTmFtZSIsIm9wdGlvbnMiLCJ0b2dnbGUiLCJlbGVtZW50IiwiY2xhc3NOYW1lIiwiYWRkIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJyZW1vdmUiLCJ1cGRhdGUiLCJzZXRTdGF0ZSIsInNldFR3ZWVuIiwiZ3NhcCIsInRpbWVsaW5lIiwieW95byIsInNwZWVkIiwicmV2ZXJzZVNwZWVkIiwiZGVsYXkiLCJ0bCIsInJlcGVhdCIsInJlcGVhdERlbGF5IiwicGxheSIsInRpbWVTY2FsZSIsInBhdXNlIiwicmV2ZXJzZSIsImtpbGwiLCJzY3J1YiIsImludGVyc2VjdGlvblJhdGlvIiwicHJvZ3Jlc3MiLCJzZXRQbGF5ZXIiLCJ2aWRlbyIsInBsYXlpbmdDbGFzc05hbWUiLCJwYXVzZWRDbGFzc05hbWUiLCJoYW5kbGVQbGF5Iiwic3JjIiwiaGFuZGxlUGF1c2UiLCJ0cnlQbGF5IiwiZXJyb3IiLCJ0cnlQYXVzZSIsInNldEZ1bmN0aW9uIiwiY2FsbGJhY2siLCJhY3RpdmUiLCJub3RBY3RpdmUiLCJTY3JvbGxPYnNlcnZlciIsImJyZWFrcG9pbnRzIiwiZGVzdHJveUltbWVkaWF0ZWx5Iiwib2JzZXJ2ZXIiLCJvZmZzZXQiLCJ3aGVuVmlzaWJsZSIsInRocmVzaG9sZHMiLCJ0cmlnZ2VyRWxlbWVudCIsInVzZUR1cmF0aW9uIiwiJHRoaXMiLCJzZXRUb2dnbGUiLCJzZXRHc2FwIiwic2V0VmlkZW8iLCJzZXRDYWxsYmFjayIsInJhdGlvIiwic2V0Um9vdE1hcmdpbiIsIk1hdGgiLCJhYnMiLCJwYXJzZUZsb2F0Iiwib2JzZXJ2ZXJDYWxsYmFjayIsImVudHJpZXMiLCJmb3JFYWNoIiwiaXNJbnRlcnNlY3RpbmciLCJkZXN0cm95IiwiZ2V0UGVyY2VudGFnZSIsInZhbHVlIiwicGFyc2VkIiwicGFyc2VJbnQiLCJyZXBsYWNlIiwiZ2V0VGhyZXNvbGRzIiwiZGVmYXVsdHMiLCJvbmUiLCJyZXR1cm5lZFRocmVzaG9sZHMiLCJPYnNlcnZlciIsIkludGVyc2VjdGlvbk9ic2VydmVyIiwidGhyZXNob2xkIiwicm9vdE1hcmdpbiIsImluaXQiLCJvYnNlcnZlIiwidW5vYnNlcnZlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxTQUFTQSxRQUFULEVBQW1CQyxNQUFuQixFQUEyQkMsUUFBM0IsRUFBcUNDLG1CQUFyQyxFQUEwREMsV0FBMUQsRUFBdUVDLFFBQXZFLEVBQWlGQyxjQUFqRjtBQUVBLElBQU1DLFNBQVMsR0FBRyxnQkFBbEI7O0FBR0EsSUFBTUMsS0FBSyxHQUFHLFNBQVJBLEtBQVEsQ0FBU0MsT0FBVCxFQUFrQkMsWUFBbEIsRUFBZ0M7QUFDNUMsT0FBS0QsT0FBTCxHQUFlLEtBQWY7QUFDQSxPQUFLQyxZQUFMLEdBQW9CLEtBQXBCO0FBQ0QsQ0FIRDs7QUFLQSxJQUFNQyxZQUFZLEdBQUcsU0FBZkEsWUFBZSxDQUFvQkMsT0FBcEIsRUFBNkI7QUFDaEQsTUFBTUMsTUFBTTtBQUNWQyxJQUFBQSxPQUFPLEVBQUUsSUFEQztBQUVWQyxJQUFBQSxTQUFTLEVBQUU7QUFGRCxLQUdQSCxPQUhPLENBQVo7O0FBTUEsTUFBSSxDQUFDQyxNQUFNLENBQUNDLE9BQVosRUFBcUI7QUFDbkJkLElBQUFBLFFBQVEsQ0FDTk8sU0FETSwyR0FFNEZBLFNBRjVGLDhDQUFSO0FBSUQ7O0FBRUQsTUFBSSxDQUFDTSxNQUFNLENBQUNFLFNBQVosRUFBdUI7QUFDckJmLElBQUFBLFFBQVEsQ0FDTk8sU0FETSx1RUFFd0RBLFNBRnhELCtDQUFSO0FBSUQ7O0FBRUQsT0FBS1MsR0FBTCxHQUFXLFlBQVc7QUFFcEIsS0FBQ0gsTUFBTSxDQUFD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QUosRUFBaUI7QUFDZndCLE1BQUFBLGtCQUFrQixHQUFHRixRQUFRLENBQUM3RCxJQUE5QjtBQUNEOztBQUVELFFBQUlxQyxVQUFKLEVBQWdCO0FBQ2QwQixNQUFBQSxrQkFBa0IsR0FBR2xGLFdBQVcsQ0FBQ3dELFVBQUQsQ0FBaEM7QUFDRDs7QUFFRCxXQUFPMEIsa0JBQVA7QUFDRCxHQXJCRDs7QUF1QkEsTUFBTUMsUUFBUSxHQUFHLElBQUlDLG9CQUFKLENBQXlCZixnQkFBekI7QUFDZmdCLElBQUFBLFNBQVMsRUFBRU4sWUFBWSxFQURSO0FBRWZPLElBQUFBLFVBQVUsRUFBRXJCO0FBRkcsS0FHWlosUUFIWSxFQUFqQjs7QUFNQSxPQUFLa0MsSUFBTCxHQUFZLFlBQVc7QUFDckJKLElBQUFBLFFBQVEsQ0FBQ0ssT0FBVCxDQUFpQi9CLGNBQWpCO0FBQ0QsR0FGRDs7QUFJQSxPQUFLZ0IsT0FBTCxHQUFlLFlBQVc7QUFDeEIsUUFBSWhCLGNBQWMsSUFBSTBCLFFBQXRCLEVBQWdDO0FBQzlCLFVBQUl2QixTQUFKLEVBQWU7QUFDYkEsUUFBQUEsU0FBUyxDQUFDN0MsTUFBVjtBQUNEOztBQUVELFVBQUk4QyxPQUFKLEVBQWE7QUFDWEEsUUFBQUEsT0FBTyxDQUFDN0IsSUFBUjtBQUNEOztBQUVELFVBQUk4QixRQUFKLEVBQWM7QUFDWkEsUUFBQUEsUUFBUSxDQUFDOUIsSUFBVDtBQUNEOztBQUVEbUQsTUFBQUEsUUFBUSxDQUFDTSxTQUFULENBQW1CaEMsY0FBbkI7QUFDRDtBQUNGLEdBaEJEOztBQWtCQTFELEVBQUFBLG1CQUFtQixDQUFDb0QsV0FBRCxFQUFjLEtBQUtvQyxJQUFuQixFQUF5QixLQUFLZCxPQUE5QixDQUFuQjtBQUNELENBbktEOztBQXFLQSxTQUFTdkIsY0FBVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVycm9yTG9nLCBpc0Z1bmMsIGlzT2JqZWN0LCBzY3JvbGxBbmltYXRpb25Jbml0LCBjcmVhdGVBcnJheSwgaXNTdHJpbmcsIHN0cmluZ0NvbnRhaW5zIH0gZnJvbSAnLi9oZWxwZXJzJ1xuXG5jb25zdCBuYW1lU3BhY2UgPSAnU2Nyb2xsT2JzZXJ2ZXInXG5cbi8vIEB0cy1pZ25vcmVcbmNvbnN0IHN0YXRlID0gZnVuY3Rpb24odmlzaWJsZSwgYWxyZWFkeUZpcmVkKSB7XG4gIHRoaXMudmlzaWJsZSA9IGZhbHNlXG4gIHRoaXMuYWxyZWFkeUZpcmVkID0gZmFsc2Vcbn1cblxuY29uc3Qgc2V0Q2xhc3NOYW1lID0gZnVuY3Rpb24odGhpczogYW55LCBvcHRpb25zKSB7XG4gIGNvbnN0IHRvZ2dsZSA9IHtcbiAgICBlbGVtZW50OiBudWxsLFxuICAgIGNsYXNzTmFtZTogbnVsbCxcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgaWYgKCF0b2dnbGUuZWxlbWVudCkge1xuICAgIGVycm9yTG9nKFxuICAgICAgbmFtZVNwYWNlLFxuICAgICAgYEJlIHN1cmUgdG8gc2V0IGEgY29uc3QgdG9nZ2xlRWxlbWVudCA9IChyZWFjdFJlZi5jdXJyZW50IG9yIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IpIGluIHRoZSBuZXcgJHtuYW1lU3BhY2V9KHsgdG9nZ2xlOiB7IGVsZW1lbnQ6IHRvZ2dsZUVsZW1lbnQgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgaWYgKCF0b2dnbGUuY2xhc3NOYW1lKSB7XG4gICAgZXJyb3JMb2coXG4gICAgICBuYW1lU3BhY2UsXG4gICAgICBgQmUgc3VyZSB0byBzZXQgdGhlIGNsYXNzTmFtZSB5b3Ugd2FudCB0byB0b2dnbGUgaW4gdGhlIG5ldyAke25hbWVTcGFjZX0oeyB0b2dnbGU6IHsgY2xhc3NOYW1lOiBcIm15LWNsYXNzXCIgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgdGhpcy5hZGQgPSBmdW5jdGlvbigpIHtcbiAgICAvKiBhZGQgY2xhc3NOYW1lIGlmIGl0J3Mgbm90IGFscmVhZHkgdGhlcmUgKi9cbiAgICAhdG9nZ2xlLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKHRvZ2dsZS5jbGFzc05hbWUpICYmIHRvZ2dsZS5lbGVtZW50LmNsYXNzTGlzdC5hZGQodG9nZ2xlLmNsYXNzTmFtZSlcbiAgfVxuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oKSB7XG4gICAgLyogcmVtb3ZlIGNsYXNzTmFtZSBpZiBpdCdzIHRoZXJlICovXG4gICAgdG9nZ2xlLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKHRvZ2dsZS5jbGFzc05hbWUpICYmIHRvZ2dsZS5lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUodG9nZ2xlLmNsYXNzTmFtZSlcbiAgfVxuXG4gIHRoaXMudXBkYXRlID0gZnVuY3Rpb24oc2V0U3RhdGUpIHtcbiAgICBpZiAoIXNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiBzZXRTdGF0ZS52aXNpYmxlKSB7XG4gICAgICB0aGlzLmFkZCgpXG4gICAgfVxuXG4gICAgaWYgKHNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiAhc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgdGhpcy5yZW1vdmUoKVxuICAgIH1cbiAgfVxufVxuXG5jb25zdCBzZXRUd2VlbiA9IGZ1bmN0aW9uKHRoaXM6IGFueSwgb3B0aW9ucykge1xuICBjb25zdCBnc2FwID0ge1xuICAgIHRpbWVsaW5lOiBudWxsLFxuICAgIHlveW86IGZhbHNlLFxuICAgIHNwZWVkOiAxLFxuICAgIHJldmVyc2VTcGVlZDogMSxcbiAgICBkZWxheTogMixcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgaWYgKCFnc2FwLnRpbWVsaW5lKSB7XG4gICAgZXJyb3JMb2coXG4gICAgICBuYW1lU3BhY2UsXG4gICAgICBgQmUgc3VyZSB0byBzZXQgYSBjb25zdCB0bCA9IGdzYXAudGltZWxpbmUoeyBwYXVzZWQ6IHRydWUgfSkgaW4gdGhlIG5ldyAke25hbWVTcGFjZX0oeyBnc2FwOiB7IHRpbWVsaW5lOiB0bCB9IH0pYCxcbiAgICApXG4gIH1cblxuICBjb25zdCB0bCA9IGdzYXAudGltZWxpbmVcblxuICBpZiAoZ3NhcC55b3lvKSB7XG4gICAgdGwucmVwZWF0KC0xKVxuICAgICAgLnlveW8oZ3NhcC55b3lvKVxuICAgICAgLnJlcGVhdERlbGF5KGdzYXAuZGVsYXkpXG4gIH1cblxuICB0aGlzLnBsYXkgPSBmdW5jdGlvbigpIHtcbiAgICB0bC50aW1lU2NhbGUoZ3NhcC5zcGVlZCkucGxheSgpXG4gIH1cblxuICB0aGlzLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgdGwucGF1c2UoKVxuICB9XG5cbiAgdGhpcy5yZXZlcnNlID0gZnVuY3Rpb24oKSB7XG4gICAgdGwudGltZVNjYWxlKGdzYXAucmV2ZXJzZVNwZWVkKS5yZXZlcnNlKClcbiAgfVxuXG4gIHRoaXMua2lsbCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0bCkge1xuICAgICAgdGwucGF1c2UoMClcbiAgICAgIHRsLmtpbGwoKVxuICAgIH1cbiAgfVxuXG4gIHRoaXMudXBkYXRlID0gZnVuY3Rpb24oc2V0U3RhdGUpIHtcbiAgICBpZiAoIXNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiBzZXRTdGF0ZS52aXNpYmxlKSB7XG4gICAgICB0aGlzLnBsYXkoKVxuICAgIH1cblxuICAgIGlmIChzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgIXNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgIGdzYXAueW95byA/IHRoaXMucGF1c2UoKSA6IHRoaXMucmV2ZXJzZSgpXG4gICAgfVxuICB9XG5cbiAgdGhpcy5zY3J1YiA9IGZ1bmN0aW9uKGludGVyc2VjdGlvblJhdGlvKSB7XG4gICAgdGwucHJvZ3Jlc3MoaW50ZXJzZWN0aW9uUmF0aW8pXG4gIH1cbn1cblxuY29uc3Qgc2V0UGxheWVyID0gZnVuY3Rpb24odGhpczogYW55LCBvcHRpb25zKSB7XG4gIGNvbnN0IHZpZGVvID0ge1xuICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgcGxheWluZ0NsYXNzTmFtZTogbnVsbCxcbiAgICBwYXVzZWRDbGFzc05hbWU6IG51bGwsXG4gICAgLi4ub3B0aW9ucyxcbiAgfVxuXG4gIGlmICghdmlkZW8uZWxlbWVudCkge1xuICAgIGVycm9yTG9nKFxuICAgICAgbmFtZVNwYWNlLFxuICAgICAgYEJlIHN1cmUgdG8gc2V0IGEgdmlkZW8gZWxlbWVudCBpbiB0aGUgbmV3ICR7bmFtZVNwYWNlfSh7IHZpZGVvOiB7IGVsZW1lbnQ6IHZpZGVvUmVmLmN1cnJlbnQgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGxheSgpIHtcbiAgICBpZiAodmlkZW8uZWxlbWVudC5zcmMpIHtcbiAgICAgIHZpZGVvLmVsZW1lbnQucGxheSgpXG4gICAgICB2aWRlby5wbGF5aW5nQ2xhc3NOYW1lICYmIHZpZGVvLmVsZW1lbnQuY2xhc3NMaXN0LmFkZCh2aWRlby5wbGF5aW5nQ2xhc3NOYW1lKVxuICAgICAgdmlkZW8ucGF1c2VkQ2xhc3NOYW1lICYmIHZpZGVvLmVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSh2aWRlby5wYXVzZWRDbGFzc05hbWUpXG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGhhbmRsZVBhdXNlKCkge1xuICAgIGlmICh2aWRlby5lbGVtZW50LnNyYykge1xuICAgICAgdmlkZW8uZWxlbWVudC5wYXVzZSgpXG4gICAgICB2aWRlby5wYXVzZWRDbGFzc05hbWUgJiYgdmlkZW8uZWxlbWVudC5jbGFzc0xpc3QuYWRkKHZpZGVvLnBhdXNlZENsYXNzTmFtZSlcbiAgICAgIHZpZGVvLnBsYXlpbmdDbGFzc05hbWUgJiYgdmlkZW8uZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKHZpZGVvLnBsYXlpbmdDbGFzc05hbWUpXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdHJ5UGxheSgpIHtcbiAgICB0cnkge1xuICAgICAgaGFuZGxlUGxheSgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGhhbmRsZVBhdXNlKClcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cnlQYXVzZSgpIHtcbiAgICB0cnkge1xuICAgICAgaGFuZGxlUGF1c2UoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7fVxuICB9XG5cbiAgdGhpcy5wbGF5ID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5UGxheSgpXG4gIH1cblxuICB0aGlzLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5UGF1c2UoKVxuICB9XG5cbiAgdGhpcy5raWxsID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5UGF1c2UoKVxuICB9XG5cbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbihzZXRTdGF0ZSkge1xuICAgIGlmICghc2V0U3RhdGUuYWxyZWFkeUZpcmVkICYmIHNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgIHRoaXMucGxheSgpXG4gICAgfVxuXG4gICAgaWYgKHNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiAhc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgdGhpcy5wYXVzZSgpXG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHNldEZ1bmN0aW9uOiBhbnkgPSBmdW5jdGlvbih0aGlzOiBhbnksIG9wdGlvbnMpIHtcbiAgY29uc3QgY2FsbGJhY2sgPSB7XG4gICAgYWN0aXZlOiBudWxsLFxuICAgIG5vdEFjdGl2ZTogbnVsbCxcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgaWYgKCFjYWxsYmFjay5hY3RpdmUgJiYgIWNhbGxiYWNrLm5vdEFjdGl2ZSkge1xuICAgIGVycm9yTG9nKFxuICAgICAgbmFtZVNwYWNlLFxuICAgICAgYEJlIHN1cmUgdG8gc2V0IGEgY2FsbGJhY2sgYWN0aXZlIG9yIG5vdEFjdGl2ZSBmdW5jdGlvbiBpbiB0aGUgbmV3ICR7bmFtZVNwYWNlfSh7IGNhbGxiYWNrOiB7IGFjdGl2ZTogKCkgPT4gKCkgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgaWYgKChjYWxsYmFjay5hY3RpdmUgJiYgIWlzRnVuYyhjYWxsYmFjay5hY3RpdmUpKSB8fCAoY2FsbGJhY2subm90QWN0aXZlICYmICFpc0Z1bmMoY2FsbGJhY2subm90QWN0aXZlKSkpIHtcbiAgICBlcnJvckxvZyhuYW1lU3BhY2UsIGBCZSBzdXJlIHRvIHNldCB0aGUgY2FsbGJhY2sgYXMgYSBmdW5jdGlvbiBgKVxuICB9XG5cbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbihzZXRTdGF0ZSkge1xuICAgIGlmICghc2V0U3RhdGUuYWxyZWFkeUZpcmVkICYmIHNldFN0YXRlLnZpc2libGUgJiYgY2FsbGJhY2suYWN0aXZlKSB7XG4gICAgICBjYWxsYmFjay5hY3RpdmUoKVxuICAgIH1cblxuICAgIGlmIChzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgIXNldFN0YXRlLnZpc2libGUgJiYgY2FsbGJhY2subm90QWN0aXZlKSB7XG4gICAgICBjYWxsYmFjay5ub3RBY3RpdmUoKVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTY3JvbGxPYnNlcnZlckdzYXAge1xuICAvKipcbiAgICogdGltZWxpbmVcbiAgICogQGRlc2MgSW5zZXJ0IHlvdXIgZ3NhcC50aW1lbGluZSBvYmplY3QgdmFyXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBteVRpbWVsaW5lID0gZ3NhcC50aW1lbGluZSgpXG4gICAqIGdzYXA6IHsgdGltZWxpbmU6IG15VGltZWxpbmUgfVxuICAgKi9cbiAgdGltZWxpbmU6IGFueVxuXG4gIC8qKlxuICAgKiB5b3lvXG4gICAqIEBkZXNjIERvIHlvdSB3YW50IGdzYXAgYW5pbWF0aW9uIHRvIGxvb3AgYmFjayBhbmQgZm9ydGg/XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGVcbiAgICogZ3NhcDogeyB5b3lvOiB0cnVlIH1cbiAgICovXG4gIHlveW8/OiBib29sZWFuXG5cbiAgLyoqXG4gICAqIHNwZWVkXG4gICAqIEBkZXNjIFRoZSBzcGVlZCBhdCB3aGljaCB0aGUgZ3NhcCBhbmltYXRpb24gd2lsbCBwbGF5IHJlbGF0aXZlIHRvIGl0J3MgY3VycmVudCBzcGVlZC5cbiAgICogQHR5cGUgbnVtYmVyXG4gICAqIEBkZWZhdWx0IDFcbiAgICogQGV4YW1wbGVcbiAgICogZ3NhcDogeyBzcGVlZDogMiB9IC8vID0gdHdpY2UgYXMgZmFzdFxuICAgKi9cbiAgc3BlZWQ/OiBudW1iZXJcblxuICAvKipcbiAgICogc3BlZWRcbiAgICogQGRlc2MgVGhlIHNwZWVkIGF0IHdoaWNoIHRoZSBnc2FwIGFuaW1hdGlvbiB3aWxsIHJldmVyc2UgcmVsYXRpdmUgdG8gaXQncyBjdXJyZW50IHNwZWVkLlxuICAgKiBAdHlwZSBudW1iZXJcbiAgICogQGRlZmF1bHQgNFxuICAgKiBAZXhhbXBsZVxuICAgKiBnc2FwOiB7IHNwZWVkOiA0IH0gLy8gPSA0eCBhcyBmYXN0XG4gICAqL1xuICByZXZlcnNlU3BlZWQ/OiBudW1iZXJcblxuICAvKipcbiAgICogZGVsYXlcbiAgICogQGRlc2MgVGhlIGRlbGF5IChpbiBzZWNvbmRzKSBhdCB3aGljaCB0aGUgZ3NhcCBhbmltYXRpb24gd2FpdCBiZWZvcmUgcmV2ZXJzaW5nLlxuICAgKiBAdHlwZSBudW1iZXJcbiAgICogQGRlZmF1bHQgMlxuICAgKiBAZXhhbXBsZVxuICAgKiBnc2FwOiB7IGRlbGF5OiAzIH0gLy8gPSBXYWl0IDMgc2Vjb25kc1xuICAgKi9cbiAgZGVsYXk/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJU2Nyb2xsT2JzZXJ2ZXJUb2dnbGUge1xuICAvKipcbiAgICogY2xhc3NOYW1lXG4gICAqIEBkZXNjIFNwZWNpZnkgdGhlIGNsYXNzTmFtZSB5b3Ugd2lzaCB0byB0b2dnbGUuXG4gICAqIEB0eXBlIHN0cmluZ1xuICAgKiBAZXhhbXBsZVxuICAgKiB0b2dnbGU6IHsgY2xhc3NOYW1lOiAndHVybi1tZS1ibHVlLWJhYnknIH1cbiAgICovXG4gIGNsYXNzTmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIGVsZW1lbnRcbiAgICogQGRlc2MgU3BlY2lmeSB0aGUgZWxlbWVudCB5b3Ugd2lzaCB0byB0b2dnbGUgdGhlIGNsYXNzTmFtZSBvbi5cbiAgICogQHR5cGUgSFRNTEVsZW1lbnQgfCBhbnlcbiAgICogQGV4YW1wbGVcbiAgICogdG9nZ2xlOiB7IGVsZW1lbnQ6IGNvbnRhaW5lclJlZi5jdXJyZW50IH1cbiAgICovXG4gIGVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgYW55XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVNjcm9sbE9ic2VydmVyVmlkZW8ge1xuICAvKipcbiAgICogZWxlbWVudFxuICAgKiBAZGVzYyBTcGVjaWZ5IHRoZSB2aWRlbyBlbGVtZW50IHlvdSB3aXNoIHRvIGludGVyYWN0IHdpdGguXG4gICAqIEB0eXBlIEhUTUxFbGVtZW50IHwgYW55XG4gICAqIEBleGFtcGxlXG4gICAqIHZpZGVvOiB7IGVsZW1lbnQ6IHZpZGVvUmVmLmN1cnJlbnQgfVxuICAgKi9cbiAgZWxlbWVudDogSFRNTEVsZW1lbnQgfCBhbnlcbn1cblxuaW50ZXJmYWNlIElTY3JvbGxPYnNlcnZlciB7XG4gIC8qKlxuICAgKiBicmVha3BvaW50c1xuICAgKiBAZGVzYyBVc2UgdG8gc2V0IHJlc3BvbnNpdmVuZXNzIG9mIHRoZSBTY3JvbGxPYnNlcnZlciwgbW9iaWxlLWZpcnN0XG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBicmVha3BvaW50czogeyAwOiBmYWxzZSwgNzY4OiB0cnVlIH1cbiAgICovXG4gIGJyZWFrcG9pbnRzPzogb2JqZWN0XG5cbiAgLyoqXG4gICAqIGNhbGxiYWNrXG4gICAqIEBkZXNjIFVzZSB0byBzZXQgYSBjYWxsYmFjayB3aGVuIHRoZSBzY2VuZSBpcyBhY3RpdmUuXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBjYWxsYmFjazogeyBhY3RpdmU6ICgpID0+ICgpLCBub3RBY3RpdmU6ICgpID0+ICgpIH1cbiAgICovXG4gIGNhbGxiYWNrPzogb2JqZWN0XG5cbiAgLyoqXG4gICAqIGRlc3Ryb3lJbW1lZGlhdGVseVxuICAgKiBAZGVzYyBVc2UgdG8gZGVzdHJveSB0aGUgc2NlbmUgaW1tZWRpYXRlbHkgYWZ0ZXIgZmlyaW5nIG9uY2UgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZS5cbiAgICogQHR5cGUgYm9vbGVhblxuICAgKiBAZXhhbXBsZVxuICAgKiBkZXN0cm95SW1tZWRpYXRlbHk6IHRydWVcbiAgICovXG4gIGRlc3Ryb3lJbW1lZGlhdGVseT86IGJvb2xlYW5cblxuICAvKipcbiAgICogZ3NhcFxuICAgKiBAZGVzYyBVc2UgdG8gc2V0IG9wdGlvbnMgZm9yIHRoZSBnc2FwIGFuaW1hdGlvbiBvZiB0aGUgU2Nyb2xsT2JzZXJ2ZXIuXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBnc2FwOiB7IHRpbWVsaW5lOiBteVRpbWVsaW5lLCB5b3lvOiB0cnVlLCByZXZlcnNlU3BlZWQ6IDIgfVxuICAgKi9cbiAgZ3NhcD86IElTY3JvbGxPYnNlcnZlckdzYXBcblxuICAvKipcbiAgICogb2JzZXJ2ZXJcbiAgICogQGRlc2MgRXh0cmEgb3B0aW9ucyB0byBwYXNzIHRoZSBJbnRlcnNlY3Rpb25PYnNlcnZlciwgbGlrZSByb290LCByb290TWFyZ2luLCB0aHJlc2hvbGQgKHRvIG92ZXJyaWRlIHRoZSB0aHJlc2hvbGRzIG9wdGlvbilcbiAgICogQHR5cGUgb2JqZWN0XG4gICAqIEBleGFtcGxlXG4gICAqIG9ic2VydmVyOiB7IHJvb3RNYXJnaW46ICctNTAlIDAlJyB9XG4gICAqL1xuICBvYnNlcnZlcj86IG9iamVjdFxuXG4gIC8qKlxuICAgKiBvZmZzZXRcbiAgICogQGRlc2MgQ2hhbmdlIHRoZSBvZmZzZXQuIFRoaXMgdXNlcyByb290TWFyZ2luIHRodXMgb25seSB3b3JrcyBhcyBhIG5lZ2F0aXZlIG9mZnNldC5cbiAgICogQHR5cGUgbnVtYmVyIHwgc3RyaW5nXG4gICAqIEBkZWZhdWx0dmFsdWUgJzAlIDAlJ1xuICAgKiBAZXhhbXBsZVxuICAgKiBvZmZzZXQ6IDUwMCAvLyB0aGlzIHdpbGwgYmUgcm9vdE1hcmdpbjogJy01MDBweCAwJSdcbiAgICovXG4gIG9mZnNldD86IG51bWJlciB8IHN0cmluZ1xuXG4gIC8qKlxuICAgKiB0aHJlc2hvbGRzXG4gICAqIEBkZXNjIFNldCB0aGUgbnVtYmVyIG9mIHRocmVzaG9sZHMgeW91IHdhbnQuXG4gICAqIEByZXR1cm5zIEFuIEFycmF5IG9mIG51bWJlciBmcm9tIDAgdG8gMS4gQWRkIDEgdG8geW91ciBudW1iZXIgdG8gYWNjb3VudCBmb3IgMC5cbiAgICogQHR5cGUgbnVtYmVyXG4gICAqIEBleGFtcGxlXG4gICAqIHRocmVzaG9sZHM6IDEgPSBbMCwgMV1cbiAgICogdGhyZXNob2xkczogMiA9IFswLCAwLjUsIDFdXG4gICAqIHRocmVzaG9sZHM6IDMgPSBbMCwgMC4zMywgMC42NywgMV1cbiAgICogdGhyZXNob2xkczogMTAwID0gWzAsIDAuMSwgMC4yLCAuLi4gMC45OCwgMC45OSwgMV1cbiAgICovXG4gIHRocmVzaG9sZHM/OiBudW1iZXJcblxuICAvKipcbiAgICogdG9nZ2xlXG4gICAqIEBkZXNjIFVzZSB0byBzZXQgdGhlIG9wdGlvbnMgZm9yIHRoZSB0b2dnbGluZyBvZiBhIGNsYXNzTmFtZVxuICAgKiBAdHlwZSBvYmplY3RcbiAgICogQGV4YW1wbGVcbiAgICogdG9nZ2xlOiB7IGVsZW1lbnQ6IGNvbnRhaW5lclJlZi5jdXJyZW50LCBjbGFzc05hbWU6ICdsZXRzLWRvLXRoaXMnIH1cbiAgICovXG4gIHRvZ2dsZT86IElTY3JvbGxPYnNlcnZlclRvZ2dsZVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyRWxlbWVudFxuICAgKiBAZGVzYyBTZXQgdGhlIGVsZW1lbnQgeW91IHdpc2ggdG8gdHJpZ2dlciBldmVudHMgYmFzZWQgdXBvbiwgdGhlIG9ic2VydmVkIGVsZW1lbnQuXG4gICAqIEB0eXBlIEhUTUxFbGVtZW50IHwgYW55XG4gICAqIEBleGFtcGxlXG4gICAqIHRyaWdnZXJFbGVtZW50OiB0cmlnZ2VyUmVmLmN1cnJlbnRcbiAgICovXG4gIHRyaWdnZXJFbGVtZW50OiBIVE1MRWxlbWVudCB8IGFueVxuXG4gIC8qKlxuICAgKiB1c2VEdXJhdGlvblxuICAgKiBAZGVzYyBVc2UgdGhlIHBlcmNlbnRhZ2Ugb2YgZWxlbWVudCB2aXNpYmlsaXR5IHRvIHNjcnViIHRoZSBnc2FwIHRpbWVsaW5lLlxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqIEBleGFtcGxlXG4gICAqIHVzZUR1cmF0aW9uOiB0cnVlXG4gICAqL1xuICB1c2VEdXJhdGlvbj86IGJvb2xlYW5cblxuICAvKipcbiAgICogdmlkZW9cbiAgICogQGRlc2MgVXNlIHRvIHNldCB0aGUgb3B0aW9ucyBmb3IgcGxheWluZyBhbmQgcGF1c2luZyBvZiB0aGUgdmlkZW8uXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiB2aWRlbzogeyBlbGVtZW50OiB2aWRlb1JlZi5jdXJyZW50IH1cbiAgICovXG4gIHZpZGVvPzogSVNjcm9sbE9ic2VydmVyVmlkZW9cblxuICAvKipcbiAgICogd2hlblZpc2libGVcbiAgICogQGRlc2MgU2V0IHdoZW4gdGhlIHNjZW5lIHNob3VsZCBiZSBhY3RpdmUgYmFzZWQgb24gdGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGVsZW1lbnQgdmlzaWJsZVxuICAgKiBAdHlwZSBudW1iZXJcbiAgICogQGV4YW1wbGVcbiAgICogd2hlblZpc2libGU6ICc1MCUnXG4gICAqL1xuICB3aGVuVmlzaWJsZT86IHN0cmluZ1xufVxuXG5jb25zdCBTY3JvbGxPYnNlcnZlciA9IGZ1bmN0aW9uKFxuICB0aGlzOiBhbnksXG4gIHtcbiAgICBicmVha3BvaW50cyxcbiAgICBjYWxsYmFjayxcbiAgICBkZXN0cm95SW1tZWRpYXRlbHksXG4gICAgZ3NhcCxcbiAgICBvYnNlcnZlcixcbiAgICBvZmZzZXQsXG4gICAgd2hlblZpc2libGUsXG4gICAgdGhyZXNob2xkcyxcbiAgICB0b2dnbGUsXG4gICAgdHJpZ2dlckVsZW1lbnQsXG4gICAgdXNlRHVyYXRpb24sXG4gICAgdmlkZW8sXG4gIH06IElTY3JvbGxPYnNlcnZlcixcbikge1xuICBpZiAoIXRyaWdnZXJFbGVtZW50KSB7XG4gICAgZXJyb3JMb2coXG4gICAgICBuYW1lU3BhY2UsXG4gICAgICAnQmUgc3VyZSB0byBzZXQgYSBjb25zdCB0cmlnZ2VyRWxlbWVudCA9IChyZWFjdFJlZi5jdXJyZW50IG9yIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IpIGluIHRoZSBuZXcgU2Nyb2xsU2NlbmUoeyB0cmlnZ2VyRWxlbWVudDogdHJpZ2dlckVsZW1lbnQgfSknLFxuICAgIClcbiAgfVxuXG4gIGNvbnN0ICR0aGlzID0gdGhpc1xuICBsZXQgc2V0VG9nZ2xlXG4gIGxldCBzZXRHc2FwXG4gIGxldCBzZXRWaWRlb1xuICBsZXQgc2V0Q2FsbGJhY2tcbiAgbGV0IHJhdGlvXG4gIGxldCBzZXRSb290TWFyZ2luID0gJzAlIDAlJ1xuICBsZXQgc2V0U3RhdGUgPSBuZXcgc3RhdGUoZmFsc2UsIGZhbHNlKVxuXG4gIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnbnVtYmVyJykge1xuICAgIC8vIHByb3RlY3QgYWdhaW5zdCBwb3NpdGl2ZSBweCB2YWx1ZXMsIGZvciBub3dcbiAgICBzZXRSb290TWFyZ2luID0gYC0ke01hdGguYWJzKG9mZnNldCl9cHggMCVgXG4gIH0gZWxzZSBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBwcm90ZWN0IGFnYWluc3QgcG9zaXRpdmUgcGVyY2VudGFnZSB2YWx1ZXMsIGZvciBub3dcbiAgICBzZXRSb290TWFyZ2luID0gYC0ke01hdGguYWJzKHBhcnNlRmxvYXQob2Zmc2V0KSl9JSAwJWBcbiAgfVxuXG4gIGlmICh0b2dnbGUgJiYgaXNPYmplY3QodG9nZ2xlKSkge1xuICAgIHNldFRvZ2dsZSA9IG5ldyBzZXRDbGFzc05hbWUodG9nZ2xlKVxuICB9XG5cbiAgaWYgKGdzYXAgJiYgaXNPYmplY3QoZ3NhcCkpIHtcbiAgICBzZXRHc2FwID0gbmV3IHNldFR3ZWVuKGdzYXApXG4gIH1cblxuICBpZiAodmlkZW8gJiYgaXNPYmplY3QodmlkZW8pKSB7XG4gICAgc2V0VmlkZW8gPSBuZXcgc2V0UGxheWVyKHZpZGVvKVxuICB9XG5cbiAgaWYgKGNhbGxiYWNrICYmIGlzT2JqZWN0KGNhbGxiYWNrKSkge1xuICAgIHNldENhbGxiYWNrID0gbmV3IHNldEZ1bmN0aW9uKGNhbGxiYWNrKVxuICB9XG5cbiAgY29uc3Qgb2JzZXJ2ZXJDYWxsYmFjayA9IGZ1bmN0aW9uKGVudHJpZXMpIHtcbiAgICBlbnRyaWVzLmZvckVhY2goKHsgaXNJbnRlcnNlY3RpbmcsIGludGVyc2VjdGlvblJhdGlvIH0pID0+IHtcbiAgICAgIC8qXG4gICAgICAgKiBUbyBoZWxwIHRoZSB3b25raW5lc3Mgb2YgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIsIGlzSW50ZXJzZWN0aW5nIGZpcmluZyB0cnVlIHdoZW4gaXQncyByZWFsbHkgZmFsc2VcbiAgICAgICAqL1xuICAgICAgaWYgKHJhdGlvKSB7XG4gICAgICAgIHNldFN0YXRlLnZpc2libGUgPSBpbnRlcnNlY3Rpb25SYXRpbyA+PSByYXRpb1xuICAgICAgfSBlbHNlIGlmIChpc0ludGVyc2VjdGluZyAmJiAhc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUbyBoZWxwIHdpdGggc2V0Q2FsbGJhY2sgYW5kIGlnbm9yaW5nIHJlZmlyaW5nIGV4dHJhIGZ1bmN0aW9uXG4gICAgICAgICAqIGNhbGxzIGR1ZSB0byBpbnRlcnNlY3Rpb25SYXRpb1xuICAgICAgICAgKi9cbiAgICAgICAgc2V0U3RhdGUudmlzaWJsZSA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAoIWlzSW50ZXJzZWN0aW5nICYmIHNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgICAgc2V0U3RhdGUudmlzaWJsZSA9IGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHNldFRvZ2dsZSAmJiBzZXRUb2dnbGUudXBkYXRlKHNldFN0YXRlKVxuICAgICAgc2V0R3NhcCAmJiAoIXVzZUR1cmF0aW9uID8gc2V0R3NhcC51cGRhdGUoc2V0U3RhdGUpIDogc2V0R3NhcC5zY3J1YihpbnRlcnNlY3Rpb25SYXRpbykpXG4gICAgICBzZXRWaWRlbyAmJiBzZXRWaWRlby51cGRhdGUoc2V0U3RhdGUpXG4gICAgICBzZXRDYWxsYmFjayAmJiBzZXRDYWxsYmFjay51cGRhdGUoc2V0U3RhdGUpXG5cbiAgICAgIC8qXG4gICAgICAgKiBUbyBoZWxwIHdpdGggaWdub3JpbmcgcmVmaXJpbmcgZXh0cmEgZnVuY3Rpb25cbiAgICAgICAqL1xuICAgICAgaWYgKCFzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgICBzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgPSB0cnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgIXNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgICAgc2V0U3RhdGUuYWxyZWFkeUZpcmVkID0gZmFsc2VcbiAgICAgIH1cblxuICAgICAgaWYgKGlzSW50ZXJzZWN0aW5nICYmIGRlc3Ryb3lJbW1lZGlhdGVseSkge1xuICAgICAgICAvKlxuICAgICAgICAgKiBkZXN0cm95IHRoZSBzY2VuZSBhZnRlciB1c2VkIG9uY2VcbiAgICAgICAgICovXG4gICAgICAgICR0aGlzLmRlc3Ryb3koKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBnZXRQZXJjZW50YWdlID0gdmFsdWUgPT4ge1xuICAgIGlmICghaXNTdHJpbmcod2hlblZpc2libGUpICYmICFzdHJpbmdDb250YWlucyh3aGVuVmlzaWJsZSwgJyUnKSkge1xuICAgICAgZXJyb3JMb2cobmFtZVNwYWNlLCAnQmUgc3VyZSB0byBzZXQgYSBwZXJjZW50YWdlIGFzIGEgc3RyaW5nLiB7IHdoZW5WaXNpYmxlOiBcIjUwJVwiIH0nKVxuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlSW50KHZhbHVlLnJlcGxhY2UoJyUnLCAnJykpIC8gMTAwXG5cbiAgICByYXRpbyA9IHBhcnNlZFxuXG4gICAgcmV0dXJuIHBhcnNlZFxuICB9XG5cbiAgY29uc3QgZ2V0VGhyZXNvbGRzID0gKCkgPT4ge1xuICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgb25lOiBbMCwgMV0sXG4gICAgICBnc2FwOiBjcmVhdGVBcnJheSgxOTkpLFxuICAgIH1cblxuICAgIGxldCByZXR1cm5lZFRocmVzaG9sZHM6IGFueSA9IGRlZmF1bHRzLm9uZVxuXG4gICAgaWYgKHdoZW5WaXNpYmxlKSB7XG4gICAgICByZXR1cm5lZFRocmVzaG9sZHMgPSBnZXRQZXJjZW50YWdlKHdoZW5WaXNpYmxlKVxuICAgIH1cblxuICAgIGlmICh1c2VEdXJhdGlvbikge1xuICAgICAgcmV0dXJuZWRUaHJlc2hvbGRzID0gZGVmYXVsdHMuZ3NhcFxuICAgIH1cblxuICAgIGlmICh0aHJlc2hvbGRzKSB7XG4gICAgICByZXR1cm5lZFRocmVzaG9sZHMgPSBjcmVhdGVBcnJheSh0aHJlc2hvbGRzKVxuICAgIH1cblxuICAgIHJldHVybiByZXR1cm5lZFRocmVzaG9sZHNcbiAgfVxuXG4gIGNvbnN0IE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKG9ic2VydmVyQ2FsbGJhY2ssIHtcbiAgICB0aHJlc2hvbGQ6IGdldFRocmVzb2xkcygpLFxuICAgIHJvb3RNYXJnaW46IHNldFJvb3RNYXJnaW4sXG4gICAgLi4ub2JzZXJ2ZXIsXG4gIH0pXG5cbiAgdGhpcy5pbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgT2JzZXJ2ZXIub2JzZXJ2ZSh0cmlnZ2VyRWxlbWVudClcbiAgfVxuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0cmlnZ2VyRWxlbWVudCAmJiBPYnNlcnZlcikge1xuICAgICAgaWYgKHNldFRvZ2dsZSkge1xuICAgICAgICBzZXRUb2dnbGUucmVtb3ZlKClcbiAgICAgIH1cblxuICAgICAgaWYgKHNldEdzYXApIHtcbiAgICAgICAgc2V0R3NhcC5raWxsKClcbiAgICAgIH1cblxuICAgICAgaWYgKHNldFZpZGVvKSB7XG4gICAgICAgIHNldFZpZGVvLmtpbGwoKVxuICAgICAgfVxuXG4gICAgICBPYnNlcnZlci51bm9ic2VydmUodHJpZ2dlckVsZW1lbnQpXG4gICAgfVxuICB9XG5cbiAgc2Nyb2xsQW5pbWF0aW9uSW5pdChicmVha3BvaW50cywgdGhpcy5pbml0LCB0aGlzLmRlc3Ryb3kpXG59XG5cbmV4cG9ydCB7IFNjcm9sbE9ic2VydmVyIH1cbiJdfQ==