scrollscene
Version:
ScrollScene is an extra layer on top of ScrollMagic as well as using IntersectionObserver to achieve similar effects.
344 lines (273 loc) • 40.6 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ScrollObserver = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _helpers = require("./helpers");
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) { (0, _defineProperty2["default"])(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; }
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) {
(0, _helpers.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) {
(0, _helpers.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) {
(0, _helpers.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) {
(0, _helpers.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) {
(0, _helpers.errorLog)(nameSpace, "Be sure to set a callback active or notActive function in the new ".concat(nameSpace, "({ callback: { active: () => () } })"));
}
if (callback.active && !(0, _helpers.isFunc)(callback.active) || callback.notActive && !(0, _helpers.isFunc)(callback.notActive)) {
(0, _helpers.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) {
(0, _helpers.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 && (0, _helpers.isObject)(toggle)) {
setToggle = new setClassName(toggle);
}
if (gsap && (0, _helpers.isObject)(gsap)) {
setGsap = new setTween(gsap);
}
if (video && (0, _helpers.isObject)(video)) {
setVideo = new setPlayer(video);
}
if (callback && (0, _helpers.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 (!(0, _helpers.isString)(whenVisible) && !(0, _helpers.stringContains)(whenVisible, '%')) {
(0, _helpers.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: (0, _helpers.createArray)(199)
};
var returnedThresholds = defaults.one;
if (whenVisible) {
returnedThresholds = getPercentage(whenVisible);
}
if (useDuration) {
returnedThresholds = defaults.gsap;
}
if (thresholds) {
returnedThresholds = (0, _helpers.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);
}
};
(0, _helpers.scrollAnimationInit)(breakpoints, this.init, this.destroy);
};
exports.ScrollObserver = ScrollObserver;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TY3JvbGxPYnNlcnZlci50cyJdLCJuYW1lcyI6WyJuYW1lU3BhY2UiLCJzdGF0ZSIsInZpc2libGUiLCJhbHJlYWR5RmlyZWQiLCJzZXRDbGFzc05hbWUiLCJvcHRpb25zIiwidG9nZ2xlIiwiZWxlbWVudCIsImNsYXNzTmFtZSIsImFkZCIsImNsYXNzTGlzdCIsImNvbnRhaW5zIiwicmVtb3ZlIiwidXBkYXRlIiwic2V0U3RhdGUiLCJzZXRUd2VlbiIsImdzYXAiLCJ0aW1lbGluZSIsInlveW8iLCJzcGVlZCIsInJldmVyc2VTcGVlZCIsImRlbGF5IiwidGwiLCJyZXBlYXQiLCJyZXBlYXREZWxheSIsInBsYXkiLCJ0aW1lU2NhbGUiLCJwYXVzZSIsInJldmVyc2UiLCJraWxsIiwic2NydWIiLCJpbnRlcnNlY3Rpb25SYXRpbyIsInByb2dyZXNzIiwic2V0UGxheWVyIiwidmlkZW8iLCJwbGF5aW5nQ2xhc3NOYW1lIiwicGF1c2VkQ2xhc3NOYW1lIiwiaGFuZGxlUGxheSIsInNyYyIsImhhbmRsZVBhdXNlIiwidHJ5UGxheSIsImVycm9yIiwidHJ5UGF1c2UiLCJzZXRGdW5jdGlvbiIsImNhbGxiYWNrIiwiYWN0aXZlIiwibm90QWN0aXZlIiwiU2Nyb2xsT2JzZXJ2ZXIiLCJicmVha3BvaW50cyIsImRlc3Ryb3lJbW1lZGlhdGVseSIsIm9ic2VydmVyIiwib2Zmc2V0Iiwid2hlblZpc2libGUiLCJ0aHJlc2hvbGRzIiwidHJpZ2dlckVsZW1lbnQiLCJ1c2VEdXJhdGlvbiIsIiR0aGlzIiwic2V0VG9nZ2xlIiwic2V0R3NhcCIsInNldFZpZGVvIiwic2V0Q2FsbGJhY2siLCJyYXRpbyIsInNldFJvb3RNYXJnaW4iLCJNYXRoIiwiYWJzIiwicGFyc2VGbG9hdCIsIm9ic2VydmVyQ2FsbGJhY2siLCJlbnRyaWVzIiwiZm9yRWFjaCIsImlzSW50ZXJzZWN0aW5nIiwiZGVzdHJveSIsImdldFBlcmNlbnRhZ2UiLCJ2YWx1ZSIsInBhcnNlZCIsInBhcnNlSW50IiwicmVwbGFjZSIsImdldFRocmVzb2xkcyIsImRlZmF1bHRzIiwib25lIiwicmV0dXJuZWRUaHJlc2hvbGRzIiwiT2JzZXJ2ZXIiLCJJbnRlcnNlY3Rpb25PYnNlcnZlciIsInRocmVzaG9sZCIsInJvb3RNYXJnaW4iLCJpbml0Iiwib2JzZXJ2ZSIsInVub2JzZXJ2ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7O0FBRUEsSUFBTUEsU0FBUyxHQUFHLGdCQUFsQjs7QUFHQSxJQUFNQyxLQUFLLEdBQUcsU0FBUkEsS0FBUSxDQUFTQyxPQUFULEVBQWtCQyxZQUFsQixFQUFnQztBQUM1QyxPQUFLRCxPQUFMLEdBQWUsS0FBZjtBQUNBLE9BQUtDLFlBQUwsR0FBb0IsS0FBcEI7QUFDRCxDQUhEOztBQUtBLElBQU1DLFlBQVksR0FBRyxTQUFmQSxZQUFlLENBQW9CQyxPQUFwQixFQUE2QjtBQUNoRCxNQUFNQyxNQUFNO0FBQ1ZDLElBQUFBLE9BQU8sRUFBRSxJQURDO0FBRVZDLElBQUFBLFNBQVMsRUFBRTtBQUZELEtBR1BILE9BSE8sQ0FBWjs7QUFNQSxNQUFJLENBQUNDLE1BQU0sQ0FBQ0MsT0FBWixFQUFxQjtBQUNuQiwyQkFDRVAsU0FERiwyR0FFb0dBLFNBRnBHO0FBSUQ7O0FBRUQsTUFBSSxDQUFDTSxNQUFNLENBQUNFLFNBQVosRUFBdUI7QUFDckIsMkJBQ0VSLFNBREYsdUVBRWdFQSxTQUZoRTtBQUlEOztBQUVELE9BQUtTLEdBQUwsR0FBVyxZQUFXO0FBRXBCLEtBQUNILE1BQU0sQ0FBQ0MsT0FBUCxDQUFlRyxTQUFmLENBQXlCQyxRQUF6QixDQUFrQ0wsTUFBTSxDQUFDRSxTQUF6QyxDQUFELElBQXdERixNQUFNLENBQUNDLE9BQVAsQ0FBZUcsU0FBZixDQUF5QkQsR0FBekIsQ0FBNkJILE1BQU0sQ0FBQ0UsU0FBcEMsQ0FBeEQ7QUFDRCxHQUhEOztBQUtBLE9BQUtJLE1BQUwsR0FBYyxZQUFXO0FBRXZCTixJQUFBQSxNQUFNLENBQUNDLE9BQVAsQ0FBZUcs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LEdBRkQ7O0FBSUEsT0FBS2dCLE9BQUwsR0FBZSxZQUFXO0FBQ3hCLFFBQUloQixjQUFjLElBQUkwQixRQUF0QixFQUFnQztBQUM5QixVQUFJdkIsU0FBSixFQUFlO0FBQ2JBLFFBQUFBLFNBQVMsQ0FBQzdDLE1BQVY7QUFDRDs7QUFFRCxVQUFJOEMsT0FBSixFQUFhO0FBQ1hBLFFBQUFBLE9BQU8sQ0FBQzdCLElBQVI7QUFDRDs7QUFFRCxVQUFJOEIsUUFBSixFQUFjO0FBQ1pBLFFBQUFBLFFBQVEsQ0FBQzlCLElBQVQ7QUFDRDs7QUFFRG1ELE1BQUFBLFFBQVEsQ0FBQ00sU0FBVCxDQUFtQmhDLGNBQW5CO0FBQ0Q7QUFDRixHQWhCRDs7QUFrQkEsb0NBQW9CTixXQUFwQixFQUFpQyxLQUFLb0MsSUFBdEMsRUFBNEMsS0FBS2QsT0FBakQ7QUFDRCxDQW5LRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVycm9yTG9nLCBpc0Z1bmMsIGlzT2JqZWN0LCBzY3JvbGxBbmltYXRpb25Jbml0LCBjcmVhdGVBcnJheSwgaXNTdHJpbmcsIHN0cmluZ0NvbnRhaW5zIH0gZnJvbSAnLi9oZWxwZXJzJ1xuXG5jb25zdCBuYW1lU3BhY2UgPSAnU2Nyb2xsT2JzZXJ2ZXInXG5cbi8vIEB0cy1pZ25vcmVcbmNvbnN0IHN0YXRlID0gZnVuY3Rpb24odmlzaWJsZSwgYWxyZWFkeUZpcmVkKSB7XG4gIHRoaXMudmlzaWJsZSA9IGZhbHNlXG4gIHRoaXMuYWxyZWFkeUZpcmVkID0gZmFsc2Vcbn1cblxuY29uc3Qgc2V0Q2xhc3NOYW1lID0gZnVuY3Rpb24odGhpczogYW55LCBvcHRpb25zKSB7XG4gIGNvbnN0IHRvZ2dsZSA9IHtcbiAgICBlbGVtZW50OiBudWxsLFxuICAgIGNsYXNzTmFtZTogbnVsbCxcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgaWYgKCF0b2dnbGUuZWxlbWVudCkge1xuICAgIGVycm9yTG9nKFxuICAgICAgbmFtZVNwYWNlLFxuICAgICAgYEJlIHN1cmUgdG8gc2V0IGEgY29uc3QgdG9nZ2xlRWxlbWVudCA9IChyZWFjdFJlZi5jdXJyZW50IG9yIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IpIGluIHRoZSBuZXcgJHtuYW1lU3BhY2V9KHsgdG9nZ2xlOiB7IGVsZW1lbnQ6IHRvZ2dsZUVsZW1lbnQgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgaWYgKCF0b2dnbGUuY2xhc3NOYW1lKSB7XG4gICAgZXJyb3JMb2coXG4gICAgICBuYW1lU3BhY2UsXG4gICAgICBgQmUgc3VyZSB0byBzZXQgdGhlIGNsYXNzTmFtZSB5b3Ugd2FudCB0byB0b2dnbGUgaW4gdGhlIG5ldyAke25hbWVTcGFjZX0oeyB0b2dnbGU6IHsgY2xhc3NOYW1lOiBcIm15LWNsYXNzXCIgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgdGhpcy5hZGQgPSBmdW5jdGlvbigpIHtcbiAgICAvKiBhZGQgY2xhc3NOYW1lIGlmIGl0J3Mgbm90IGFscmVhZHkgdGhlcmUgKi9cbiAgICAhdG9nZ2xlLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKHRvZ2dsZS5jbGFzc05hbWUpICYmIHRvZ2dsZS5lbGVtZW50LmNsYXNzTGlzdC5hZGQodG9nZ2xlLmNsYXNzTmFtZSlcbiAgfVxuXG4gIHRoaXMucmVtb3ZlID0gZnVuY3Rpb24oKSB7XG4gICAgLyogcmVtb3ZlIGNsYXNzTmFtZSBpZiBpdCdzIHRoZXJlICovXG4gICAgdG9nZ2xlLmVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKHRvZ2dsZS5jbGFzc05hbWUpICYmIHRvZ2dsZS5lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUodG9nZ2xlLmNsYXNzTmFtZSlcbiAgfVxuXG4gIHRoaXMudXBkYXRlID0gZnVuY3Rpb24oc2V0U3RhdGUpIHtcbiAgICBpZiAoIXNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiBzZXRTdGF0ZS52aXNpYmxlKSB7XG4gICAgICB0aGlzLmFkZCgpXG4gICAgfVxuXG4gICAgaWYgKHNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiAhc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgdGhpcy5yZW1vdmUoKVxuICAgIH1cbiAgfVxufVxuXG5jb25zdCBzZXRUd2VlbiA9IGZ1bmN0aW9uKHRoaXM6IGFueSwgb3B0aW9ucykge1xuICBjb25zdCBnc2FwID0ge1xuICAgIHRpbWVsaW5lOiBudWxsLFxuICAgIHlveW86IGZhbHNlLFxuICAgIHNwZWVkOiAxLFxuICAgIHJldmVyc2VTcGVlZDogMSxcbiAgICBkZWxheTogMixcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgaWYgKCFnc2FwLnRpbWVsaW5lKSB7XG4gICAgZXJyb3JMb2coXG4gICAgICBuYW1lU3BhY2UsXG4gICAgICBgQmUgc3VyZSB0byBzZXQgYSBjb25zdCB0bCA9IGdzYXAudGltZWxpbmUoeyBwYXVzZWQ6IHRydWUgfSkgaW4gdGhlIG5ldyAke25hbWVTcGFjZX0oeyBnc2FwOiB7IHRpbWVsaW5lOiB0bCB9IH0pYCxcbiAgICApXG4gIH1cblxuICBjb25zdCB0bCA9IGdzYXAudGltZWxpbmVcblxuICBpZiAoZ3NhcC55b3lvKSB7XG4gICAgdGwucmVwZWF0KC0xKVxuICAgICAgLnlveW8oZ3NhcC55b3lvKVxuICAgICAgLnJlcGVhdERlbGF5KGdzYXAuZGVsYXkpXG4gIH1cblxuICB0aGlzLnBsYXkgPSBmdW5jdGlvbigpIHtcbiAgICB0bC50aW1lU2NhbGUoZ3NhcC5zcGVlZCkucGxheSgpXG4gIH1cblxuICB0aGlzLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgdGwucGF1c2UoKVxuICB9XG5cbiAgdGhpcy5yZXZlcnNlID0gZnVuY3Rpb24oKSB7XG4gICAgdGwudGltZVNjYWxlKGdzYXAucmV2ZXJzZVNwZWVkKS5yZXZlcnNlKClcbiAgfVxuXG4gIHRoaXMua2lsbCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0bCkge1xuICAgICAgdGwucGF1c2UoMClcbiAgICAgIHRsLmtpbGwoKVxuICAgIH1cbiAgfVxuXG4gIHRoaXMudXBkYXRlID0gZnVuY3Rpb24oc2V0U3RhdGUpIHtcbiAgICBpZiAoIXNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiBzZXRTdGF0ZS52aXNpYmxlKSB7XG4gICAgICB0aGlzLnBsYXkoKVxuICAgIH1cblxuICAgIGlmIChzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgIXNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgIGdzYXAueW95byA/IHRoaXMucGF1c2UoKSA6IHRoaXMucmV2ZXJzZSgpXG4gICAgfVxuICB9XG5cbiAgdGhpcy5zY3J1YiA9IGZ1bmN0aW9uKGludGVyc2VjdGlvblJhdGlvKSB7XG4gICAgdGwucHJvZ3Jlc3MoaW50ZXJzZWN0aW9uUmF0aW8pXG4gIH1cbn1cblxuY29uc3Qgc2V0UGxheWVyID0gZnVuY3Rpb24odGhpczogYW55LCBvcHRpb25zKSB7XG4gIGNvbnN0IHZpZGVvID0ge1xuICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgcGxheWluZ0NsYXNzTmFtZTogbnVsbCxcbiAgICBwYXVzZWRDbGFzc05hbWU6IG51bGwsXG4gICAgLi4ub3B0aW9ucyxcbiAgfVxuXG4gIGlmICghdmlkZW8uZWxlbWVudCkge1xuICAgIGVycm9yTG9nKFxuICAgICAgbmFtZVNwYWNlLFxuICAgICAgYEJlIHN1cmUgdG8gc2V0IGEgdmlkZW8gZWxlbWVudCBpbiB0aGUgbmV3ICR7bmFtZVNwYWNlfSh7IHZpZGVvOiB7IGVsZW1lbnQ6IHZpZGVvUmVmLmN1cnJlbnQgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGxheSgpIHtcbiAgICBpZiAodmlkZW8uZWxlbWVudC5zcmMpIHtcbiAgICAgIHZpZGVvLmVsZW1lbnQucGxheSgpXG4gICAgICB2aWRlby5wbGF5aW5nQ2xhc3NOYW1lICYmIHZpZGVvLmVsZW1lbnQuY2xhc3NMaXN0LmFkZCh2aWRlby5wbGF5aW5nQ2xhc3NOYW1lKVxuICAgICAgdmlkZW8ucGF1c2VkQ2xhc3NOYW1lICYmIHZpZGVvLmVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSh2aWRlby5wYXVzZWRDbGFzc05hbWUpXG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGhhbmRsZVBhdXNlKCkge1xuICAgIGlmICh2aWRlby5lbGVtZW50LnNyYykge1xuICAgICAgdmlkZW8uZWxlbWVudC5wYXVzZSgpXG4gICAgICB2aWRlby5wYXVzZWRDbGFzc05hbWUgJiYgdmlkZW8uZWxlbWVudC5jbGFzc0xpc3QuYWRkKHZpZGVvLnBhdXNlZENsYXNzTmFtZSlcbiAgICAgIHZpZGVvLnBsYXlpbmdDbGFzc05hbWUgJiYgdmlkZW8uZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKHZpZGVvLnBsYXlpbmdDbGFzc05hbWUpXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdHJ5UGxheSgpIHtcbiAgICB0cnkge1xuICAgICAgaGFuZGxlUGxheSgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGhhbmRsZVBhdXNlKClcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0cnlQYXVzZSgpIHtcbiAgICB0cnkge1xuICAgICAgaGFuZGxlUGF1c2UoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7fVxuICB9XG5cbiAgdGhpcy5wbGF5ID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5UGxheSgpXG4gIH1cblxuICB0aGlzLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5UGF1c2UoKVxuICB9XG5cbiAgdGhpcy5raWxsID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5UGF1c2UoKVxuICB9XG5cbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbihzZXRTdGF0ZSkge1xuICAgIGlmICghc2V0U3RhdGUuYWxyZWFkeUZpcmVkICYmIHNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgIHRoaXMucGxheSgpXG4gICAgfVxuXG4gICAgaWYgKHNldFN0YXRlLmFscmVhZHlGaXJlZCAmJiAhc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgdGhpcy5wYXVzZSgpXG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHNldEZ1bmN0aW9uOiBhbnkgPSBmdW5jdGlvbih0aGlzOiBhbnksIG9wdGlvbnMpIHtcbiAgY29uc3QgY2FsbGJhY2sgPSB7XG4gICAgYWN0aXZlOiBudWxsLFxuICAgIG5vdEFjdGl2ZTogbnVsbCxcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgaWYgKCFjYWxsYmFjay5hY3RpdmUgJiYgIWNhbGxiYWNrLm5vdEFjdGl2ZSkge1xuICAgIGVycm9yTG9nKFxuICAgICAgbmFtZVNwYWNlLFxuICAgICAgYEJlIHN1cmUgdG8gc2V0IGEgY2FsbGJhY2sgYWN0aXZlIG9yIG5vdEFjdGl2ZSBmdW5jdGlvbiBpbiB0aGUgbmV3ICR7bmFtZVNwYWNlfSh7IGNhbGxiYWNrOiB7IGFjdGl2ZTogKCkgPT4gKCkgfSB9KWAsXG4gICAgKVxuICB9XG5cbiAgaWYgKChjYWxsYmFjay5hY3RpdmUgJiYgIWlzRnVuYyhjYWxsYmFjay5hY3RpdmUpKSB8fCAoY2FsbGJhY2subm90QWN0aXZlICYmICFpc0Z1bmMoY2FsbGJhY2subm90QWN0aXZlKSkpIHtcbiAgICBlcnJvckxvZyhuYW1lU3BhY2UsIGBCZSBzdXJlIHRvIHNldCB0aGUgY2FsbGJhY2sgYXMgYSBmdW5jdGlvbiBgKVxuICB9XG5cbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbihzZXRTdGF0ZSkge1xuICAgIGlmICghc2V0U3RhdGUuYWxyZWFkeUZpcmVkICYmIHNldFN0YXRlLnZpc2libGUgJiYgY2FsbGJhY2suYWN0aXZlKSB7XG4gICAgICBjYWxsYmFjay5hY3RpdmUoKVxuICAgIH1cblxuICAgIGlmIChzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgIXNldFN0YXRlLnZpc2libGUgJiYgY2FsbGJhY2subm90QWN0aXZlKSB7XG4gICAgICBjYWxsYmFjay5ub3RBY3RpdmUoKVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTY3JvbGxPYnNlcnZlckdzYXAge1xuICAvKipcbiAgICogdGltZWxpbmVcbiAgICogQGRlc2MgSW5zZXJ0IHlvdXIgZ3NhcC50aW1lbGluZSBvYmplY3QgdmFyXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBteVRpbWVsaW5lID0gZ3NhcC50aW1lbGluZSgpXG4gICAqIGdzYXA6IHsgdGltZWxpbmU6IG15VGltZWxpbmUgfVxuICAgKi9cbiAgdGltZWxpbmU6IGFueVxuXG4gIC8qKlxuICAgKiB5b3lvXG4gICAqIEBkZXNjIERvIHlvdSB3YW50IGdzYXAgYW5pbWF0aW9uIHRvIGxvb3AgYmFjayBhbmQgZm9ydGg/XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGVcbiAgICogZ3NhcDogeyB5b3lvOiB0cnVlIH1cbiAgICovXG4gIHlveW8/OiBib29sZWFuXG5cbiAgLyoqXG4gICAqIHNwZWVkXG4gICAqIEBkZXNjIFRoZSBzcGVlZCBhdCB3aGljaCB0aGUgZ3NhcCBhbmltYXRpb24gd2lsbCBwbGF5IHJlbGF0aXZlIHRvIGl0J3MgY3VycmVudCBzcGVlZC5cbiAgICogQHR5cGUgbnVtYmVyXG4gICAqIEBkZWZhdWx0IDFcbiAgICogQGV4YW1wbGVcbiAgICogZ3NhcDogeyBzcGVlZDogMiB9IC8vID0gdHdpY2UgYXMgZmFzdFxuICAgKi9cbiAgc3BlZWQ/OiBudW1iZXJcblxuICAvKipcbiAgICogc3BlZWRcbiAgICogQGRlc2MgVGhlIHNwZWVkIGF0IHdoaWNoIHRoZSBnc2FwIGFuaW1hdGlvbiB3aWxsIHJldmVyc2UgcmVsYXRpdmUgdG8gaXQncyBjdXJyZW50IHNwZWVkLlxuICAgKiBAdHlwZSBudW1iZXJcbiAgICogQGRlZmF1bHQgNFxuICAgKiBAZXhhbXBsZVxuICAgKiBnc2FwOiB7IHNwZWVkOiA0IH0gLy8gPSA0eCBhcyBmYXN0XG4gICAqL1xuICByZXZlcnNlU3BlZWQ/OiBudW1iZXJcblxuICAvKipcbiAgICogZGVsYXlcbiAgICogQGRlc2MgVGhlIGRlbGF5IChpbiBzZWNvbmRzKSBhdCB3aGljaCB0aGUgZ3NhcCBhbmltYXRpb24gd2FpdCBiZWZvcmUgcmV2ZXJzaW5nLlxuICAgKiBAdHlwZSBudW1iZXJcbiAgICogQGRlZmF1bHQgMlxuICAgKiBAZXhhbXBsZVxuICAgKiBnc2FwOiB7IGRlbGF5OiAzIH0gLy8gPSBXYWl0IDMgc2Vjb25kc1xuICAgKi9cbiAgZGVsYXk/OiBudW1iZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJU2Nyb2xsT2JzZXJ2ZXJUb2dnbGUge1xuICAvKipcbiAgICogY2xhc3NOYW1lXG4gICAqIEBkZXNjIFNwZWNpZnkgdGhlIGNsYXNzTmFtZSB5b3Ugd2lzaCB0byB0b2dnbGUuXG4gICAqIEB0eXBlIHN0cmluZ1xuICAgKiBAZXhhbXBsZVxuICAgKiB0b2dnbGU6IHsgY2xhc3NOYW1lOiAndHVybi1tZS1ibHVlLWJhYnknIH1cbiAgICovXG4gIGNsYXNzTmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIGVsZW1lbnRcbiAgICogQGRlc2MgU3BlY2lmeSB0aGUgZWxlbWVudCB5b3Ugd2lzaCB0byB0b2dnbGUgdGhlIGNsYXNzTmFtZSBvbi5cbiAgICogQHR5cGUgSFRNTEVsZW1lbnQgfCBhbnlcbiAgICogQGV4YW1wbGVcbiAgICogdG9nZ2xlOiB7IGVsZW1lbnQ6IGNvbnRhaW5lclJlZi5jdXJyZW50IH1cbiAgICovXG4gIGVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgYW55XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVNjcm9sbE9ic2VydmVyVmlkZW8ge1xuICAvKipcbiAgICogZWxlbWVudFxuICAgKiBAZGVzYyBTcGVjaWZ5IHRoZSB2aWRlbyBlbGVtZW50IHlvdSB3aXNoIHRvIGludGVyYWN0IHdpdGguXG4gICAqIEB0eXBlIEhUTUxFbGVtZW50IHwgYW55XG4gICAqIEBleGFtcGxlXG4gICAqIHZpZGVvOiB7IGVsZW1lbnQ6IHZpZGVvUmVmLmN1cnJlbnQgfVxuICAgKi9cbiAgZWxlbWVudDogSFRNTEVsZW1lbnQgfCBhbnlcbn1cblxuaW50ZXJmYWNlIElTY3JvbGxPYnNlcnZlciB7XG4gIC8qKlxuICAgKiBicmVha3BvaW50c1xuICAgKiBAZGVzYyBVc2UgdG8gc2V0IHJlc3BvbnNpdmVuZXNzIG9mIHRoZSBTY3JvbGxPYnNlcnZlciwgbW9iaWxlLWZpcnN0XG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBicmVha3BvaW50czogeyAwOiBmYWxzZSwgNzY4OiB0cnVlIH1cbiAgICovXG4gIGJyZWFrcG9pbnRzPzogb2JqZWN0XG5cbiAgLyoqXG4gICAqIGNhbGxiYWNrXG4gICAqIEBkZXNjIFVzZSB0byBzZXQgYSBjYWxsYmFjayB3aGVuIHRoZSBzY2VuZSBpcyBhY3RpdmUuXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBjYWxsYmFjazogeyBhY3RpdmU6ICgpID0+ICgpLCBub3RBY3RpdmU6ICgpID0+ICgpIH1cbiAgICovXG4gIGNhbGxiYWNrPzogb2JqZWN0XG5cbiAgLyoqXG4gICAqIGRlc3Ryb3lJbW1lZGlhdGVseVxuICAgKiBAZGVzYyBVc2UgdG8gZGVzdHJveSB0aGUgc2NlbmUgaW1tZWRpYXRlbHkgYWZ0ZXIgZmlyaW5nIG9uY2UgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZS5cbiAgICogQHR5cGUgYm9vbGVhblxuICAgKiBAZXhhbXBsZVxuICAgKiBkZXN0cm95SW1tZWRpYXRlbHk6IHRydWVcbiAgICovXG4gIGRlc3Ryb3lJbW1lZGlhdGVseT86IGJvb2xlYW5cblxuICAvKipcbiAgICogZ3NhcFxuICAgKiBAZGVzYyBVc2UgdG8gc2V0IG9wdGlvbnMgZm9yIHRoZSBnc2FwIGFuaW1hdGlvbiBvZiB0aGUgU2Nyb2xsT2JzZXJ2ZXIuXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiBnc2FwOiB7IHRpbWVsaW5lOiBteVRpbWVsaW5lLCB5b3lvOiB0cnVlLCByZXZlcnNlU3BlZWQ6IDIgfVxuICAgKi9cbiAgZ3NhcD86IElTY3JvbGxPYnNlcnZlckdzYXBcblxuICAvKipcbiAgICogb2JzZXJ2ZXJcbiAgICogQGRlc2MgRXh0cmEgb3B0aW9ucyB0byBwYXNzIHRoZSBJbnRlcnNlY3Rpb25PYnNlcnZlciwgbGlrZSByb290LCByb290TWFyZ2luLCB0aHJlc2hvbGQgKHRvIG92ZXJyaWRlIHRoZSB0aHJlc2hvbGRzIG9wdGlvbilcbiAgICogQHR5cGUgb2JqZWN0XG4gICAqIEBleGFtcGxlXG4gICAqIG9ic2VydmVyOiB7IHJvb3RNYXJnaW46ICctNTAlIDAlJyB9XG4gICAqL1xuICBvYnNlcnZlcj86IG9iamVjdFxuXG4gIC8qKlxuICAgKiBvZmZzZXRcbiAgICogQGRlc2MgQ2hhbmdlIHRoZSBvZmZzZXQuIFRoaXMgdXNlcyByb290TWFyZ2luIHRodXMgb25seSB3b3JrcyBhcyBhIG5lZ2F0aXZlIG9mZnNldC5cbiAgICogQHR5cGUgbnVtYmVyIHwgc3RyaW5nXG4gICAqIEBkZWZhdWx0dmFsdWUgJzAlIDAlJ1xuICAgKiBAZXhhbXBsZVxuICAgKiBvZmZzZXQ6IDUwMCAvLyB0aGlzIHdpbGwgYmUgcm9vdE1hcmdpbjogJy01MDBweCAwJSdcbiAgICovXG4gIG9mZnNldD86IG51bWJlciB8IHN0cmluZ1xuXG4gIC8qKlxuICAgKiB0aHJlc2hvbGRzXG4gICAqIEBkZXNjIFNldCB0aGUgbnVtYmVyIG9mIHRocmVzaG9sZHMgeW91IHdhbnQuXG4gICAqIEByZXR1cm5zIEFuIEFycmF5IG9mIG51bWJlciBmcm9tIDAgdG8gMS4gQWRkIDEgdG8geW91ciBudW1iZXIgdG8gYWNjb3VudCBmb3IgMC5cbiAgICogQHR5cGUgbnVtYmVyXG4gICAqIEBleGFtcGxlXG4gICAqIHRocmVzaG9sZHM6IDEgPSBbMCwgMV1cbiAgICogdGhyZXNob2xkczogMiA9IFswLCAwLjUsIDFdXG4gICAqIHRocmVzaG9sZHM6IDMgPSBbMCwgMC4zMywgMC42NywgMV1cbiAgICogdGhyZXNob2xkczogMTAwID0gWzAsIDAuMSwgMC4yLCAuLi4gMC45OCwgMC45OSwgMV1cbiAgICovXG4gIHRocmVzaG9sZHM/OiBudW1iZXJcblxuICAvKipcbiAgICogdG9nZ2xlXG4gICAqIEBkZXNjIFVzZSB0byBzZXQgdGhlIG9wdGlvbnMgZm9yIHRoZSB0b2dnbGluZyBvZiBhIGNsYXNzTmFtZVxuICAgKiBAdHlwZSBvYmplY3RcbiAgICogQGV4YW1wbGVcbiAgICogdG9nZ2xlOiB7IGVsZW1lbnQ6IGNvbnRhaW5lclJlZi5jdXJyZW50LCBjbGFzc05hbWU6ICdsZXRzLWRvLXRoaXMnIH1cbiAgICovXG4gIHRvZ2dsZT86IElTY3JvbGxPYnNlcnZlclRvZ2dsZVxuXG4gIC8qKlxuICAgKiB0cmlnZ2VyRWxlbWVudFxuICAgKiBAZGVzYyBTZXQgdGhlIGVsZW1lbnQgeW91IHdpc2ggdG8gdHJpZ2dlciBldmVudHMgYmFzZWQgdXBvbiwgdGhlIG9ic2VydmVkIGVsZW1lbnQuXG4gICAqIEB0eXBlIEhUTUxFbGVtZW50IHwgYW55XG4gICAqIEBleGFtcGxlXG4gICAqIHRyaWdnZXJFbGVtZW50OiB0cmlnZ2VyUmVmLmN1cnJlbnRcbiAgICovXG4gIHRyaWdnZXJFbGVtZW50OiBIVE1MRWxlbWVudCB8IGFueVxuXG4gIC8qKlxuICAgKiB1c2VEdXJhdGlvblxuICAgKiBAZGVzYyBVc2UgdGhlIHBlcmNlbnRhZ2Ugb2YgZWxlbWVudCB2aXNpYmlsaXR5IHRvIHNjcnViIHRoZSBnc2FwIHRpbWVsaW5lLlxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqIEBleGFtcGxlXG4gICAqIHVzZUR1cmF0aW9uOiB0cnVlXG4gICAqL1xuICB1c2VEdXJhdGlvbj86IGJvb2xlYW5cblxuICAvKipcbiAgICogdmlkZW9cbiAgICogQGRlc2MgVXNlIHRvIHNldCB0aGUgb3B0aW9ucyBmb3IgcGxheWluZyBhbmQgcGF1c2luZyBvZiB0aGUgdmlkZW8uXG4gICAqIEB0eXBlIG9iamVjdFxuICAgKiBAZXhhbXBsZVxuICAgKiB2aWRlbzogeyBlbGVtZW50OiB2aWRlb1JlZi5jdXJyZW50IH1cbiAgICovXG4gIHZpZGVvPzogSVNjcm9sbE9ic2VydmVyVmlkZW9cblxuICAvKipcbiAgICogd2hlblZpc2libGVcbiAgICogQGRlc2MgU2V0IHdoZW4gdGhlIHNjZW5lIHNob3VsZCBiZSBhY3RpdmUgYmFzZWQgb24gdGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGVsZW1lbnQgdmlzaWJsZVxuICAgKiBAdHlwZSBudW1iZXJcbiAgICogQGV4YW1wbGVcbiAgICogd2hlblZpc2libGU6ICc1MCUnXG4gICAqL1xuICB3aGVuVmlzaWJsZT86IHN0cmluZ1xufVxuXG5jb25zdCBTY3JvbGxPYnNlcnZlciA9IGZ1bmN0aW9uKFxuICB0aGlzOiBhbnksXG4gIHtcbiAgICBicmVha3BvaW50cyxcbiAgICBjYWxsYmFjayxcbiAgICBkZXN0cm95SW1tZWRpYXRlbHksXG4gICAgZ3NhcCxcbiAgICBvYnNlcnZlcixcbiAgICBvZmZzZXQsXG4gICAgd2hlblZpc2libGUsXG4gICAgdGhyZXNob2xkcyxcbiAgICB0b2dnbGUsXG4gICAgdHJpZ2dlckVsZW1lbnQsXG4gICAgdXNlRHVyYXRpb24sXG4gICAgdmlkZW8sXG4gIH06IElTY3JvbGxPYnNlcnZlcixcbikge1xuICBpZiAoIXRyaWdnZXJFbGVtZW50KSB7XG4gICAgZXJyb3JMb2coXG4gICAgICBuYW1lU3BhY2UsXG4gICAgICAnQmUgc3VyZSB0byBzZXQgYSBjb25zdCB0cmlnZ2VyRWxlbWVudCA9IChyZWFjdFJlZi5jdXJyZW50IG9yIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IpIGluIHRoZSBuZXcgU2Nyb2xsU2NlbmUoeyB0cmlnZ2VyRWxlbWVudDogdHJpZ2dlckVsZW1lbnQgfSknLFxuICAgIClcbiAgfVxuXG4gIGNvbnN0ICR0aGlzID0gdGhpc1xuICBsZXQgc2V0VG9nZ2xlXG4gIGxldCBzZXRHc2FwXG4gIGxldCBzZXRWaWRlb1xuICBsZXQgc2V0Q2FsbGJhY2tcbiAgbGV0IHJhdGlvXG4gIGxldCBzZXRSb290TWFyZ2luID0gJzAlIDAlJ1xuICBsZXQgc2V0U3RhdGUgPSBuZXcgc3RhdGUoZmFsc2UsIGZhbHNlKVxuXG4gIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnbnVtYmVyJykge1xuICAgIC8vIHByb3RlY3QgYWdhaW5zdCBwb3NpdGl2ZSBweCB2YWx1ZXMsIGZvciBub3dcbiAgICBzZXRSb290TWFyZ2luID0gYC0ke01hdGguYWJzKG9mZnNldCl9cHggMCVgXG4gIH0gZWxzZSBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBwcm90ZWN0IGFnYWluc3QgcG9zaXRpdmUgcGVyY2VudGFnZSB2YWx1ZXMsIGZvciBub3dcbiAgICBzZXRSb290TWFyZ2luID0gYC0ke01hdGguYWJzKHBhcnNlRmxvYXQob2Zmc2V0KSl9JSAwJWBcbiAgfVxuXG4gIGlmICh0b2dnbGUgJiYgaXNPYmplY3QodG9nZ2xlKSkge1xuICAgIHNldFRvZ2dsZSA9IG5ldyBzZXRDbGFzc05hbWUodG9nZ2xlKVxuICB9XG5cbiAgaWYgKGdzYXAgJiYgaXNPYmplY3QoZ3NhcCkpIHtcbiAgICBzZXRHc2FwID0gbmV3IHNldFR3ZWVuKGdzYXApXG4gIH1cblxuICBpZiAodmlkZW8gJiYgaXNPYmplY3QodmlkZW8pKSB7XG4gICAgc2V0VmlkZW8gPSBuZXcgc2V0UGxheWVyKHZpZGVvKVxuICB9XG5cbiAgaWYgKGNhbGxiYWNrICYmIGlzT2JqZWN0KGNhbGxiYWNrKSkge1xuICAgIHNldENhbGxiYWNrID0gbmV3IHNldEZ1bmN0aW9uKGNhbGxiYWNrKVxuICB9XG5cbiAgY29uc3Qgb2JzZXJ2ZXJDYWxsYmFjayA9IGZ1bmN0aW9uKGVudHJpZXMpIHtcbiAgICBlbnRyaWVzLmZvckVhY2goKHsgaXNJbnRlcnNlY3RpbmcsIGludGVyc2VjdGlvblJhdGlvIH0pID0+IHtcbiAgICAgIC8qXG4gICAgICAgKiBUbyBoZWxwIHRoZSB3b25raW5lc3Mgb2YgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIsIGlzSW50ZXJzZWN0aW5nIGZpcmluZyB0cnVlIHdoZW4gaXQncyByZWFsbHkgZmFsc2VcbiAgICAgICAqL1xuICAgICAgaWYgKHJhdGlvKSB7XG4gICAgICAgIHNldFN0YXRlLnZpc2libGUgPSBpbnRlcnNlY3Rpb25SYXRpbyA+PSByYXRpb1xuICAgICAgfSBlbHNlIGlmIChpc0ludGVyc2VjdGluZyAmJiAhc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUbyBoZWxwIHdpdGggc2V0Q2FsbGJhY2sgYW5kIGlnbm9yaW5nIHJlZmlyaW5nIGV4dHJhIGZ1bmN0aW9uXG4gICAgICAgICAqIGNhbGxzIGR1ZSB0byBpbnRlcnNlY3Rpb25SYXRpb1xuICAgICAgICAgKi9cbiAgICAgICAgc2V0U3RhdGUudmlzaWJsZSA9IHRydWVcbiAgICAgIH0gZWxzZSBpZiAoIWlzSW50ZXJzZWN0aW5nICYmIHNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgICAgc2V0U3RhdGUudmlzaWJsZSA9IGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHNldFRvZ2dsZSAmJiBzZXRUb2dnbGUudXBkYXRlKHNldFN0YXRlKVxuICAgICAgc2V0R3NhcCAmJiAoIXVzZUR1cmF0aW9uID8gc2V0R3NhcC51cGRhdGUoc2V0U3RhdGUpIDogc2V0R3NhcC5zY3J1YihpbnRlcnNlY3Rpb25SYXRpbykpXG4gICAgICBzZXRWaWRlbyAmJiBzZXRWaWRlby51cGRhdGUoc2V0U3RhdGUpXG4gICAgICBzZXRDYWxsYmFjayAmJiBzZXRDYWxsYmFjay51cGRhdGUoc2V0U3RhdGUpXG5cbiAgICAgIC8qXG4gICAgICAgKiBUbyBoZWxwIHdpdGggaWdub3JpbmcgcmVmaXJpbmcgZXh0cmEgZnVuY3Rpb25cbiAgICAgICAqL1xuICAgICAgaWYgKCFzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgc2V0U3RhdGUudmlzaWJsZSkge1xuICAgICAgICBzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgPSB0cnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChzZXRTdGF0ZS5hbHJlYWR5RmlyZWQgJiYgIXNldFN0YXRlLnZpc2libGUpIHtcbiAgICAgICAgc2V0U3RhdGUuYWxyZWFkeUZpcmVkID0gZmFsc2VcbiAgICAgIH1cblxuICAgICAgaWYgKGlzSW50ZXJzZWN0aW5nICYmIGRlc3Ryb3lJbW1lZGlhdGVseSkge1xuICAgICAgICAvKlxuICAgICAgICAgKiBkZXN0cm95IHRoZSBzY2VuZSBhZnRlciB1c2VkIG9uY2VcbiAgICAgICAgICovXG4gICAgICAgICR0aGlzLmRlc3Ryb3koKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBnZXRQZXJjZW50YWdlID0gdmFsdWUgPT4ge1xuICAgIGlmICghaXNTdHJpbmcod2hlblZpc2libGUpICYmICFzdHJpbmdDb250YWlucyh3aGVuVmlzaWJsZSwgJyUnKSkge1xuICAgICAgZXJyb3JMb2cobmFtZVNwYWNlLCAnQmUgc3VyZSB0byBzZXQgYSBwZXJjZW50YWdlIGFzIGEgc3RyaW5nLiB7IHdoZW5WaXNpYmxlOiBcIjUwJVwiIH0nKVxuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlSW50KHZhbHVlLnJlcGxhY2UoJyUnLCAnJykpIC8gMTAwXG5cbiAgICByYXRpbyA9IHBhcnNlZFxuXG4gICAgcmV0dXJuIHBhcnNlZFxuICB9XG5cbiAgY29uc3QgZ2V0VGhyZXNvbGRzID0gKCkgPT4ge1xuICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgb25lOiBbMCwgMV0sXG4gICAgICBnc2FwOiBjcmVhdGVBcnJheSgxOTkpLFxuICAgIH1cblxuICAgIGxldCByZXR1cm5lZFRocmVzaG9sZHM6IGFueSA9IGRlZmF1bHRzLm9uZVxuXG4gICAgaWYgKHdoZW5WaXNpYmxlKSB7XG4gICAgICByZXR1cm5lZFRocmVzaG9sZHMgPSBnZXRQZXJjZW50YWdlKHdoZW5WaXNpYmxlKVxuICAgIH1cblxuICAgIGlmICh1c2VEdXJhdGlvbikge1xuICAgICAgcmV0dXJuZWRUaHJlc2hvbGRzID0gZGVmYXVsdHMuZ3NhcFxuICAgIH1cblxuICAgIGlmICh0aHJlc2hvbGRzKSB7XG4gICAgICByZXR1cm5lZFRocmVzaG9sZHMgPSBjcmVhdGVBcnJheSh0aHJlc2hvbGRzKVxuICAgIH1cblxuICAgIHJldHVybiByZXR1cm5lZFRocmVzaG9sZHNcbiAgfVxuXG4gIGNvbnN0IE9ic2VydmVyID0gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKG9ic2VydmVyQ2FsbGJhY2ssIHtcbiAgICB0aHJlc2hvbGQ6IGdldFRocmVzb2xkcygpLFxuICAgIHJvb3RNYXJnaW46IHNldFJvb3RNYXJnaW4sXG4gICAgLi4ub2JzZXJ2ZXIsXG4gIH0pXG5cbiAgdGhpcy5pbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgT2JzZXJ2ZXIub2JzZXJ2ZSh0cmlnZ2VyRWxlbWVudClcbiAgfVxuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0cmlnZ2VyRWxlbWVudCAmJiBPYnNlcnZlcikge1xuICAgICAgaWYgKHNldFRvZ2dsZSkge1xuICAgICAgICBzZXRUb2dnbGUucmVtb3ZlKClcbiAgICAgIH1cblxuICAgICAgaWYgKHNldEdzYXApIHtcbiAgICAgICAgc2V0R3NhcC5raWxsKClcbiAgICAgIH1cblxuICAgICAgaWYgKHNldFZpZGVvKSB7XG4gICAgICAgIHNldFZpZGVvLmtpbGwoKVxuICAgICAgfVxuXG4gICAgICBPYnNlcnZlci51bm9ic2VydmUodHJpZ2dlckVsZW1lbnQpXG4gICAgfVxuICB9XG5cbiAgc2Nyb2xsQW5pbWF0aW9uSW5pdChicmVha3BvaW50cywgdGhpcy5pbml0LCB0aGlzLmRlc3Ryb3kpXG59XG5cbmV4cG9ydCB7IFNjcm9sbE9ic2VydmVyIH1cbiJdfQ==