From b5c7d1ef89ecfa7b7d38b8b3a345242378c73a26 Mon Sep 17 00:00:00 2001 From: Alexandru Naiman Date: Tue, 19 Jun 2018 01:36:51 +0300 Subject: [PATCH 1/6] check if the content and the wrapper exists before computing the sizes of the container avoiding componentDidMount errors when calling scrollToBottom/refresh --- src/js/ScrollArea.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/js/ScrollArea.jsx b/src/js/ScrollArea.jsx index ffe3484..e0c5526 100644 --- a/src/js/ScrollArea.jsx +++ b/src/js/ScrollArea.jsx @@ -370,10 +370,10 @@ export default class ScrollArea extends React.Component { } computeSizes() { - let realHeight = this.content.offsetHeight; - let containerHeight = this.wrapper.offsetHeight; - let realWidth = this.content.offsetWidth; - let containerWidth = this.wrapper.offsetWidth; + let realHeight = (this.content) ? this.content.offsetHeight : 0; + let containerHeight = (this.wrapper) ? this.wrapper.offsetHeight : 0; + let realWidth = (this.content) ? this.content.offsetWidth : 0; + let containerWidth = (this.content) ? this.wrapper.offsetWidth : 0; return { realHeight: realHeight, From 89e41a650d3c2350bb5aa8444786932bd0ad86bd Mon Sep 17 00:00:00 2001 From: Alexandru Naiman Date: Wed, 20 Jun 2018 11:41:11 +0300 Subject: [PATCH 2/6] check if the content and the wrapper exists before computing the sizes of the container avoiding componentDidMount errors when calling scrollToBottom/refresh --- dist/css/scrollArea.css | 59 + dist/no-css.js | 3823 +++++++++++++++++++++++++++++++++++ dist/scrollArea.js | 4173 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 8055 insertions(+) create mode 100644 dist/css/scrollArea.css create mode 100644 dist/no-css.js create mode 100644 dist/scrollArea.js diff --git a/dist/css/scrollArea.css b/dist/css/scrollArea.css new file mode 100644 index 0000000..4a39fe6 --- /dev/null +++ b/dist/css/scrollArea.css @@ -0,0 +1,59 @@ +.scrollarea-content { + margin: 0; + padding: 0; + overflow: hidden; + position: relative; +} +.scrollarea-content:focus { + outline: 0; +} +.scrollarea { + position: relative; + overflow: hidden; +} +.scrollarea .scrollbar-container { + position: absolute; + background: none; + opacity: .1; + z-index: 9999; + -webkit-transition: all .4s; + -moz-transition: all .4s; + -ms-transition: all .4s; + -o-transition: all .4s; + transition: all .4s; +} +.scrollarea .scrollbar-container.horizontal { + width: 100%; + height: 10px; + left: 0; + bottom: 0; +} +.scrollarea .scrollbar-container.horizontal .scrollbar { + width: 20px; + height: 8px; + background: black; + margin-top: 1px; +} +.scrollarea .scrollbar-container.vertical { + width: 10px; + height: 100%; + right: 0; + top: 0; +} +.scrollarea .scrollbar-container.vertical .scrollbar { + width: 8px; + height: 20px; + background: black; + margin-left: 1px; +} +.scrollarea .scrollbar-container:hover { + background: gray; + opacity: .6 !important; +} +.scrollarea .scrollbar-container.active { + background: gray; + opacity: .6 !important; +} +.scrollarea:hover .scrollbar-container { + opacity: .3; +} diff --git a/dist/no-css.js b/dist/no-css.js new file mode 100644 index 0000000..62acd05 --- /dev/null +++ b/dist/no-css.js @@ -0,0 +1,3823 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("react")); + else if(typeof define === 'function' && define.amd) + define(["react"], factory); + else if(typeof exports === 'object') + exports["ScrollArea"] = factory(require("react")); + else + root["ScrollArea"] = factory(root["React"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_2__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _ScrollArea = __webpack_require__(1); + + var _ScrollArea2 = _interopRequireDefault(_ScrollArea); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + exports.default = _ScrollArea2.default; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _react = __webpack_require__(2); + + var _react2 = _interopRequireDefault(_react); + + var _propTypes = __webpack_require__(3); + + var _propTypes2 = _interopRequireDefault(_propTypes); + + var _lineHeight2 = __webpack_require__(10); + + var _lineHeight3 = _interopRequireDefault(_lineHeight2); + + var _reactMotion = __webpack_require__(12); + + var _utils = __webpack_require__(27); + + var _Scrollbar = __webpack_require__(28); + + var _Scrollbar2 = _interopRequireDefault(_Scrollbar); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var eventTypes = { + wheel: 'wheel', + api: 'api', + touch: 'touch', + touchEnd: 'touchEnd', + mousemove: 'mousemove', + keyPress: 'keypress' + }; + + var ScrollArea = function (_React$Component) { + _inherits(ScrollArea, _React$Component); + + function ScrollArea(props) { + _classCallCheck(this, ScrollArea); + + var _this = _possibleConstructorReturn(this, (ScrollArea.__proto__ || Object.getPrototypeOf(ScrollArea)).call(this, props)); + + _this.state = { + topPosition: 0, + leftPosition: 0, + realHeight: 0, + containerHeight: 0, + realWidth: 0, + containerWidth: 0 + }; + + _this.scrollArea = { + refresh: function refresh() { + _this.setSizesToState(); + }, + scrollTop: function scrollTop() { + _this.scrollTop(); + }, + scrollBottom: function scrollBottom() { + _this.scrollBottom(); + }, + scrollYTo: function scrollYTo(position) { + _this.scrollYTo(position); + }, + scrollLeft: function scrollLeft() { + _this.scrollLeft(); + }, + scrollRight: function scrollRight() { + _this.scrollRight(); + }, + scrollXTo: function scrollXTo(position) { + _this.scrollXTo(position); + } + }; + + _this.evntsPreviousValues = { + clientX: 0, + clientY: 0, + deltaX: 0, + deltaY: 0 + }; + + _this.bindedHandleWindowResize = _this.handleWindowResize.bind(_this); + return _this; + } + + _createClass(ScrollArea, [{ + key: 'getChildContext', + value: function getChildContext() { + return { + scrollArea: this.scrollArea + }; + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + if (this.props.contentWindow) { + this.props.contentWindow.addEventListener("resize", this.bindedHandleWindowResize); + } + this.lineHeightPx = (0, _lineHeight3.default)((0, _utils.findDOMNode)(this.content)); + this.setSizesToState(); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + if (this.props.contentWindow) { + this.props.contentWindow.removeEventListener("resize", this.bindedHandleWindowResize); + } + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + this.setSizesToState(); + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var _props = this.props, + children = _props.children, + className = _props.className, + contentClassName = _props.contentClassName, + ownerDocument = _props.ownerDocument; + + var withMotion = this.props.smoothScrolling && (this.state.eventType === eventTypes.wheel || this.state.eventType === eventTypes.api || this.state.eventType === eventTypes.touchEnd || this.state.eventType === eventTypes.keyPress); + + var scrollbarY = this.canScrollY() ? _react2.default.createElement(_Scrollbar2.default, { + ownerDocument: ownerDocument, + realSize: this.state.realHeight, + containerSize: this.state.containerHeight, + position: this.state.topPosition, + onMove: this.handleScrollbarMove.bind(this), + onPositionChange: this.handleScrollbarYPositionChange.bind(this), + containerStyle: this.props.verticalContainerStyle, + scrollbarStyle: this.props.verticalScrollbarStyle, + smoothScrolling: withMotion, + minScrollSize: this.props.minScrollSize, + onFocus: this.focusContent.bind(this), + type: 'vertical' }) : null; + + var scrollbarX = this.canScrollX() ? _react2.default.createElement(_Scrollbar2.default, { + ownerDocument: ownerDocument, + realSize: this.state.realWidth, + containerSize: this.state.containerWidth, + position: this.state.leftPosition, + onMove: this.handleScrollbarMove.bind(this), + onPositionChange: this.handleScrollbarXPositionChange.bind(this), + containerStyle: this.props.horizontalContainerStyle, + scrollbarStyle: this.props.horizontalScrollbarStyle, + smoothScrolling: withMotion, + minScrollSize: this.props.minScrollSize, + onFocus: this.focusContent.bind(this), + type: 'horizontal' }) : null; + + if (typeof children === 'function') { + (0, _utils.warnAboutFunctionChild)(); + children = children(); + } else { + (0, _utils.warnAboutElementChild)(); + } + + var classes = 'scrollarea ' + (className || ''); + var contentClasses = 'scrollarea-content ' + (contentClassName || ''); + + var contentStyle = { + marginTop: -this.state.topPosition, + marginLeft: -this.state.leftPosition + }; + var springifiedContentStyle = withMotion ? (0, _utils.modifyObjValues)(contentStyle, function (x) { + return (0, _reactMotion.spring)(x); + }) : contentStyle; + + return _react2.default.createElement( + _reactMotion.Motion, + { style: springifiedContentStyle }, + function (style) { + return _react2.default.createElement( + 'div', + { + ref: function ref(x) { + return _this2.wrapper = x; + }, + className: classes, + style: _this2.props.style, + onWheel: _this2.handleWheel.bind(_this2) + }, + _react2.default.createElement( + 'div', + { + ref: function ref(x) { + return _this2.content = x; + }, + style: _extends({}, _this2.props.contentStyle, style), + className: contentClasses, + onTouchStart: _this2.handleTouchStart.bind(_this2), + onTouchMove: _this2.handleTouchMove.bind(_this2), + onTouchEnd: _this2.handleTouchEnd.bind(_this2), + onKeyDown: _this2.handleKeyDown.bind(_this2), + tabIndex: _this2.props.focusableTabIndex + }, + children + ), + scrollbarY, + scrollbarX + ); + } + ); + } + }, { + key: 'setStateFromEvent', + value: function setStateFromEvent(newState, eventType) { + if (this.props.onScroll) { + this.props.onScroll(newState); + } + this.setState(_extends({}, newState, { eventType: eventType })); + } + }, { + key: 'handleTouchStart', + value: function handleTouchStart(e) { + var touches = e.touches; + + if (touches.length === 1) { + var _touches$ = touches[0], + clientX = _touches$.clientX, + clientY = _touches$.clientY; + + this.eventPreviousValues = _extends({}, this.eventPreviousValues, { + clientY: clientY, + clientX: clientX, + timestamp: Date.now() + }); + } + } + }, { + key: 'handleTouchMove', + value: function handleTouchMove(e) { + if (this.canScroll()) { + e.preventDefault(); + e.stopPropagation(); + } + + var touches = e.touches; + + if (touches.length === 1) { + var _touches$2 = touches[0], + clientX = _touches$2.clientX, + clientY = _touches$2.clientY; + + + var deltaY = this.eventPreviousValues.clientY - clientY; + var deltaX = this.eventPreviousValues.clientX - clientX; + + this.eventPreviousValues = _extends({}, this.eventPreviousValues, { + deltaY: deltaY, + deltaX: deltaX, + clientY: clientY, + clientX: clientX, + timestamp: Date.now() + }); + + this.setStateFromEvent(this.composeNewState(-deltaX, -deltaY)); + } + } + }, { + key: 'handleTouchEnd', + value: function handleTouchEnd(e) { + var _eventPreviousValues = this.eventPreviousValues, + deltaX = _eventPreviousValues.deltaX, + deltaY = _eventPreviousValues.deltaY, + timestamp = _eventPreviousValues.timestamp; + + if (typeof deltaX === 'undefined') deltaX = 0; + if (typeof deltaY === 'undefined') deltaY = 0; + if (Date.now() - timestamp < 200) { + this.setStateFromEvent(this.composeNewState(-deltaX * 10, -deltaY * 10), eventTypes.touchEnd); + } + + this.eventPreviousValues = _extends({}, this.eventPreviousValues, { + deltaY: 0, + deltaX: 0 + }); + } + }, { + key: 'handleScrollbarMove', + value: function handleScrollbarMove(deltaY, deltaX) { + this.setStateFromEvent(this.composeNewState(deltaX, deltaY)); + } + }, { + key: 'handleScrollbarXPositionChange', + value: function handleScrollbarXPositionChange(position) { + this.scrollXTo(position); + } + }, { + key: 'handleScrollbarYPositionChange', + value: function handleScrollbarYPositionChange(position) { + this.scrollYTo(position); + } + }, { + key: 'handleWheel', + value: function handleWheel(e) { + var deltaY = e.deltaY; + var deltaX = e.deltaX; + + if (this.props.swapWheelAxes) { + var _ref = [deltaX, deltaY]; + deltaY = _ref[0]; + deltaX = _ref[1]; + } + + /* + * WheelEvent.deltaMode can differ between browsers and must be normalized + * e.deltaMode === 0: The delta values are specified in pixels + * e.deltaMode === 1: The delta values are specified in lines + * https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode + */ + if (e.deltaMode === 1) { + deltaY = deltaY * this.lineHeightPx; + deltaX = deltaX * this.lineHeightPx; + } + + deltaY = deltaY * this.props.speed; + deltaX = deltaX * this.props.speed; + + var newState = this.composeNewState(-deltaX, -deltaY); + + if (newState.topPosition && this.state.topPosition !== newState.topPosition || newState.leftPosition && this.state.leftPosition !== newState.leftPosition || this.props.stopScrollPropagation) { + e.preventDefault(); + e.stopPropagation(); + } + + this.setStateFromEvent(newState, eventTypes.wheel); + this.focusContent(); + } + }, { + key: 'handleKeyDown', + value: function handleKeyDown(e) { + // only handle if scroll area is in focus + if (e.target.tagName.toLowerCase() !== 'input' && e.target.tagName.toLowerCase() !== 'textarea' && !e.target.isContentEditable) { + var deltaY = 0; + var deltaX = 0; + var _lineHeight = this.lineHeightPx ? this.lineHeightPx : 10; + + switch (e.keyCode) { + case 33: + // page up + deltaY = this.state.containerHeight - _lineHeight; + break; + case 34: + // page down + deltaY = -this.state.containerHeight + _lineHeight; + break; + case 37: + // left + deltaX = _lineHeight; + break; + case 38: + // up + deltaY = _lineHeight; + break; + case 39: + // right + deltaX = -_lineHeight; + break; + case 40: + // down + deltaY = -_lineHeight; + break; + } + + // only compose new state if key code matches those above + if (deltaY !== 0 || deltaX !== 0) { + var newState = this.composeNewState(deltaX, deltaY); + + e.preventDefault(); + e.stopPropagation(); + + this.setStateFromEvent(newState, eventTypes.keyPress); + } + } + } + }, { + key: 'handleWindowResize', + value: function handleWindowResize() { + var newState = this.computeSizes(); + newState = this.getModifiedPositionsIfNeeded(newState); + this.setStateFromEvent(newState); + } + }, { + key: 'composeNewState', + value: function composeNewState(deltaX, deltaY) { + var newState = this.computeSizes(); + + if (this.canScrollY(newState)) { + newState.topPosition = this.computeTopPosition(deltaY, newState); + } else { + newState.topPosition = 0; + } + if (this.canScrollX(newState)) { + newState.leftPosition = this.computeLeftPosition(deltaX, newState); + } + + return newState; + } + }, { + key: 'computeTopPosition', + value: function computeTopPosition(deltaY, sizes) { + var newTopPosition = this.state.topPosition - deltaY; + return this.normalizeTopPosition(newTopPosition, sizes); + } + }, { + key: 'computeLeftPosition', + value: function computeLeftPosition(deltaX, sizes) { + var newLeftPosition = this.state.leftPosition - deltaX; + return this.normalizeLeftPosition(newLeftPosition, sizes); + } + }, { + key: 'normalizeTopPosition', + value: function normalizeTopPosition(newTopPosition, sizes) { + if (newTopPosition > sizes.realHeight - sizes.containerHeight) { + newTopPosition = sizes.realHeight - sizes.containerHeight; + } + if (newTopPosition < 0) { + newTopPosition = 0; + } + return newTopPosition; + } + }, { + key: 'normalizeLeftPosition', + value: function normalizeLeftPosition(newLeftPosition, sizes) { + if (newLeftPosition > sizes.realWidth - sizes.containerWidth) { + newLeftPosition = sizes.realWidth - sizes.containerWidth; + } else if (newLeftPosition < 0) { + newLeftPosition = 0; + } + + return newLeftPosition; + } + }, { + key: 'computeSizes', + value: function computeSizes() { + var realHeight = this.content ? this.content.offsetHeight : 0; + var containerHeight = this.wrapper ? this.wrapper.offsetHeight : 0; + var realWidth = this.content ? this.content.offsetWidth : 0; + var containerWidth = this.content ? this.wrapper.offsetWidth : 0; + + return { + realHeight: realHeight, + containerHeight: containerHeight, + realWidth: realWidth, + containerWidth: containerWidth + }; + } + }, { + key: 'setSizesToState', + value: function setSizesToState() { + var sizes = this.computeSizes(); + if (sizes.realHeight !== this.state.realHeight || sizes.realWidth !== this.state.realWidth) { + this.setStateFromEvent(this.getModifiedPositionsIfNeeded(sizes)); + } + } + }, { + key: 'scrollTop', + value: function scrollTop() { + this.scrollYTo(0); + } + }, { + key: 'scrollBottom', + value: function scrollBottom() { + this.scrollYTo(this.state.realHeight - this.state.containerHeight); + } + }, { + key: 'scrollLeft', + value: function scrollLeft() { + this.scrollXTo(0); + } + }, { + key: 'scrollRight', + value: function scrollRight() { + this.scrollXTo(this.state.realWidth - this.state.containerWidth); + } + }, { + key: 'scrollYTo', + value: function scrollYTo(topPosition) { + if (this.canScrollY()) { + var position = this.normalizeTopPosition(topPosition, this.computeSizes()); + this.setStateFromEvent({ topPosition: position }, eventTypes.api); + } + } + }, { + key: 'scrollXTo', + value: function scrollXTo(leftPosition) { + if (this.canScrollX()) { + var position = this.normalizeLeftPosition(leftPosition, this.computeSizes()); + this.setStateFromEvent({ leftPosition: position }, eventTypes.api); + } + } + }, { + key: 'canScrollY', + value: function canScrollY() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state; + + var scrollableY = state.realHeight > state.containerHeight; + return scrollableY && this.props.vertical; + } + }, { + key: 'canScrollX', + value: function canScrollX() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state; + + var scrollableX = state.realWidth > state.containerWidth; + return scrollableX && this.props.horizontal; + } + }, { + key: 'canScroll', + value: function canScroll() { + var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state; + + return this.canScrollY(state) || this.canScrollX(state); + } + }, { + key: 'getModifiedPositionsIfNeeded', + value: function getModifiedPositionsIfNeeded(newState) { + var bottomPosition = newState.realHeight - newState.containerHeight; + if (this.state.topPosition >= bottomPosition) { + newState.topPosition = this.canScrollY(newState) ? (0, _utils.positiveOrZero)(bottomPosition) : 0; + } + + var rightPosition = newState.realWidth - newState.containerWidth; + if (this.state.leftPosition >= rightPosition) { + newState.leftPosition = this.canScrollX(newState) ? (0, _utils.positiveOrZero)(rightPosition) : 0; + } + + return newState; + } + }, { + key: 'focusContent', + value: function focusContent() { + if (this.content) { + (0, _utils.findDOMNode)(this.content).focus(); + } + } + }]); + + return ScrollArea; + }(_react2.default.Component); + + exports.default = ScrollArea; + + + ScrollArea.childContextTypes = { + scrollArea: _propTypes2.default.object + }; + + ScrollArea.propTypes = { + className: _propTypes2.default.string, + style: _propTypes2.default.object, + speed: _propTypes2.default.number, + contentClassName: _propTypes2.default.string, + contentStyle: _propTypes2.default.object, + vertical: _propTypes2.default.bool, + verticalContainerStyle: _propTypes2.default.object, + verticalScrollbarStyle: _propTypes2.default.object, + horizontal: _propTypes2.default.bool, + horizontalContainerStyle: _propTypes2.default.object, + horizontalScrollbarStyle: _propTypes2.default.object, + onScroll: _propTypes2.default.func, + contentWindow: _propTypes2.default.any, + ownerDocument: _propTypes2.default.any, + smoothScrolling: _propTypes2.default.bool, + minScrollSize: _propTypes2.default.number, + swapWheelAxes: _propTypes2.default.bool, + stopScrollPropagation: _propTypes2.default.bool, + focusableTabIndex: _propTypes2.default.number + }; + + ScrollArea.defaultProps = { + speed: 1, + vertical: true, + horizontal: true, + smoothScrolling: false, + swapWheelAxes: false, + contentWindow: (typeof window === 'undefined' ? 'undefined' : _typeof(window)) === "object" ? window : undefined, + ownerDocument: (typeof document === 'undefined' ? 'undefined' : _typeof(document)) === "object" ? document : undefined, + focusableTabIndex: 1 + }; + +/***/ }), +/* 2 */ +/***/ (function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_2__; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + if (process.env.NODE_ENV !== 'production') { + var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && + Symbol.for && + Symbol.for('react.element')) || + 0xeac7; + + var isValidElement = function(object) { + return typeof object === 'object' && + object !== null && + object.$$typeof === REACT_ELEMENT_TYPE; + }; + + // By explicitly using `prop-types` you are opting into new development behavior. + // http://fb.me/prop-types-in-prod + var throwOnDirectAccess = true; + module.exports = __webpack_require__(5)(isValidElement, throwOnDirectAccess); + } else { + // By explicitly using `prop-types` you are opting into new production behavior. + // http://fb.me/prop-types-in-prod + module.exports = __webpack_require__(9)(); + } + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }), +/* 4 */ +/***/ (function(module, exports) { + + // shim for using process in browser + var process = module.exports = {}; + + // cached from whatever global is present so that test runners that stub it + // don't break things. But we need to wrap it in a try catch in case it is + // wrapped in strict mode code which doesn't define any globals. It's inside a + // function because try/catches deoptimize in certain engines. + + var cachedSetTimeout; + var cachedClearTimeout; + + function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); + } + function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); + } + (function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } + } ()) + function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + + } + function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + + } + var queue = []; + var draining = false; + var currentQueue; + var queueIndex = -1; + + function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } + } + + function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); + } + + process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } + }; + + // v8 likes predictible objects + function Item(fun, array) { + this.fun = fun; + this.array = array; + } + Item.prototype.run = function () { + this.fun.apply(null, this.array); + }; + process.title = 'browser'; + process.browser = true; + process.env = {}; + process.argv = []; + process.version = ''; // empty string to avoid regexp issues + process.versions = {}; + + function noop() {} + + process.on = noop; + process.addListener = noop; + process.once = noop; + process.off = noop; + process.removeListener = noop; + process.removeAllListeners = noop; + process.emit = noop; + process.prependListener = noop; + process.prependOnceListener = noop; + + process.listeners = function (name) { return [] } + + process.binding = function (name) { + throw new Error('process.binding is not supported'); + }; + + process.cwd = function () { return '/' }; + process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); + }; + process.umask = function() { return 0; }; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + 'use strict'; + + var assign = __webpack_require__(6); + + var ReactPropTypesSecret = __webpack_require__(7); + var checkPropTypes = __webpack_require__(8); + + var printWarning = function() {}; + + if (process.env.NODE_ENV !== 'production') { + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; + } + + function emptyFunctionThatReturnsNull() { + return null; + } + + module.exports = function(isValidElement, throwOnDirectAccess) { + /* global Symbol */ + var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + + /** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ + function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + /** + * Collection of methods that allow declaration and validation of props that are + * supplied to React components. Example usage: + * + * var Props = require('ReactPropTypes'); + * var MyArticle = React.createClass({ + * propTypes: { + * // An optional string prop named "description". + * description: Props.string, + * + * // A required enum prop named "category". + * category: Props.oneOf(['News','Photos']).isRequired, + * + * // A prop named "dialog" that requires an instance of Dialog. + * dialog: Props.instanceOf(Dialog).isRequired + * }, + * render: function() { ... } + * }); + * + * A more formal specification of how these methods are used: + * + * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) + * decl := ReactPropTypes.{type}(.isRequired)? + * + * Each and every declaration produces a function with the same signature. This + * allows the creation of custom validation functions. For example: + * + * var MyLink = React.createClass({ + * propTypes: { + * // An optional string or URI prop named "href". + * href: function(props, propName, componentName) { + * var propValue = props[propName]; + * if (propValue != null && typeof propValue !== 'string' && + * !(propValue instanceof URI)) { + * return new Error( + * 'Expected a string or an URI for ' + propName + ' in ' + + * componentName + * ); + * } + * } + * }, + * render: function() {...} + * }); + * + * @internal + */ + + var ANONYMOUS = '<>'; + + // Important! + // Keep this list in sync with production version in `./factoryWithThrowingShims.js`. + var ReactPropTypes = { + array: createPrimitiveTypeChecker('array'), + bool: createPrimitiveTypeChecker('boolean'), + func: createPrimitiveTypeChecker('function'), + number: createPrimitiveTypeChecker('number'), + object: createPrimitiveTypeChecker('object'), + string: createPrimitiveTypeChecker('string'), + symbol: createPrimitiveTypeChecker('symbol'), + + any: createAnyTypeChecker(), + arrayOf: createArrayOfTypeChecker, + element: createElementTypeChecker(), + instanceOf: createInstanceTypeChecker, + node: createNodeChecker(), + objectOf: createObjectOfTypeChecker, + oneOf: createEnumTypeChecker, + oneOfType: createUnionTypeChecker, + shape: createShapeTypeChecker, + exact: createStrictShapeTypeChecker, + }; + + /** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ + /*eslint-disable no-self-compare*/ + function is(x, y) { + // SameValue algorithm + if (x === y) { + // Steps 1-5, 7-10 + // Steps 6.b-6.e: +0 != -0 + return x !== 0 || 1 / x === 1 / y; + } else { + // Step 6.a: NaN == NaN + return x !== x && y !== y; + } + } + /*eslint-enable no-self-compare*/ + + /** + * We use an Error-like object for backward compatibility as people may call + * PropTypes directly and inspect their output. However, we don't use real + * Errors anymore. We don't inspect their stack anyway, and creating them + * is prohibitively expensive if they are created too often, such as what + * happens in oneOfType() for any type before the one that matched. + */ + function PropTypeError(message) { + this.message = message; + this.stack = ''; + } + // Make `instanceof Error` still work for returned errors. + PropTypeError.prototype = Error.prototype; + + function createChainableTypeChecker(validate) { + if (process.env.NODE_ENV !== 'production') { + var manualPropTypeCallCache = {}; + var manualPropTypeWarningCount = 0; + } + function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { + componentName = componentName || ANONYMOUS; + propFullName = propFullName || propName; + + if (secret !== ReactPropTypesSecret) { + if (throwOnDirectAccess) { + // New behavior only for users of `prop-types` package + var err = new Error( + 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + + 'Use `PropTypes.checkPropTypes()` to call them. ' + + 'Read more at http://fb.me/use-check-prop-types' + ); + err.name = 'Invariant Violation'; + throw err; + } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') { + // Old behavior for people using React.PropTypes + var cacheKey = componentName + ':' + propName; + if ( + !manualPropTypeCallCache[cacheKey] && + // Avoid spamming the console because they are often not actionable except for lib authors + manualPropTypeWarningCount < 3 + ) { + printWarning( + 'You are manually calling a React.PropTypes validation ' + + 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' + + 'and will throw in the standalone `prop-types` package. ' + + 'You may be seeing this warning due to a third-party PropTypes ' + + 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.' + ); + manualPropTypeCallCache[cacheKey] = true; + manualPropTypeWarningCount++; + } + } + } + if (props[propName] == null) { + if (isRequired) { + if (props[propName] === null) { + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); + } + return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); + } + return null; + } else { + return validate(props, propName, componentName, location, propFullName); + } + } + + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); + + return chainedCheckType; + } + + function createPrimitiveTypeChecker(expectedType) { + function validate(props, propName, componentName, location, propFullName, secret) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== expectedType) { + // `propValue` being instance of, say, date/regexp, pass the 'object' + // check, but we can offer a more precise error message here rather than + // 'of type `object`'. + var preciseType = getPreciseType(propValue); + + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createAnyTypeChecker() { + return createChainableTypeChecker(emptyFunctionThatReturnsNull); + } + + function createArrayOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); + } + var propValue = props[propName]; + if (!Array.isArray(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); + } + for (var i = 0; i < propValue.length; i++) { + var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createElementTypeChecker() { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + if (!isValidElement(propValue)) { + var propType = getPropType(propValue); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createInstanceTypeChecker(expectedClass) { + function validate(props, propName, componentName, location, propFullName) { + if (!(props[propName] instanceof expectedClass)) { + var expectedClassName = expectedClass.name || ANONYMOUS; + var actualClassName = getClassName(props[propName]); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createEnumTypeChecker(expectedValues) { + if (!Array.isArray(expectedValues)) { + process.env.NODE_ENV !== 'production' ? printWarning('Invalid argument supplied to oneOf, expected an instance of array.') : void 0; + return emptyFunctionThatReturnsNull; + } + + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + for (var i = 0; i < expectedValues.length; i++) { + if (is(propValue, expectedValues[i])) { + return null; + } + } + + var valuesString = JSON.stringify(expectedValues); + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); + } + return createChainableTypeChecker(validate); + } + + function createObjectOfTypeChecker(typeChecker) { + function validate(props, propName, componentName, location, propFullName) { + if (typeof typeChecker !== 'function') { + return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); + } + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); + } + for (var key in propValue) { + if (propValue.hasOwnProperty(key)) { + var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error instanceof Error) { + return error; + } + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createUnionTypeChecker(arrayOfTypeCheckers) { + if (!Array.isArray(arrayOfTypeCheckers)) { + process.env.NODE_ENV !== 'production' ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; + return emptyFunctionThatReturnsNull; + } + + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + if (typeof checker !== 'function') { + printWarning( + 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' + + 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.' + ); + return emptyFunctionThatReturnsNull; + } + } + + function validate(props, propName, componentName, location, propFullName) { + for (var i = 0; i < arrayOfTypeCheckers.length; i++) { + var checker = arrayOfTypeCheckers[i]; + if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { + return null; + } + } + + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); + } + return createChainableTypeChecker(validate); + } + + function createNodeChecker() { + function validate(props, propName, componentName, location, propFullName) { + if (!isNode(props[propName])) { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + for (var key in shapeTypes) { + var checker = shapeTypes[key]; + if (!checker) { + continue; + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + return createChainableTypeChecker(validate); + } + + function createStrictShapeTypeChecker(shapeTypes) { + function validate(props, propName, componentName, location, propFullName) { + var propValue = props[propName]; + var propType = getPropType(propValue); + if (propType !== 'object') { + return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.')); + } + // We need to check all keys in case some are required but missing from + // props. + var allKeys = assign({}, props[propName], shapeTypes); + for (var key in allKeys) { + var checker = shapeTypes[key]; + if (!checker) { + return new PropTypeError( + 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' + + '\nBad object: ' + JSON.stringify(props[propName], null, ' ') + + '\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ') + ); + } + var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); + if (error) { + return error; + } + } + return null; + } + + return createChainableTypeChecker(validate); + } + + function isNode(propValue) { + switch (typeof propValue) { + case 'number': + case 'string': + case 'undefined': + return true; + case 'boolean': + return !propValue; + case 'object': + if (Array.isArray(propValue)) { + return propValue.every(isNode); + } + if (propValue === null || isValidElement(propValue)) { + return true; + } + + var iteratorFn = getIteratorFn(propValue); + if (iteratorFn) { + var iterator = iteratorFn.call(propValue); + var step; + if (iteratorFn !== propValue.entries) { + while (!(step = iterator.next()).done) { + if (!isNode(step.value)) { + return false; + } + } + } else { + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + if (!isNode(entry[1])) { + return false; + } + } + } + } + } else { + return false; + } + + return true; + default: + return false; + } + } + + function isSymbol(propType, propValue) { + // Native Symbol. + if (propType === 'symbol') { + return true; + } + + // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' + if (propValue['@@toStringTag'] === 'Symbol') { + return true; + } + + // Fallback for non-spec compliant Symbols which are polyfilled. + if (typeof Symbol === 'function' && propValue instanceof Symbol) { + return true; + } + + return false; + } + + // Equivalent of `typeof` but with special handling for array and regexp. + function getPropType(propValue) { + var propType = typeof propValue; + if (Array.isArray(propValue)) { + return 'array'; + } + if (propValue instanceof RegExp) { + // Old webkits (at least until Android 4.0) return 'function' rather than + // 'object' for typeof a RegExp. We'll normalize this here so that /bla/ + // passes PropTypes.object. + return 'object'; + } + if (isSymbol(propType, propValue)) { + return 'symbol'; + } + return propType; + } + + // This handles more types than `getPropType`. Only used for error messages. + // See `createPrimitiveTypeChecker`. + function getPreciseType(propValue) { + if (typeof propValue === 'undefined' || propValue === null) { + return '' + propValue; + } + var propType = getPropType(propValue); + if (propType === 'object') { + if (propValue instanceof Date) { + return 'date'; + } else if (propValue instanceof RegExp) { + return 'regexp'; + } + } + return propType; + } + + // Returns a string that is postfixed to a warning about an invalid type. + // For example, "undefined" or "of type array" + function getPostfixForTypeWarning(value) { + var type = getPreciseType(value); + switch (type) { + case 'array': + case 'object': + return 'an ' + type; + case 'boolean': + case 'date': + case 'regexp': + return 'a ' + type; + default: + return type; + } + } + + // Returns class name of the object, if any. + function getClassName(propValue) { + if (!propValue.constructor || !propValue.constructor.name) { + return ANONYMOUS; + } + return propValue.constructor.name; + } + + ReactPropTypes.checkPropTypes = checkPropTypes; + ReactPropTypes.PropTypes = ReactPropTypes; + + return ReactPropTypes; + }; + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }), +/* 6 */ +/***/ (function(module, exports) { + + /* + object-assign + (c) Sindre Sorhus + @license MIT + */ + + 'use strict'; + /* eslint-disable no-unused-vars */ + var getOwnPropertySymbols = Object.getOwnPropertySymbols; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var propIsEnumerable = Object.prototype.propertyIsEnumerable; + + function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); + } + + function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } + } + + module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; + }; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports) { + + /** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + 'use strict'; + + var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; + + module.exports = ReactPropTypesSecret; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + 'use strict'; + + var printWarning = function() {}; + + if (process.env.NODE_ENV !== 'production') { + var ReactPropTypesSecret = __webpack_require__(7); + var loggedTypeFailures = {}; + + printWarning = function(text) { + var message = 'Warning: ' + text; + if (typeof console !== 'undefined') { + console.error(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; + } + + /** + * Assert that the values match with the type specs. + * Error messages are memorized and will only be shown once. + * + * @param {object} typeSpecs Map of name to a ReactPropType + * @param {object} values Runtime values that need to be type-checked + * @param {string} location e.g. "prop", "context", "child context" + * @param {string} componentName Name of the component for error messages. + * @param {?Function} getStack Returns the component stack. + * @private + */ + function checkPropTypes(typeSpecs, values, location, componentName, getStack) { + if (process.env.NODE_ENV !== 'production') { + for (var typeSpecName in typeSpecs) { + if (typeSpecs.hasOwnProperty(typeSpecName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== 'function') { + var err = Error( + (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + ); + err.name = 'Invariant Violation'; + throw err; + } + error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); + } catch (ex) { + error = ex; + } + if (error && !(error instanceof Error)) { + printWarning( + (componentName || 'React class') + ': type specification of ' + + location + ' `' + typeSpecName + '` is invalid; the type checker ' + + 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' + + 'You may have forgotten to pass an argument to the type checker ' + + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + + 'shape all require an argument).' + ) + + } + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var stack = getStack ? getStack() : ''; + + printWarning( + 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '') + ); + } + } + } + } + } + + module.exports = checkPropTypes; + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + + /** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + 'use strict'; + + var ReactPropTypesSecret = __webpack_require__(7); + + function emptyFunction() {} + + module.exports = function() { + function shim(props, propName, componentName, location, propFullName, secret) { + if (secret === ReactPropTypesSecret) { + // It is still safe when called from React. + return; + } + var err = new Error( + 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' + + 'Use PropTypes.checkPropTypes() to call them. ' + + 'Read more at http://fb.me/use-check-prop-types' + ); + err.name = 'Invariant Violation'; + throw err; + }; + shim.isRequired = shim; + function getShim() { + return shim; + }; + // Important! + // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. + var ReactPropTypes = { + array: shim, + bool: shim, + func: shim, + number: shim, + object: shim, + string: shim, + symbol: shim, + + any: shim, + arrayOf: getShim, + element: shim, + instanceOf: getShim, + node: shim, + objectOf: getShim, + oneOf: getShim, + oneOfType: getShim, + shape: getShim, + exact: getShim + }; + + ReactPropTypes.checkPropTypes = emptyFunction; + ReactPropTypes.PropTypes = ReactPropTypes; + + return ReactPropTypes; + }; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + + // Load in dependencies + var computedStyle = __webpack_require__(11); + + /** + * Calculate the `line-height` of a given node + * @param {HTMLElement} node Element to calculate line height of. Must be in the DOM. + * @returns {Number} `line-height` of the element in pixels + */ + function lineHeight(node) { + // Grab the line-height via style + var lnHeightStr = computedStyle(node, 'line-height'), + lnHeight = parseFloat(lnHeightStr, 10); + + // If the lineHeight did not contain a unit (i.e. it was numeric), convert it to ems (e.g. '2.3' === '2.3em') + if (lnHeightStr === lnHeight + '') { + // Save the old lineHeight style and update the em unit to the element + var _lnHeightStyle = node.style.lineHeight; + node.style.lineHeight = lnHeightStr + 'em'; + + // Calculate the em based height + lnHeightStr = computedStyle(node, 'line-height'); + lnHeight = parseFloat(lnHeightStr, 10); + + // Revert the lineHeight style + if (_lnHeightStyle) { + node.style.lineHeight = _lnHeightStyle; + } else { + delete node.style.lineHeight; + } + } + + // If the lineHeight is in `pt`, convert it to pixels (4px for 3pt) + // DEV: `em` units are converted to `pt` in IE6 + // Conversion ratio from https://developer.mozilla.org/en-US/docs/Web/CSS/length + if (lnHeightStr.indexOf('pt') !== -1) { + lnHeight *= 4; + lnHeight /= 3; + } else if (lnHeightStr.indexOf('mm') !== -1) { + // Otherwise, if the lineHeight is in `mm`, convert it to pixels (96px for 25.4mm) + lnHeight *= 96; + lnHeight /= 25.4; + } else if (lnHeightStr.indexOf('cm') !== -1) { + // Otherwise, if the lineHeight is in `cm`, convert it to pixels (96px for 2.54cm) + lnHeight *= 96; + lnHeight /= 2.54; + } else if (lnHeightStr.indexOf('in') !== -1) { + // Otherwise, if the lineHeight is in `in`, convert it to pixels (96px for 1in) + lnHeight *= 96; + } else if (lnHeightStr.indexOf('pc') !== -1) { + // Otherwise, if the lineHeight is in `pc`, convert it to pixels (12pt for 1pc) + lnHeight *= 16; + } + + // Continue our computation + lnHeight = Math.round(lnHeight); + + // If the line-height is "normal", calculate by font-size + if (lnHeightStr === 'normal') { + // Create a temporary node + var nodeName = node.nodeName, + _node = document.createElement(nodeName); + _node.innerHTML = ' '; + + // Set the font-size of the element + var fontSizeStr = computedStyle(node, 'font-size'); + _node.style.fontSize = fontSizeStr; + + // Append it to the body + var body = document.body; + body.appendChild(_node); + + // Assume the line height of the element is the height + var height = _node.offsetHeight; + lnHeight = height; + + // Remove our child from the DOM + body.removeChild(_node); + } + + // Return the calculated height + return lnHeight; + } + + // Export lineHeight + module.exports = lineHeight; + +/***/ }), +/* 11 */ +/***/ (function(module, exports) { + + // This code has been refactored for 140 bytes + // You can see the original here: https://github.com/twolfson/computedStyle/blob/04cd1da2e30fa45844f95f5cb1ac898e9b9ef050/lib/computedStyle.js + var computedStyle = function (el, prop, getComputedStyle) { + getComputedStyle = window.getComputedStyle; + + // In one fell swoop + return ( + // If we have getComputedStyle + getComputedStyle ? + // Query it + // TODO: From CSS-Query notes, we might need (node, null) for FF + getComputedStyle(el) : + + // Otherwise, we are in IE and use currentStyle + el.currentStyle + )[ + // Switch to camelCase for CSSOM + // DEV: Grabbed from jQuery + // https://github.com/jquery/jquery/blob/1.9-stable/src/css.js#L191-L194 + // https://github.com/jquery/jquery/blob/1.9-stable/src/core.js#L593-L597 + prop.replace(/-(\w)/gi, function (word, letter) { + return letter.toUpperCase(); + }) + ]; + }; + + module.exports = computedStyle; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; } + + var _Motion = __webpack_require__(13); + + exports.Motion = _interopRequire(_Motion); + + var _StaggeredMotion = __webpack_require__(21); + + exports.StaggeredMotion = _interopRequire(_StaggeredMotion); + + var _TransitionMotion = __webpack_require__(22); + + exports.TransitionMotion = _interopRequire(_TransitionMotion); + + var _spring = __webpack_require__(24); + + exports.spring = _interopRequire(_spring); + + var _presets = __webpack_require__(25); + + exports.presets = _interopRequire(_presets); + + var _stripStyle = __webpack_require__(15); + + exports.stripStyle = _interopRequire(_stripStyle); + + // deprecated, dummy warning function + + var _reorderKeys = __webpack_require__(26); + + exports.reorderKeys = _interopRequire(_reorderKeys); + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _mapToZero = __webpack_require__(14); + + var _mapToZero2 = _interopRequireDefault(_mapToZero); + + var _stripStyle = __webpack_require__(15); + + var _stripStyle2 = _interopRequireDefault(_stripStyle); + + var _stepper3 = __webpack_require__(16); + + var _stepper4 = _interopRequireDefault(_stepper3); + + var _performanceNow = __webpack_require__(17); + + var _performanceNow2 = _interopRequireDefault(_performanceNow); + + var _raf = __webpack_require__(18); + + var _raf2 = _interopRequireDefault(_raf); + + var _shouldStopAnimation = __webpack_require__(20); + + var _shouldStopAnimation2 = _interopRequireDefault(_shouldStopAnimation); + + var _react = __webpack_require__(2); + + var _react2 = _interopRequireDefault(_react); + + var _propTypes = __webpack_require__(3); + + var _propTypes2 = _interopRequireDefault(_propTypes); + + var msPerFrame = 1000 / 60; + + var Motion = (function (_React$Component) { + _inherits(Motion, _React$Component); + + _createClass(Motion, null, [{ + key: 'propTypes', + value: { + // TOOD: warn against putting a config in here + defaultStyle: _propTypes2['default'].objectOf(_propTypes2['default'].number), + style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired, + children: _propTypes2['default'].func.isRequired, + onRest: _propTypes2['default'].func + }, + enumerable: true + }]); + + function Motion(props) { + var _this = this; + + _classCallCheck(this, Motion); + + _React$Component.call(this, props); + this.wasAnimating = false; + this.animationID = null; + this.prevTime = 0; + this.accumulatedTime = 0; + this.unreadPropStyle = null; + + this.clearUnreadPropStyle = function (destStyle) { + var dirty = false; + var _state = _this.state; + var currentStyle = _state.currentStyle; + var currentVelocity = _state.currentVelocity; + var lastIdealStyle = _state.lastIdealStyle; + var lastIdealVelocity = _state.lastIdealVelocity; + + for (var key in destStyle) { + if (!Object.prototype.hasOwnProperty.call(destStyle, key)) { + continue; + } + + var styleValue = destStyle[key]; + if (typeof styleValue === 'number') { + if (!dirty) { + dirty = true; + currentStyle = _extends({}, currentStyle); + currentVelocity = _extends({}, currentVelocity); + lastIdealStyle = _extends({}, lastIdealStyle); + lastIdealVelocity = _extends({}, lastIdealVelocity); + } + + currentStyle[key] = styleValue; + currentVelocity[key] = 0; + lastIdealStyle[key] = styleValue; + lastIdealVelocity[key] = 0; + } + } + + if (dirty) { + _this.setState({ currentStyle: currentStyle, currentVelocity: currentVelocity, lastIdealStyle: lastIdealStyle, lastIdealVelocity: lastIdealVelocity }); + } + }; + + this.startAnimationIfNecessary = function () { + // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and + // call cb? No, otherwise accidental parent rerender causes cb trigger + _this.animationID = _raf2['default'](function (timestamp) { + // check if we need to animate in the first place + var propsStyle = _this.props.style; + if (_shouldStopAnimation2['default'](_this.state.currentStyle, propsStyle, _this.state.currentVelocity)) { + if (_this.wasAnimating && _this.props.onRest) { + _this.props.onRest(); + } + + // no need to cancel animationID here; shouldn't have any in flight + _this.animationID = null; + _this.wasAnimating = false; + _this.accumulatedTime = 0; + return; + } + + _this.wasAnimating = true; + + var currentTime = timestamp || _performanceNow2['default'](); + var timeDelta = currentTime - _this.prevTime; + _this.prevTime = currentTime; + _this.accumulatedTime = _this.accumulatedTime + timeDelta; + // more than 10 frames? prolly switched browser tab. Restart + if (_this.accumulatedTime > msPerFrame * 10) { + _this.accumulatedTime = 0; + } + + if (_this.accumulatedTime === 0) { + // no need to cancel animationID here; shouldn't have any in flight + _this.animationID = null; + _this.startAnimationIfNecessary(); + return; + } + + var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; + var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); + + var newLastIdealStyle = {}; + var newLastIdealVelocity = {}; + var newCurrentStyle = {}; + var newCurrentVelocity = {}; + + for (var key in propsStyle) { + if (!Object.prototype.hasOwnProperty.call(propsStyle, key)) { + continue; + } + + var styleValue = propsStyle[key]; + if (typeof styleValue === 'number') { + newCurrentStyle[key] = styleValue; + newCurrentVelocity[key] = 0; + newLastIdealStyle[key] = styleValue; + newLastIdealVelocity[key] = 0; + } else { + var newLastIdealStyleValue = _this.state.lastIdealStyle[key]; + var newLastIdealVelocityValue = _this.state.lastIdealVelocity[key]; + for (var i = 0; i < framesToCatchUp; i++) { + var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); + + newLastIdealStyleValue = _stepper[0]; + newLastIdealVelocityValue = _stepper[1]; + } + + var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); + + var nextIdealX = _stepper2[0]; + var nextIdealV = _stepper2[1]; + + newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; + newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; + newLastIdealStyle[key] = newLastIdealStyleValue; + newLastIdealVelocity[key] = newLastIdealVelocityValue; + } + } + + _this.animationID = null; + // the amount we're looped over above + _this.accumulatedTime -= framesToCatchUp * msPerFrame; + + _this.setState({ + currentStyle: newCurrentStyle, + currentVelocity: newCurrentVelocity, + lastIdealStyle: newLastIdealStyle, + lastIdealVelocity: newLastIdealVelocity + }); + + _this.unreadPropStyle = null; + + _this.startAnimationIfNecessary(); + }); + }; + + this.state = this.defaultState(); + } + + Motion.prototype.defaultState = function defaultState() { + var _props = this.props; + var defaultStyle = _props.defaultStyle; + var style = _props.style; + + var currentStyle = defaultStyle || _stripStyle2['default'](style); + var currentVelocity = _mapToZero2['default'](currentStyle); + return { + currentStyle: currentStyle, + currentVelocity: currentVelocity, + lastIdealStyle: currentStyle, + lastIdealVelocity: currentVelocity + }; + }; + + // it's possible that currentStyle's value is stale: if props is immediately + // changed from 0 to 400 to spring(0) again, the async currentStyle is still + // at 0 (didn't have time to tick and interpolate even once). If we naively + // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). + // In reality currentStyle should be 400 + + Motion.prototype.componentDidMount = function componentDidMount() { + this.prevTime = _performanceNow2['default'](); + this.startAnimationIfNecessary(); + }; + + Motion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { + if (this.unreadPropStyle != null) { + // previous props haven't had the chance to be set yet; set them here + this.clearUnreadPropStyle(this.unreadPropStyle); + } + + this.unreadPropStyle = props.style; + if (this.animationID == null) { + this.prevTime = _performanceNow2['default'](); + this.startAnimationIfNecessary(); + } + }; + + Motion.prototype.componentWillUnmount = function componentWillUnmount() { + if (this.animationID != null) { + _raf2['default'].cancel(this.animationID); + this.animationID = null; + } + }; + + Motion.prototype.render = function render() { + var renderedChildren = this.props.children(this.state.currentStyle); + return renderedChildren && _react2['default'].Children.only(renderedChildren); + }; + + return Motion; + })(_react2['default'].Component); + + exports['default'] = Motion; + module.exports = exports['default']; + + // after checking for unreadPropStyle != null, we manually go set the + // non-interpolating values (those that are a number, without a spring + // config) + +/***/ }), +/* 14 */ +/***/ (function(module, exports) { + + + + // currently used to initiate the velocity style object to 0 + 'use strict'; + + exports.__esModule = true; + exports['default'] = mapToZero; + + function mapToZero(obj) { + var ret = {}; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + ret[key] = 0; + } + } + return ret; + } + + module.exports = exports['default']; + +/***/ }), +/* 15 */ +/***/ (function(module, exports) { + + + // turn {x: {val: 1, stiffness: 1, damping: 2}, y: 2} generated by + // `{x: spring(1, {stiffness: 1, damping: 2}), y: 2}` into {x: 1, y: 2} + + 'use strict'; + + exports.__esModule = true; + exports['default'] = stripStyle; + + function stripStyle(style) { + var ret = {}; + for (var key in style) { + if (!Object.prototype.hasOwnProperty.call(style, key)) { + continue; + } + ret[key] = typeof style[key] === 'number' ? style[key] : style[key].val; + } + return ret; + } + + module.exports = exports['default']; + +/***/ }), +/* 16 */ +/***/ (function(module, exports) { + + + + // stepper is used a lot. Saves allocation to return the same array wrapper. + // This is fine and danger-free against mutations because the callsite + // immediately destructures it and gets the numbers inside without passing the + "use strict"; + + exports.__esModule = true; + exports["default"] = stepper; + + var reusedTuple = [0, 0]; + + function stepper(secondPerFrame, x, v, destX, k, b, precision) { + // Spring stiffness, in kg / s^2 + + // for animations, destX is really spring length (spring at rest). initial + // position is considered as the stretched/compressed position of a spring + var Fspring = -k * (x - destX); + + // Damping, in kg / s + var Fdamper = -b * v; + + // usually we put mass here, but for animation purposes, specifying mass is a + // bit redundant. you could simply adjust k and b accordingly + // let a = (Fspring + Fdamper) / mass; + var a = Fspring + Fdamper; + + var newV = v + a * secondPerFrame; + var newX = x + newV * secondPerFrame; + + if (Math.abs(newV) < precision && Math.abs(newX - destX) < precision) { + reusedTuple[0] = destX; + reusedTuple[1] = 0; + return reusedTuple; + } + + reusedTuple[0] = newX; + reusedTuple[1] = newV; + return reusedTuple; + } + + module.exports = exports["default"]; + // array reference around. + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {// Generated by CoffeeScript 1.7.1 + (function() { + var getNanoSeconds, hrtime, loadTime; + + if ((typeof performance !== "undefined" && performance !== null) && performance.now) { + module.exports = function() { + return performance.now(); + }; + } else if ((typeof process !== "undefined" && process !== null) && process.hrtime) { + module.exports = function() { + return (getNanoSeconds() - loadTime) / 1e6; + }; + hrtime = process.hrtime; + getNanoSeconds = function() { + var hr; + hr = hrtime(); + return hr[0] * 1e9 + hr[1]; + }; + loadTime = getNanoSeconds(); + } else if (Date.now) { + module.exports = function() { + return Date.now() - loadTime; + }; + loadTime = Date.now(); + } else { + module.exports = function() { + return new Date().getTime() - loadTime; + }; + loadTime = new Date().getTime(); + } + + }).call(this); + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global) {var now = __webpack_require__(19) + , root = typeof window === 'undefined' ? global : window + , vendors = ['moz', 'webkit'] + , suffix = 'AnimationFrame' + , raf = root['request' + suffix] + , caf = root['cancel' + suffix] || root['cancelRequest' + suffix] + + for(var i = 0; !raf && i < vendors.length; i++) { + raf = root[vendors[i] + 'Request' + suffix] + caf = root[vendors[i] + 'Cancel' + suffix] + || root[vendors[i] + 'CancelRequest' + suffix] + } + + // Some versions of FF have rAF but not cAF + if(!raf || !caf) { + var last = 0 + , id = 0 + , queue = [] + , frameDuration = 1000 / 60 + + raf = function(callback) { + if(queue.length === 0) { + var _now = now() + , next = Math.max(0, frameDuration - (_now - last)) + last = next + _now + setTimeout(function() { + var cp = queue.slice(0) + // Clear queue here to prevent + // callbacks from appending listeners + // to the current frame's queue + queue.length = 0 + for(var i = 0; i < cp.length; i++) { + if(!cp[i].cancelled) { + try{ + cp[i].callback(last) + } catch(e) { + setTimeout(function() { throw e }, 0) + } + } + } + }, Math.round(next)) + } + queue.push({ + handle: ++id, + callback: callback, + cancelled: false + }) + return id + } + + caf = function(handle) { + for(var i = 0; i < queue.length; i++) { + if(queue[i].handle === handle) { + queue[i].cancelled = true + } + } + } + } + + module.exports = function(fn) { + // Wrap in a new function to prevent + // `cancel` potentially being assigned + // to the native rAF function + return raf.call(root, fn) + } + module.exports.cancel = function() { + caf.apply(root, arguments) + } + module.exports.polyfill = function(object) { + if (!object) { + object = root; + } + object.requestAnimationFrame = raf + object.cancelAnimationFrame = caf + } + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {// Generated by CoffeeScript 1.12.2 + (function() { + var getNanoSeconds, hrtime, loadTime, moduleLoadTime, nodeLoadTime, upTime; + + if ((typeof performance !== "undefined" && performance !== null) && performance.now) { + module.exports = function() { + return performance.now(); + }; + } else if ((typeof process !== "undefined" && process !== null) && process.hrtime) { + module.exports = function() { + return (getNanoSeconds() - nodeLoadTime) / 1e6; + }; + hrtime = process.hrtime; + getNanoSeconds = function() { + var hr; + hr = hrtime(); + return hr[0] * 1e9 + hr[1]; + }; + moduleLoadTime = getNanoSeconds(); + upTime = process.uptime() * 1e9; + nodeLoadTime = moduleLoadTime - upTime; + } else if (Date.now) { + module.exports = function() { + return Date.now() - loadTime; + }; + loadTime = Date.now(); + } else { + module.exports = function() { + return new Date().getTime() - loadTime; + }; + loadTime = new Date().getTime(); + } + + }).call(this); + + //# sourceMappingURL=performance-now.js.map + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }), +/* 20 */ +/***/ (function(module, exports) { + + + + // usage assumption: currentStyle values have already been rendered but it says + // nothing of whether currentStyle is stale (see unreadPropStyle) + 'use strict'; + + exports.__esModule = true; + exports['default'] = shouldStopAnimation; + + function shouldStopAnimation(currentStyle, style, currentVelocity) { + for (var key in style) { + if (!Object.prototype.hasOwnProperty.call(style, key)) { + continue; + } + + if (currentVelocity[key] !== 0) { + return false; + } + + var styleValue = typeof style[key] === 'number' ? style[key] : style[key].val; + // stepper will have already taken care of rounding precision errors, so + // won't have such thing as 0.9999 !=== 1 + if (currentStyle[key] !== styleValue) { + return false; + } + } + + return true; + } + + module.exports = exports['default']; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _mapToZero = __webpack_require__(14); + + var _mapToZero2 = _interopRequireDefault(_mapToZero); + + var _stripStyle = __webpack_require__(15); + + var _stripStyle2 = _interopRequireDefault(_stripStyle); + + var _stepper3 = __webpack_require__(16); + + var _stepper4 = _interopRequireDefault(_stepper3); + + var _performanceNow = __webpack_require__(17); + + var _performanceNow2 = _interopRequireDefault(_performanceNow); + + var _raf = __webpack_require__(18); + + var _raf2 = _interopRequireDefault(_raf); + + var _shouldStopAnimation = __webpack_require__(20); + + var _shouldStopAnimation2 = _interopRequireDefault(_shouldStopAnimation); + + var _react = __webpack_require__(2); + + var _react2 = _interopRequireDefault(_react); + + var _propTypes = __webpack_require__(3); + + var _propTypes2 = _interopRequireDefault(_propTypes); + + var msPerFrame = 1000 / 60; + + function shouldStopAnimationAll(currentStyles, styles, currentVelocities) { + for (var i = 0; i < currentStyles.length; i++) { + if (!_shouldStopAnimation2['default'](currentStyles[i], styles[i], currentVelocities[i])) { + return false; + } + } + return true; + } + + var StaggeredMotion = (function (_React$Component) { + _inherits(StaggeredMotion, _React$Component); + + _createClass(StaggeredMotion, null, [{ + key: 'propTypes', + value: { + // TOOD: warn against putting a config in here + defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].objectOf(_propTypes2['default'].number)), + styles: _propTypes2['default'].func.isRequired, + children: _propTypes2['default'].func.isRequired + }, + enumerable: true + }]); + + function StaggeredMotion(props) { + var _this = this; + + _classCallCheck(this, StaggeredMotion); + + _React$Component.call(this, props); + this.animationID = null; + this.prevTime = 0; + this.accumulatedTime = 0; + this.unreadPropStyles = null; + + this.clearUnreadPropStyle = function (unreadPropStyles) { + var _state = _this.state; + var currentStyles = _state.currentStyles; + var currentVelocities = _state.currentVelocities; + var lastIdealStyles = _state.lastIdealStyles; + var lastIdealVelocities = _state.lastIdealVelocities; + + var someDirty = false; + for (var i = 0; i < unreadPropStyles.length; i++) { + var unreadPropStyle = unreadPropStyles[i]; + var dirty = false; + + for (var key in unreadPropStyle) { + if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) { + continue; + } + + var styleValue = unreadPropStyle[key]; + if (typeof styleValue === 'number') { + if (!dirty) { + dirty = true; + someDirty = true; + currentStyles[i] = _extends({}, currentStyles[i]); + currentVelocities[i] = _extends({}, currentVelocities[i]); + lastIdealStyles[i] = _extends({}, lastIdealStyles[i]); + lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]); + } + currentStyles[i][key] = styleValue; + currentVelocities[i][key] = 0; + lastIdealStyles[i][key] = styleValue; + lastIdealVelocities[i][key] = 0; + } + } + } + + if (someDirty) { + _this.setState({ currentStyles: currentStyles, currentVelocities: currentVelocities, lastIdealStyles: lastIdealStyles, lastIdealVelocities: lastIdealVelocities }); + } + }; + + this.startAnimationIfNecessary = function () { + // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and + // call cb? No, otherwise accidental parent rerender causes cb trigger + _this.animationID = _raf2['default'](function (timestamp) { + var destStyles = _this.props.styles(_this.state.lastIdealStyles); + + // check if we need to animate in the first place + if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities)) { + // no need to cancel animationID here; shouldn't have any in flight + _this.animationID = null; + _this.accumulatedTime = 0; + return; + } + + var currentTime = timestamp || _performanceNow2['default'](); + var timeDelta = currentTime - _this.prevTime; + _this.prevTime = currentTime; + _this.accumulatedTime = _this.accumulatedTime + timeDelta; + // more than 10 frames? prolly switched browser tab. Restart + if (_this.accumulatedTime > msPerFrame * 10) { + _this.accumulatedTime = 0; + } + + if (_this.accumulatedTime === 0) { + // no need to cancel animationID here; shouldn't have any in flight + _this.animationID = null; + _this.startAnimationIfNecessary(); + return; + } + + var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; + var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); + + var newLastIdealStyles = []; + var newLastIdealVelocities = []; + var newCurrentStyles = []; + var newCurrentVelocities = []; + + for (var i = 0; i < destStyles.length; i++) { + var destStyle = destStyles[i]; + var newCurrentStyle = {}; + var newCurrentVelocity = {}; + var newLastIdealStyle = {}; + var newLastIdealVelocity = {}; + + for (var key in destStyle) { + if (!Object.prototype.hasOwnProperty.call(destStyle, key)) { + continue; + } + + var styleValue = destStyle[key]; + if (typeof styleValue === 'number') { + newCurrentStyle[key] = styleValue; + newCurrentVelocity[key] = 0; + newLastIdealStyle[key] = styleValue; + newLastIdealVelocity[key] = 0; + } else { + var newLastIdealStyleValue = _this.state.lastIdealStyles[i][key]; + var newLastIdealVelocityValue = _this.state.lastIdealVelocities[i][key]; + for (var j = 0; j < framesToCatchUp; j++) { + var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); + + newLastIdealStyleValue = _stepper[0]; + newLastIdealVelocityValue = _stepper[1]; + } + + var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); + + var nextIdealX = _stepper2[0]; + var nextIdealV = _stepper2[1]; + + newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; + newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; + newLastIdealStyle[key] = newLastIdealStyleValue; + newLastIdealVelocity[key] = newLastIdealVelocityValue; + } + } + + newCurrentStyles[i] = newCurrentStyle; + newCurrentVelocities[i] = newCurrentVelocity; + newLastIdealStyles[i] = newLastIdealStyle; + newLastIdealVelocities[i] = newLastIdealVelocity; + } + + _this.animationID = null; + // the amount we're looped over above + _this.accumulatedTime -= framesToCatchUp * msPerFrame; + + _this.setState({ + currentStyles: newCurrentStyles, + currentVelocities: newCurrentVelocities, + lastIdealStyles: newLastIdealStyles, + lastIdealVelocities: newLastIdealVelocities + }); + + _this.unreadPropStyles = null; + + _this.startAnimationIfNecessary(); + }); + }; + + this.state = this.defaultState(); + } + + StaggeredMotion.prototype.defaultState = function defaultState() { + var _props = this.props; + var defaultStyles = _props.defaultStyles; + var styles = _props.styles; + + var currentStyles = defaultStyles || styles().map(_stripStyle2['default']); + var currentVelocities = currentStyles.map(function (currentStyle) { + return _mapToZero2['default'](currentStyle); + }); + return { + currentStyles: currentStyles, + currentVelocities: currentVelocities, + lastIdealStyles: currentStyles, + lastIdealVelocities: currentVelocities + }; + }; + + StaggeredMotion.prototype.componentDidMount = function componentDidMount() { + this.prevTime = _performanceNow2['default'](); + this.startAnimationIfNecessary(); + }; + + StaggeredMotion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { + if (this.unreadPropStyles != null) { + // previous props haven't had the chance to be set yet; set them here + this.clearUnreadPropStyle(this.unreadPropStyles); + } + + this.unreadPropStyles = props.styles(this.state.lastIdealStyles); + if (this.animationID == null) { + this.prevTime = _performanceNow2['default'](); + this.startAnimationIfNecessary(); + } + }; + + StaggeredMotion.prototype.componentWillUnmount = function componentWillUnmount() { + if (this.animationID != null) { + _raf2['default'].cancel(this.animationID); + this.animationID = null; + } + }; + + StaggeredMotion.prototype.render = function render() { + var renderedChildren = this.props.children(this.state.currentStyles); + return renderedChildren && _react2['default'].Children.only(renderedChildren); + }; + + return StaggeredMotion; + })(_react2['default'].Component); + + exports['default'] = StaggeredMotion; + module.exports = exports['default']; + + // it's possible that currentStyle's value is stale: if props is immediately + // changed from 0 to 400 to spring(0) again, the async currentStyle is still + // at 0 (didn't have time to tick and interpolate even once). If we naively + // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). + // In reality currentStyle should be 400 + + // after checking for unreadPropStyles != null, we manually go set the + // non-interpolating values (those that are a number, without a spring + // config) + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _mapToZero = __webpack_require__(14); + + var _mapToZero2 = _interopRequireDefault(_mapToZero); + + var _stripStyle = __webpack_require__(15); + + var _stripStyle2 = _interopRequireDefault(_stripStyle); + + var _stepper3 = __webpack_require__(16); + + var _stepper4 = _interopRequireDefault(_stepper3); + + var _mergeDiff = __webpack_require__(23); + + var _mergeDiff2 = _interopRequireDefault(_mergeDiff); + + var _performanceNow = __webpack_require__(17); + + var _performanceNow2 = _interopRequireDefault(_performanceNow); + + var _raf = __webpack_require__(18); + + var _raf2 = _interopRequireDefault(_raf); + + var _shouldStopAnimation = __webpack_require__(20); + + var _shouldStopAnimation2 = _interopRequireDefault(_shouldStopAnimation); + + var _react = __webpack_require__(2); + + var _react2 = _interopRequireDefault(_react); + + var _propTypes = __webpack_require__(3); + + var _propTypes2 = _interopRequireDefault(_propTypes); + + var msPerFrame = 1000 / 60; + + // the children function & (potential) styles function asks as param an + // Array, where each TransitionPlainStyle is of the format + // {key: string, data?: any, style: PlainStyle}. However, the way we keep + // internal states doesn't contain such a data structure (check the state and + // TransitionMotionState). So when children function and others ask for such + // data we need to generate them on the fly by combining mergedPropsStyles and + // currentStyles/lastIdealStyles + function rehydrateStyles(mergedPropsStyles, unreadPropStyles, plainStyles) { + // Copy the value to a `const` so that Flow understands that the const won't + // change and will be non-nullable in the callback below. + var cUnreadPropStyles = unreadPropStyles; + if (cUnreadPropStyles == null) { + return mergedPropsStyles.map(function (mergedPropsStyle, i) { + return { + key: mergedPropsStyle.key, + data: mergedPropsStyle.data, + style: plainStyles[i] + }; + }); + } + return mergedPropsStyles.map(function (mergedPropsStyle, i) { + for (var j = 0; j < cUnreadPropStyles.length; j++) { + if (cUnreadPropStyles[j].key === mergedPropsStyle.key) { + return { + key: cUnreadPropStyles[j].key, + data: cUnreadPropStyles[j].data, + style: plainStyles[i] + }; + } + } + return { key: mergedPropsStyle.key, data: mergedPropsStyle.data, style: plainStyles[i] }; + }); + } + + function shouldStopAnimationAll(currentStyles, destStyles, currentVelocities, mergedPropsStyles) { + if (mergedPropsStyles.length !== destStyles.length) { + return false; + } + + for (var i = 0; i < mergedPropsStyles.length; i++) { + if (mergedPropsStyles[i].key !== destStyles[i].key) { + return false; + } + } + + // we have the invariant that mergedPropsStyles and + // currentStyles/currentVelocities/last* are synced in terms of cells, see + // mergeAndSync comment for more info + for (var i = 0; i < mergedPropsStyles.length; i++) { + if (!_shouldStopAnimation2['default'](currentStyles[i], destStyles[i].style, currentVelocities[i])) { + return false; + } + } + + return true; + } + + // core key merging logic + + // things to do: say previously merged style is {a, b}, dest style (prop) is {b, + // c}, previous current (interpolating) style is {a, b} + // **invariant**: current[i] corresponds to merged[i] in terms of key + + // steps: + // turn merged style into {a?, b, c} + // add c, value of c is destStyles.c + // maybe remove a, aka call willLeave(a), then merged is either {b, c} or {a, b, c} + // turn current (interpolating) style from {a, b} into {a?, b, c} + // maybe remove a + // certainly add c, value of c is willEnter(c) + // loop over merged and construct new current + // dest doesn't change, that's owner's + function mergeAndSync(willEnter, willLeave, didLeave, oldMergedPropsStyles, destStyles, oldCurrentStyles, oldCurrentVelocities, oldLastIdealStyles, oldLastIdealVelocities) { + var newMergedPropsStyles = _mergeDiff2['default'](oldMergedPropsStyles, destStyles, function (oldIndex, oldMergedPropsStyle) { + var leavingStyle = willLeave(oldMergedPropsStyle); + if (leavingStyle == null) { + didLeave({ key: oldMergedPropsStyle.key, data: oldMergedPropsStyle.data }); + return null; + } + if (_shouldStopAnimation2['default'](oldCurrentStyles[oldIndex], leavingStyle, oldCurrentVelocities[oldIndex])) { + didLeave({ key: oldMergedPropsStyle.key, data: oldMergedPropsStyle.data }); + return null; + } + return { key: oldMergedPropsStyle.key, data: oldMergedPropsStyle.data, style: leavingStyle }; + }); + + var newCurrentStyles = []; + var newCurrentVelocities = []; + var newLastIdealStyles = []; + var newLastIdealVelocities = []; + for (var i = 0; i < newMergedPropsStyles.length; i++) { + var newMergedPropsStyleCell = newMergedPropsStyles[i]; + var foundOldIndex = null; + for (var j = 0; j < oldMergedPropsStyles.length; j++) { + if (oldMergedPropsStyles[j].key === newMergedPropsStyleCell.key) { + foundOldIndex = j; + break; + } + } + // TODO: key search code + if (foundOldIndex == null) { + var plainStyle = willEnter(newMergedPropsStyleCell); + newCurrentStyles[i] = plainStyle; + newLastIdealStyles[i] = plainStyle; + + var velocity = _mapToZero2['default'](newMergedPropsStyleCell.style); + newCurrentVelocities[i] = velocity; + newLastIdealVelocities[i] = velocity; + } else { + newCurrentStyles[i] = oldCurrentStyles[foundOldIndex]; + newLastIdealStyles[i] = oldLastIdealStyles[foundOldIndex]; + newCurrentVelocities[i] = oldCurrentVelocities[foundOldIndex]; + newLastIdealVelocities[i] = oldLastIdealVelocities[foundOldIndex]; + } + } + + return [newMergedPropsStyles, newCurrentStyles, newCurrentVelocities, newLastIdealStyles, newLastIdealVelocities]; + } + + var TransitionMotion = (function (_React$Component) { + _inherits(TransitionMotion, _React$Component); + + _createClass(TransitionMotion, null, [{ + key: 'propTypes', + value: { + defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].shape({ + key: _propTypes2['default'].string.isRequired, + data: _propTypes2['default'].any, + style: _propTypes2['default'].objectOf(_propTypes2['default'].number).isRequired + })), + styles: _propTypes2['default'].oneOfType([_propTypes2['default'].func, _propTypes2['default'].arrayOf(_propTypes2['default'].shape({ + key: _propTypes2['default'].string.isRequired, + data: _propTypes2['default'].any, + style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired + }))]).isRequired, + children: _propTypes2['default'].func.isRequired, + willEnter: _propTypes2['default'].func, + willLeave: _propTypes2['default'].func, + didLeave: _propTypes2['default'].func + }, + enumerable: true + }, { + key: 'defaultProps', + value: { + willEnter: function willEnter(styleThatEntered) { + return _stripStyle2['default'](styleThatEntered.style); + }, + // recall: returning null makes the current unmounting TransitionStyle + // disappear immediately + willLeave: function willLeave() { + return null; + }, + didLeave: function didLeave() {} + }, + enumerable: true + }]); + + function TransitionMotion(props) { + var _this = this; + + _classCallCheck(this, TransitionMotion); + + _React$Component.call(this, props); + this.unmounting = false; + this.animationID = null; + this.prevTime = 0; + this.accumulatedTime = 0; + this.unreadPropStyles = null; + + this.clearUnreadPropStyle = function (unreadPropStyles) { + var _mergeAndSync = mergeAndSync(_this.props.willEnter, _this.props.willLeave, _this.props.didLeave, _this.state.mergedPropsStyles, unreadPropStyles, _this.state.currentStyles, _this.state.currentVelocities, _this.state.lastIdealStyles, _this.state.lastIdealVelocities); + + var mergedPropsStyles = _mergeAndSync[0]; + var currentStyles = _mergeAndSync[1]; + var currentVelocities = _mergeAndSync[2]; + var lastIdealStyles = _mergeAndSync[3]; + var lastIdealVelocities = _mergeAndSync[4]; + + for (var i = 0; i < unreadPropStyles.length; i++) { + var unreadPropStyle = unreadPropStyles[i].style; + var dirty = false; + + for (var key in unreadPropStyle) { + if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) { + continue; + } + + var styleValue = unreadPropStyle[key]; + if (typeof styleValue === 'number') { + if (!dirty) { + dirty = true; + currentStyles[i] = _extends({}, currentStyles[i]); + currentVelocities[i] = _extends({}, currentVelocities[i]); + lastIdealStyles[i] = _extends({}, lastIdealStyles[i]); + lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]); + mergedPropsStyles[i] = { + key: mergedPropsStyles[i].key, + data: mergedPropsStyles[i].data, + style: _extends({}, mergedPropsStyles[i].style) + }; + } + currentStyles[i][key] = styleValue; + currentVelocities[i][key] = 0; + lastIdealStyles[i][key] = styleValue; + lastIdealVelocities[i][key] = 0; + mergedPropsStyles[i].style[key] = styleValue; + } + } + } + + // unlike the other 2 components, we can't detect staleness and optionally + // opt out of setState here. each style object's data might contain new + // stuff we're not/cannot compare + _this.setState({ + currentStyles: currentStyles, + currentVelocities: currentVelocities, + mergedPropsStyles: mergedPropsStyles, + lastIdealStyles: lastIdealStyles, + lastIdealVelocities: lastIdealVelocities + }); + }; + + this.startAnimationIfNecessary = function () { + if (_this.unmounting) { + return; + } + + // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and + // call cb? No, otherwise accidental parent rerender causes cb trigger + _this.animationID = _raf2['default'](function (timestamp) { + // https://github.com/chenglou/react-motion/pull/420 + // > if execution passes the conditional if (this.unmounting), then + // executes async defaultRaf and after that component unmounts and after + // that the callback of defaultRaf is called, then setState will be called + // on unmounted component. + if (_this.unmounting) { + return; + } + + var propStyles = _this.props.styles; + var destStyles = typeof propStyles === 'function' ? propStyles(rehydrateStyles(_this.state.mergedPropsStyles, _this.unreadPropStyles, _this.state.lastIdealStyles)) : propStyles; + + // check if we need to animate in the first place + if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities, _this.state.mergedPropsStyles)) { + // no need to cancel animationID here; shouldn't have any in flight + _this.animationID = null; + _this.accumulatedTime = 0; + return; + } + + var currentTime = timestamp || _performanceNow2['default'](); + var timeDelta = currentTime - _this.prevTime; + _this.prevTime = currentTime; + _this.accumulatedTime = _this.accumulatedTime + timeDelta; + // more than 10 frames? prolly switched browser tab. Restart + if (_this.accumulatedTime > msPerFrame * 10) { + _this.accumulatedTime = 0; + } + + if (_this.accumulatedTime === 0) { + // no need to cancel animationID here; shouldn't have any in flight + _this.animationID = null; + _this.startAnimationIfNecessary(); + return; + } + + var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; + var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); + + var _mergeAndSync2 = mergeAndSync(_this.props.willEnter, _this.props.willLeave, _this.props.didLeave, _this.state.mergedPropsStyles, destStyles, _this.state.currentStyles, _this.state.currentVelocities, _this.state.lastIdealStyles, _this.state.lastIdealVelocities); + + var newMergedPropsStyles = _mergeAndSync2[0]; + var newCurrentStyles = _mergeAndSync2[1]; + var newCurrentVelocities = _mergeAndSync2[2]; + var newLastIdealStyles = _mergeAndSync2[3]; + var newLastIdealVelocities = _mergeAndSync2[4]; + + for (var i = 0; i < newMergedPropsStyles.length; i++) { + var newMergedPropsStyle = newMergedPropsStyles[i].style; + var newCurrentStyle = {}; + var newCurrentVelocity = {}; + var newLastIdealStyle = {}; + var newLastIdealVelocity = {}; + + for (var key in newMergedPropsStyle) { + if (!Object.prototype.hasOwnProperty.call(newMergedPropsStyle, key)) { + continue; + } + + var styleValue = newMergedPropsStyle[key]; + if (typeof styleValue === 'number') { + newCurrentStyle[key] = styleValue; + newCurrentVelocity[key] = 0; + newLastIdealStyle[key] = styleValue; + newLastIdealVelocity[key] = 0; + } else { + var newLastIdealStyleValue = newLastIdealStyles[i][key]; + var newLastIdealVelocityValue = newLastIdealVelocities[i][key]; + for (var j = 0; j < framesToCatchUp; j++) { + var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); + + newLastIdealStyleValue = _stepper[0]; + newLastIdealVelocityValue = _stepper[1]; + } + + var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); + + var nextIdealX = _stepper2[0]; + var nextIdealV = _stepper2[1]; + + newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; + newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; + newLastIdealStyle[key] = newLastIdealStyleValue; + newLastIdealVelocity[key] = newLastIdealVelocityValue; + } + } + + newLastIdealStyles[i] = newLastIdealStyle; + newLastIdealVelocities[i] = newLastIdealVelocity; + newCurrentStyles[i] = newCurrentStyle; + newCurrentVelocities[i] = newCurrentVelocity; + } + + _this.animationID = null; + // the amount we're looped over above + _this.accumulatedTime -= framesToCatchUp * msPerFrame; + + _this.setState({ + currentStyles: newCurrentStyles, + currentVelocities: newCurrentVelocities, + lastIdealStyles: newLastIdealStyles, + lastIdealVelocities: newLastIdealVelocities, + mergedPropsStyles: newMergedPropsStyles + }); + + _this.unreadPropStyles = null; + + _this.startAnimationIfNecessary(); + }); + }; + + this.state = this.defaultState(); + } + + TransitionMotion.prototype.defaultState = function defaultState() { + var _props = this.props; + var defaultStyles = _props.defaultStyles; + var styles = _props.styles; + var willEnter = _props.willEnter; + var willLeave = _props.willLeave; + var didLeave = _props.didLeave; + + var destStyles = typeof styles === 'function' ? styles(defaultStyles) : styles; + + // this is special. for the first time around, we don't have a comparison + // between last (no last) and current merged props. we'll compute last so: + // say default is {a, b} and styles (dest style) is {b, c}, we'll + // fabricate last as {a, b} + var oldMergedPropsStyles = undefined; + if (defaultStyles == null) { + oldMergedPropsStyles = destStyles; + } else { + oldMergedPropsStyles = defaultStyles.map(function (defaultStyleCell) { + // TODO: key search code + for (var i = 0; i < destStyles.length; i++) { + if (destStyles[i].key === defaultStyleCell.key) { + return destStyles[i]; + } + } + return defaultStyleCell; + }); + } + var oldCurrentStyles = defaultStyles == null ? destStyles.map(function (s) { + return _stripStyle2['default'](s.style); + }) : defaultStyles.map(function (s) { + return _stripStyle2['default'](s.style); + }); + var oldCurrentVelocities = defaultStyles == null ? destStyles.map(function (s) { + return _mapToZero2['default'](s.style); + }) : defaultStyles.map(function (s) { + return _mapToZero2['default'](s.style); + }); + + var _mergeAndSync3 = mergeAndSync( + // Because this is an old-style createReactClass component, Flow doesn't + // understand that the willEnter and willLeave props have default values + // and will always be present. + willEnter, willLeave, didLeave, oldMergedPropsStyles, destStyles, oldCurrentStyles, oldCurrentVelocities, oldCurrentStyles, // oldLastIdealStyles really + oldCurrentVelocities); + + var mergedPropsStyles = _mergeAndSync3[0]; + var currentStyles = _mergeAndSync3[1]; + var currentVelocities = _mergeAndSync3[2]; + var lastIdealStyles = _mergeAndSync3[3]; + var lastIdealVelocities = _mergeAndSync3[4]; + // oldLastIdealVelocities really + + return { + currentStyles: currentStyles, + currentVelocities: currentVelocities, + lastIdealStyles: lastIdealStyles, + lastIdealVelocities: lastIdealVelocities, + mergedPropsStyles: mergedPropsStyles + }; + }; + + // after checking for unreadPropStyles != null, we manually go set the + // non-interpolating values (those that are a number, without a spring + // config) + + TransitionMotion.prototype.componentDidMount = function componentDidMount() { + this.prevTime = _performanceNow2['default'](); + this.startAnimationIfNecessary(); + }; + + TransitionMotion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { + if (this.unreadPropStyles) { + // previous props haven't had the chance to be set yet; set them here + this.clearUnreadPropStyle(this.unreadPropStyles); + } + + var styles = props.styles; + if (typeof styles === 'function') { + this.unreadPropStyles = styles(rehydrateStyles(this.state.mergedPropsStyles, this.unreadPropStyles, this.state.lastIdealStyles)); + } else { + this.unreadPropStyles = styles; + } + + if (this.animationID == null) { + this.prevTime = _performanceNow2['default'](); + this.startAnimationIfNecessary(); + } + }; + + TransitionMotion.prototype.componentWillUnmount = function componentWillUnmount() { + this.unmounting = true; + if (this.animationID != null) { + _raf2['default'].cancel(this.animationID); + this.animationID = null; + } + }; + + TransitionMotion.prototype.render = function render() { + var hydratedStyles = rehydrateStyles(this.state.mergedPropsStyles, this.unreadPropStyles, this.state.currentStyles); + var renderedChildren = this.props.children(hydratedStyles); + return renderedChildren && _react2['default'].Children.only(renderedChildren); + }; + + return TransitionMotion; + })(_react2['default'].Component); + + exports['default'] = TransitionMotion; + module.exports = exports['default']; + + // list of styles, each containing interpolating values. Part of what's passed + // to children function. Notice that this is + // Array, without the wrapper that is {key: ..., + // data: ... style: ActualInterpolatingStyleObject}. Only mergedPropsStyles + // contains the key & data info (so that we only have a single source of truth + // for these, and to save space). Check the comment for `rehydrateStyles` to + // see how we regenerate the entirety of what's passed to children function + + // the array that keeps track of currently rendered stuff! Including stuff + // that you've unmounted but that's still animating. This is where it lives + + // it's possible that currentStyle's value is stale: if props is immediately + // changed from 0 to 400 to spring(0) again, the async currentStyle is still + // at 0 (didn't have time to tick and interpolate even once). If we naively + // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). + // In reality currentStyle should be 400 + +/***/ }), +/* 23 */ +/***/ (function(module, exports) { + + + + // core keys merging algorithm. If previous render's keys are [a, b], and the + // next render's [c, b, d], what's the final merged keys and ordering? + + // - c and a must both be before b + // - b before d + // - ordering between a and c ambiguous + + // this reduces to merging two partially ordered lists (e.g. lists where not + // every item has a definite ordering, like comparing a and c above). For the + // ambiguous ordering we deterministically choose to place the next render's + // item after the previous'; so c after a + + // this is called a topological sorting. Except the existing algorithms don't + // work well with js bc of the amount of allocation, and isn't optimized for our + // current use-case bc the runtime is linear in terms of edges (see wiki for + // meaning), which is huge when two lists have many common elements + 'use strict'; + + exports.__esModule = true; + exports['default'] = mergeDiff; + + function mergeDiff(prev, next, onRemove) { + // bookkeeping for easier access of a key's index below. This is 2 allocations + + // potentially triggering chrome hash map mode for objs (so it might be faster + + var prevKeyIndex = {}; + for (var i = 0; i < prev.length; i++) { + prevKeyIndex[prev[i].key] = i; + } + var nextKeyIndex = {}; + for (var i = 0; i < next.length; i++) { + nextKeyIndex[next[i].key] = i; + } + + // first, an overly elaborate way of merging prev and next, eliminating + // duplicates (in terms of keys). If there's dupe, keep the item in next). + // This way of writing it saves allocations + var ret = []; + for (var i = 0; i < next.length; i++) { + ret[i] = next[i]; + } + for (var i = 0; i < prev.length; i++) { + if (!Object.prototype.hasOwnProperty.call(nextKeyIndex, prev[i].key)) { + // this is called my TM's `mergeAndSync`, which calls willLeave. We don't + // merge in keys that the user desires to kill + var fill = onRemove(i, prev[i]); + if (fill != null) { + ret.push(fill); + } + } + } + + // now all the items all present. Core sorting logic to have the right order + return ret.sort(function (a, b) { + var nextOrderA = nextKeyIndex[a.key]; + var nextOrderB = nextKeyIndex[b.key]; + var prevOrderA = prevKeyIndex[a.key]; + var prevOrderB = prevKeyIndex[b.key]; + + if (nextOrderA != null && nextOrderB != null) { + // both keys in next + return nextKeyIndex[a.key] - nextKeyIndex[b.key]; + } else if (prevOrderA != null && prevOrderB != null) { + // both keys in prev + return prevKeyIndex[a.key] - prevKeyIndex[b.key]; + } else if (nextOrderA != null) { + // key a in next, key b in prev + + // how to determine the order between a and b? We find a "pivot" (term + // abuse), a key present in both prev and next, that is sandwiched between + // a and b. In the context of our above example, if we're comparing a and + // d, b's (the only) pivot + for (var i = 0; i < next.length; i++) { + var pivot = next[i].key; + if (!Object.prototype.hasOwnProperty.call(prevKeyIndex, pivot)) { + continue; + } + + if (nextOrderA < nextKeyIndex[pivot] && prevOrderB > prevKeyIndex[pivot]) { + return -1; + } else if (nextOrderA > nextKeyIndex[pivot] && prevOrderB < prevKeyIndex[pivot]) { + return 1; + } + } + // pluggable. default to: next bigger than prev + return 1; + } + // prevOrderA, nextOrderB + for (var i = 0; i < next.length; i++) { + var pivot = next[i].key; + if (!Object.prototype.hasOwnProperty.call(prevKeyIndex, pivot)) { + continue; + } + if (nextOrderB < nextKeyIndex[pivot] && prevOrderA > prevKeyIndex[pivot]) { + return 1; + } else if (nextOrderB > nextKeyIndex[pivot] && prevOrderA < prevKeyIndex[pivot]) { + return -1; + } + } + // pluggable. default to: next bigger than prev + return -1; + }); + } + + module.exports = exports['default']; + // to loop through and find a key's index each time), but I no longer care + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + exports['default'] = spring; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _presets = __webpack_require__(25); + + var _presets2 = _interopRequireDefault(_presets); + + var defaultConfig = _extends({}, _presets2['default'].noWobble, { + precision: 0.01 + }); + + function spring(val, config) { + return _extends({}, defaultConfig, config, { val: val }); + } + + module.exports = exports['default']; + +/***/ }), +/* 25 */ +/***/ (function(module, exports) { + + "use strict"; + + exports.__esModule = true; + exports["default"] = { + noWobble: { stiffness: 170, damping: 26 }, // the default, if nothing provided + gentle: { stiffness: 120, damping: 14 }, + wobbly: { stiffness: 180, damping: 12 }, + stiff: { stiffness: 210, damping: 20 } + }; + module.exports = exports["default"]; + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(process) {'use strict'; + + exports.__esModule = true; + exports['default'] = reorderKeys; + + var hasWarned = false; + + function reorderKeys() { + if (process.env.NODE_ENV === 'development') { + if (!hasWarned) { + hasWarned = true; + console.error('`reorderKeys` has been removed, since it is no longer needed for TransitionMotion\'s new styles array API.'); + } + } + } + + module.exports = exports['default']; + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(4))) + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.findDOMNode = findDOMNode; + exports.warnAboutFunctionChild = warnAboutFunctionChild; + exports.warnAboutElementChild = warnAboutElementChild; + exports.positiveOrZero = positiveOrZero; + exports.modifyObjValues = modifyObjValues; + exports.isReact13 = isReact13; + + var _react = __webpack_require__(2); + + var _react2 = _interopRequireDefault(_react); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var react13 = isReact13(_react2.default); + var didWarnAboutChild = false; + + function findDOMNode(component) { + if (!react13) { + return component; + } else { + return _react2.default.findDOMNode(component); + } + } + + function warnAboutFunctionChild() { + if (didWarnAboutChild || react13) { + return; + } + + didWarnAboutChild = true; + console.error('With React 0.14 and later versions, you no longer need to wrap child into a function.'); + } + + function warnAboutElementChild() { + if (didWarnAboutChild || !react13) { + return; + } + + didWarnAboutChild = true; + console.error('With React 0.13, you need to wrap child into a function.'); + } + + function positiveOrZero(number) { + return number < 0 ? 0 : number; + } + + function modifyObjValues(obj) { + var modifier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (x) { + return x; + }; + + var modifiedObj = {}; + for (var key in obj) { + if (obj.hasOwnProperty(key)) modifiedObj[key] = modifier(obj[key]); + } + + return modifiedObj; + } + + function isReact13(React) { + var version = React.version; + + if (typeof version !== 'string') { + return true; + } + + var parts = version.split('.'); + var major = parseInt(parts[0], 10); + var minor = parseInt(parts[1], 10); + + return major === 0 && minor === 13; + } + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _react = __webpack_require__(2); + + var _react2 = _interopRequireDefault(_react); + + var _propTypes = __webpack_require__(3); + + var _propTypes2 = _interopRequireDefault(_propTypes); + + var _reactMotion = __webpack_require__(12); + + var _utils = __webpack_require__(27); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var ScrollBar = function (_React$Component) { + _inherits(ScrollBar, _React$Component); + + function ScrollBar(props) { + _classCallCheck(this, ScrollBar); + + var _this = _possibleConstructorReturn(this, (ScrollBar.__proto__ || Object.getPrototypeOf(ScrollBar)).call(this, props)); + + var newState = _this.calculateState(props); + _this.state = { + position: newState.position, + scrollSize: newState.scrollSize, + isDragging: false, + lastClientPosition: 0 + }; + + if (props.type === 'vertical') { + _this.bindedHandleMouseMove = _this.handleMouseMoveForVertical.bind(_this); + } else { + _this.bindedHandleMouseMove = _this.handleMouseMoveForHorizontal.bind(_this); + } + + _this.bindedHandleMouseUp = _this.handleMouseUp.bind(_this); + return _this; + } + + _createClass(ScrollBar, [{ + key: 'componentDidMount', + value: function componentDidMount() { + if (this.props.ownerDocument) { + this.props.ownerDocument.addEventListener("mousemove", this.bindedHandleMouseMove); + this.props.ownerDocument.addEventListener("mouseup", this.bindedHandleMouseUp); + } + } + }, { + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + this.setState(this.calculateState(nextProps)); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + if (this.props.ownerDocument) { + this.props.ownerDocument.removeEventListener("mousemove", this.bindedHandleMouseMove); + this.props.ownerDocument.removeEventListener("mouseup", this.bindedHandleMouseUp); + } + } + }, { + key: 'calculateFractionalPosition', + value: function calculateFractionalPosition(realContentSize, containerSize, contentPosition) { + var relativeSize = realContentSize - containerSize; + + return 1 - (relativeSize - contentPosition) / relativeSize; + } + }, { + key: 'calculateState', + value: function calculateState(props) { + var fractionalPosition = this.calculateFractionalPosition(props.realSize, props.containerSize, props.position); + var proportionalToPageScrollSize = props.containerSize * props.containerSize / props.realSize; + var scrollSize = proportionalToPageScrollSize < props.minScrollSize ? props.minScrollSize : proportionalToPageScrollSize; + + var scrollPosition = (props.containerSize - scrollSize) * fractionalPosition; + return { + scrollSize: scrollSize, + position: Math.round(scrollPosition) + }; + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var _props = this.props, + smoothScrolling = _props.smoothScrolling, + isDragging = _props.isDragging, + type = _props.type, + scrollbarStyle = _props.scrollbarStyle, + containerStyle = _props.containerStyle; + + var isVoriziontal = type === 'horizontal'; + var isVertical = type === 'vertical'; + var scrollStyles = this.createScrollStyles(); + var springifiedScrollStyles = smoothScrolling ? (0, _utils.modifyObjValues)(scrollStyles, function (x) { + return (0, _reactMotion.spring)(x); + }) : scrollStyles; + + var scrollbarClasses = 'scrollbar-container ' + (isDragging ? 'active' : '') + ' ' + (isVoriziontal ? 'horizontal' : '') + ' ' + (isVertical ? 'vertical' : ''); + + return _react2.default.createElement( + _reactMotion.Motion, + { style: springifiedScrollStyles }, + function (style) { + return _react2.default.createElement( + 'div', + { + className: scrollbarClasses, + style: containerStyle, + onMouseDown: _this2.handleScrollBarContainerClick.bind(_this2), + ref: function ref(x) { + return _this2.scrollbarContainer = x; + } + }, + _react2.default.createElement('div', { + className: 'scrollbar', + style: _extends({}, scrollbarStyle, style), + onMouseDown: _this2.handleMouseDown.bind(_this2) + }) + ); + } + ); + } + }, { + key: 'handleScrollBarContainerClick', + value: function handleScrollBarContainerClick(e) { + e.preventDefault(); + var multiplier = this.computeMultiplier(); + var clientPosition = this.isVertical() ? e.clientY : e.clientX; + + var _scrollbarContainer$g = this.scrollbarContainer.getBoundingClientRect(), + top = _scrollbarContainer$g.top, + left = _scrollbarContainer$g.left; + + var clientScrollPosition = this.isVertical() ? top : left; + + var position = clientPosition - clientScrollPosition; + var proportionalToPageScrollSize = this.props.containerSize * this.props.containerSize / this.props.realSize; + + this.setState({ isDragging: true, lastClientPosition: clientPosition }); + this.props.onPositionChange((position - proportionalToPageScrollSize / 2) / multiplier); + } + }, { + key: 'handleMouseMoveForHorizontal', + value: function handleMouseMoveForHorizontal(e) { + var multiplier = this.computeMultiplier(); + + if (this.state.isDragging) { + e.preventDefault(); + var deltaX = this.state.lastClientPosition - e.clientX; + this.setState({ lastClientPosition: e.clientX }); + this.props.onMove(0, deltaX / multiplier); + } + } + }, { + key: 'handleMouseMoveForVertical', + value: function handleMouseMoveForVertical(e) { + var multiplier = this.computeMultiplier(); + + if (this.state.isDragging) { + e.preventDefault(); + var deltaY = this.state.lastClientPosition - e.clientY; + this.setState({ lastClientPosition: e.clientY }); + this.props.onMove(deltaY / multiplier, 0); + } + } + }, { + key: 'handleMouseDown', + value: function handleMouseDown(e) { + e.preventDefault(); + e.stopPropagation(); + var lastClientPosition = this.isVertical() ? e.clientY : e.clientX; + this.setState({ isDragging: true, lastClientPosition: lastClientPosition }); + + this.props.onFocus(); + } + }, { + key: 'handleMouseUp', + value: function handleMouseUp(e) { + if (this.state.isDragging) { + e.preventDefault(); + this.setState({ isDragging: false }); + } + } + }, { + key: 'createScrollStyles', + value: function createScrollStyles() { + if (this.props.type === 'vertical') { + return { + height: this.state.scrollSize, + marginTop: this.state.position + }; + } else { + return { + width: this.state.scrollSize, + marginLeft: this.state.position + }; + } + } + }, { + key: 'computeMultiplier', + value: function computeMultiplier() { + return this.props.containerSize / this.props.realSize; + } + }, { + key: 'isVertical', + value: function isVertical() { + return this.props.type === 'vertical'; + } + }]); + + return ScrollBar; + }(_react2.default.Component); + + ScrollBar.propTypes = { + onMove: _propTypes2.default.func, + onPositionChange: _propTypes2.default.func, + onFocus: _propTypes2.default.func, + realSize: _propTypes2.default.number, + containerSize: _propTypes2.default.number, + position: _propTypes2.default.number, + containerStyle: _propTypes2.default.object, + scrollbarStyle: _propTypes2.default.object, + type: _propTypes2.default.oneOf(['vertical', 'horizontal']), + ownerDocument: _propTypes2.default.any, + smoothScrolling: _propTypes2.default.bool, + minScrollSize: _propTypes2.default.number + }; + + ScrollBar.defaultProps = { + type: 'vertical', + smoothScrolling: false + }; + + exports.default = ScrollBar; + +/***/ }) +/******/ ]) +}); +; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCBiMjI1NjZkNWFhMjNmMzBiYzk1MiIsIndlYnBhY2s6Ly8vLi9zcmMvanMvU2Nyb2xsQXJlYVdpdGhvdXRDc3MuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2pzL1Njcm9sbEFyZWEuanN4Iiwid2VicGFjazovLy9leHRlcm5hbCB7XCJyb290XCI6XCJSZWFjdFwiLFwiY29tbW9uanMyXCI6XCJyZWFjdFwiLFwiY29tbW9uanNcIjpcInJlYWN0XCIsXCJhbWRcIjpcInJlYWN0XCJ9Iiwid2VicGFjazovLy8uL34vcHJvcC10eXBlcy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9+L3Byb2Nlc3MvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9+L3Byb3AtdHlwZXMvZmFjdG9yeVdpdGhUeXBlQ2hlY2tlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9vYmplY3QtYXNzaWduL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vcHJvcC10eXBlcy9saWIvUmVhY3RQcm9wVHlwZXNTZWNyZXQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9wcm9wLXR5cGVzL2NoZWNrUHJvcFR5cGVzLmpzIiwid2VicGFjazovLy8uL34vcHJvcC10eXBlcy9mYWN0b3J5V2l0aFRocm93aW5nU2hpbXMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9saW5lLWhlaWdodC9saWIvbGluZS1oZWlnaHQuanMiLCJ3ZWJwYWNrOi8vLy4vfi9saW5lLWhlaWdodC9+L2NvbXB1dGVkLXN0eWxlL2Rpc3QvY29tcHV0ZWRTdHlsZS5jb21tb25qcy5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWN0LW1vdGlvbi9saWIvcmVhY3QtbW90aW9uLmpzIiwid2VicGFjazovLy8uL34vcmVhY3QtbW90aW9uL2xpYi9Nb3Rpb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFjdC1tb3Rpb24vbGliL21hcFRvWmVyby5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWN0LW1vdGlvbi9saWIvc3RyaXBTdHlsZS5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWN0LW1vdGlvbi9saWIvc3RlcHBlci5qcyIsIndlYnBhY2s6Ly8vLi9+L3BlcmZvcm1hbmNlLW5vdy9saWIvcGVyZm9ybWFuY2Utbm93LmpzIiwid2VicGFjazovLy8uL34vcmFmL2luZGV4LmpzIiwid2VicGFjazovLy8uL34vcmFmL34vcGVyZm9ybWFuY2Utbm93L2xpYi9wZXJmb3JtYW5jZS1ub3cuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFjdC1tb3Rpb24vbGliL3Nob3VsZFN0b3BBbmltYXRpb24uanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFjdC1tb3Rpb24vbGliL1N0YWdnZXJlZE1vdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWN0LW1vdGlvbi9saWIvVHJhbnNpdGlvbk1vdGlvbi5qcyIsIndlYnBhY2s6Ly8vLi9+L3JlYWN0LW1vdGlvbi9saWIvbWVyZ2VEaWZmLmpzIiwid2VicGFjazovLy8uL34vcmVhY3QtbW90aW9uL2xpYi9zcHJpbmcuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFjdC1tb3Rpb24vbGliL3ByZXNldHMuanMiLCJ3ZWJwYWNrOi8vLy4vfi9yZWFjdC1tb3Rpb24vbGliL3Jlb3JkZXJLZXlzLmpzIiwid2VicGFjazovLy8uL3NyYy9qcy91dGlscy5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvanMvU2Nyb2xsYmFyLmpzeCJdLCJuYW1lcyI6WyJTY3JvbGxBcmVhIiwiZXZlbnRUeXBlcyIsIndoZWVsIiwiYXBpIiwidG91Y2giLCJ0b3VjaEVuZCIsIm1vdXNlbW92ZSIsImtleVByZXNzIiwicHJvcHMiLCJzdGF0ZSIsInRvcFBvc2l0aW9uIiwibGVmdFBvc2l0aW9uIiwicmVhbEhlaWdodCIsImNvbnRhaW5lckhlaWdodCIsInJlYWxXaWR0aCIsImNvbnRhaW5lcldpZHRoIiwic2Nyb2xsQXJlYSIsInJlZnJlc2giLCJzZXRTaXplc1RvU3RhdGUiLCJzY3JvbGxUb3AiLCJzY3JvbGxCb3R0b20iLCJzY3JvbGxZVG8iLCJwb3NpdGlvbiIsInNjcm9sbExlZnQiLCJzY3JvbGxSaWdodCIsInNjcm9sbFhUbyIsImV2bnRzUHJldmlvdXNWYWx1ZXMiLCJjbGllbnRYIiwiY2xpZW50WSIsImRlbHRhWCIsImRlbHRhWSIsImJpbmRlZEhhbmRsZVdpbmRvd1Jlc2l6ZSIsImhhbmRsZVdpbmRvd1Jlc2l6ZSIsImJpbmQiLCJjb250ZW50V2luZG93IiwiYWRkRXZlbnRMaXN0ZW5lciIsImxpbmVIZWlnaHRQeCIsImNvbnRlbnQiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiY2hpbGRyZW4iLCJjbGFzc05hbWUiLCJjb250ZW50Q2xhc3NOYW1lIiwib3duZXJEb2N1bWVudCIsIndpdGhNb3Rpb24iLCJzbW9vdGhTY3JvbGxpbmciLCJldmVudFR5cGUiLCJzY3JvbGxiYXJZIiwiY2FuU2Nyb2xsWSIsImhhbmRsZVNjcm9sbGJhck1vdmUiLCJoYW5kbGVTY3JvbGxiYXJZUG9zaXRpb25DaGFuZ2UiLCJ2ZXJ0aWNhbENvbnRhaW5lclN0eWxlIiwidmVydGljYWxTY3JvbGxiYXJTdHlsZSIsIm1pblNjcm9sbFNpemUiLCJmb2N1c0NvbnRlbnQiLCJzY3JvbGxiYXJYIiwiY2FuU2Nyb2xsWCIsImhhbmRsZVNjcm9sbGJhclhQb3NpdGlvbkNoYW5nZSIsImhvcml6b250YWxDb250YWluZXJTdHlsZSIsImhvcml6b250YWxTY3JvbGxiYXJTdHlsZSIsImNsYXNzZXMiLCJjb250ZW50Q2xhc3NlcyIsImNvbnRlbnRTdHlsZSIsIm1hcmdpblRvcCIsIm1hcmdpbkxlZnQiLCJzcHJpbmdpZmllZENvbnRlbnRTdHlsZSIsIngiLCJ3cmFwcGVyIiwic3R5bGUiLCJoYW5kbGVXaGVlbCIsImhhbmRsZVRvdWNoU3RhcnQiLCJoYW5kbGVUb3VjaE1vdmUiLCJoYW5kbGVUb3VjaEVuZCIsImhhbmRsZUtleURvd24iLCJmb2N1c2FibGVUYWJJbmRleCIsIm5ld1N0YXRlIiwib25TY3JvbGwiLCJzZXRTdGF0ZSIsImUiLCJ0b3VjaGVzIiwibGVuZ3RoIiwiZXZlbnRQcmV2aW91c1ZhbHVlcyIsInRpbWVzdGFtcCIsIkRhdGUiLCJub3ciLCJjYW5TY3JvbGwiLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BQcm9wYWdhdGlvbiIsInNldFN0YXRlRnJvbUV2ZW50IiwiY29tcG9zZU5ld1N0YXRlIiwic3dhcFdoZWVsQXhlcyIsImRlbHRhTW9kZSIsInNwZWVkIiwic3RvcFNjcm9sbFByb3BhZ2F0aW9uIiwidGFyZ2V0IiwidGFnTmFtZSIsInRvTG93ZXJDYXNlIiwiaXNDb250ZW50RWRpdGFibGUiLCJsaW5lSGVpZ2h0Iiwia2V5Q29kZSIsImNvbXB1dGVTaXplcyIsImdldE1vZGlmaWVkUG9zaXRpb25zSWZOZWVkZWQiLCJjb21wdXRlVG9wUG9zaXRpb24iLCJjb21wdXRlTGVmdFBvc2l0aW9uIiwic2l6ZXMiLCJuZXdUb3BQb3NpdGlvbiIsIm5vcm1hbGl6ZVRvcFBvc2l0aW9uIiwibmV3TGVmdFBvc2l0aW9uIiwibm9ybWFsaXplTGVmdFBvc2l0aW9uIiwib2Zmc2V0SGVpZ2h0Iiwib2Zmc2V0V2lkdGgiLCJzY3JvbGxhYmxlWSIsInZlcnRpY2FsIiwic2Nyb2xsYWJsZVgiLCJob3Jpem9udGFsIiwiYm90dG9tUG9zaXRpb24iLCJyaWdodFBvc2l0aW9uIiwiZm9jdXMiLCJSZWFjdCIsIkNvbXBvbmVudCIsImNoaWxkQ29udGV4dFR5cGVzIiwiUHJvcFR5cGVzIiwib2JqZWN0IiwicHJvcFR5cGVzIiwic3RyaW5nIiwibnVtYmVyIiwiYm9vbCIsImZ1bmMiLCJhbnkiLCJkZWZhdWx0UHJvcHMiLCJ3aW5kb3ciLCJ1bmRlZmluZWQiLCJkb2N1bWVudCIsImZpbmRET01Ob2RlIiwid2FybkFib3V0RnVuY3Rpb25DaGlsZCIsIndhcm5BYm91dEVsZW1lbnRDaGlsZCIsInBvc2l0aXZlT3JaZXJvIiwibW9kaWZ5T2JqVmFsdWVzIiwiaXNSZWFjdDEzIiwicmVhY3QxMyIsImRpZFdhcm5BYm91dENoaWxkIiwiY29tcG9uZW50IiwiY29uc29sZSIsImVycm9yIiwib2JqIiwibW9kaWZpZXIiLCJtb2RpZmllZE9iaiIsImtleSIsImhhc093blByb3BlcnR5IiwidmVyc2lvbiIsInBhcnRzIiwic3BsaXQiLCJtYWpvciIsInBhcnNlSW50IiwibWlub3IiLCJTY3JvbGxCYXIiLCJjYWxjdWxhdGVTdGF0ZSIsInNjcm9sbFNpemUiLCJpc0RyYWdnaW5nIiwibGFzdENsaWVudFBvc2l0aW9uIiwidHlwZSIsImJpbmRlZEhhbmRsZU1vdXNlTW92ZSIsImhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsIiwiaGFuZGxlTW91c2VNb3ZlRm9ySG9yaXpvbnRhbCIsImJpbmRlZEhhbmRsZU1vdXNlVXAiLCJoYW5kbGVNb3VzZVVwIiwibmV4dFByb3BzIiwicmVhbENvbnRlbnRTaXplIiwiY29udGFpbmVyU2l6ZSIsImNvbnRlbnRQb3NpdGlvbiIsInJlbGF0aXZlU2l6ZSIsImZyYWN0aW9uYWxQb3NpdGlvbiIsImNhbGN1bGF0ZUZyYWN0aW9uYWxQb3NpdGlvbiIsInJlYWxTaXplIiwicHJvcG9ydGlvbmFsVG9QYWdlU2Nyb2xsU2l6ZSIsInNjcm9sbFBvc2l0aW9uIiwiTWF0aCIsInJvdW5kIiwic2Nyb2xsYmFyU3R5bGUiLCJjb250YWluZXJTdHlsZSIsImlzVm9yaXppb250YWwiLCJpc1ZlcnRpY2FsIiwic2Nyb2xsU3R5bGVzIiwiY3JlYXRlU2Nyb2xsU3R5bGVzIiwic3ByaW5naWZpZWRTY3JvbGxTdHlsZXMiLCJzY3JvbGxiYXJDbGFzc2VzIiwiaGFuZGxlU2Nyb2xsQmFyQ29udGFpbmVyQ2xpY2siLCJzY3JvbGxiYXJDb250YWluZXIiLCJoYW5kbGVNb3VzZURvd24iLCJtdWx0aXBsaWVyIiwiY29tcHV0ZU11bHRpcGxpZXIiLCJjbGllbnRQb3NpdGlvbiIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInRvcCIsImxlZnQiLCJjbGllbnRTY3JvbGxQb3NpdGlvbiIsIm9uUG9zaXRpb25DaGFuZ2UiLCJvbk1vdmUiLCJvbkZvY3VzIiwiaGVpZ2h0Iiwid2lkdGgiLCJvbmVPZiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELE87QUNWQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDdENBOzs7Ozs7bUJBRWVBLG9COzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNGZjs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFFQTs7QUFHQTs7Ozs7Ozs7Ozs7O0FBRUEsS0FBTUMsYUFBYTtBQUNmQyxZQUFPLE9BRFE7QUFFZkMsVUFBSyxLQUZVO0FBR2ZDLFlBQU8sT0FIUTtBQUlmQyxlQUFVLFVBSks7QUFLZkMsZ0JBQVcsV0FMSTtBQU1mQyxlQUFVO0FBTkssRUFBbkI7O0tBU3FCUCxVOzs7QUFDakIseUJBQVlRLEtBQVosRUFBbUI7QUFBQTs7QUFBQSw2SEFDVEEsS0FEUzs7QUFFZixlQUFLQyxLQUFMLEdBQWE7QUFDVEMsMEJBQWEsQ0FESjtBQUVUQywyQkFBYyxDQUZMO0FBR1RDLHlCQUFZLENBSEg7QUFJVEMsOEJBQWlCLENBSlI7QUFLVEMsd0JBQVcsQ0FMRjtBQU1UQyw2QkFBZ0I7QUFOUCxVQUFiOztBQVNBLGVBQUtDLFVBQUwsR0FBa0I7QUFDZEMsc0JBQVMsbUJBQU07QUFDWCx1QkFBS0MsZUFBTDtBQUNILGNBSGE7QUFJZEMsd0JBQVcscUJBQU07QUFDYix1QkFBS0EsU0FBTDtBQUNILGNBTmE7QUFPZEMsMkJBQWMsd0JBQU07QUFDaEIsdUJBQUtBLFlBQUw7QUFDSCxjQVRhO0FBVWRDLHdCQUFXLG1CQUFDQyxRQUFELEVBQWM7QUFDckIsdUJBQUtELFNBQUwsQ0FBZUMsUUFBZjtBQUNILGNBWmE7QUFhZEMseUJBQVksc0JBQU07QUFDZCx1QkFBS0EsVUFBTDtBQUNILGNBZmE7QUFnQmRDLDBCQUFhLHVCQUFNO0FBQ2YsdUJBQUtBLFdBQUw7QUFDSCxjQWxCYTtBQW1CZEMsd0JBQVcsbUJBQUNILFFBQUQsRUFBYztBQUNyQix1QkFBS0csU0FBTCxDQUFlSCxRQUFmO0FBQ0g7QUFyQmEsVUFBbEI7O0FBd0JBLGVBQUtJLG1CQUFMLEdBQTJCO0FBQ3ZCQyxzQkFBUyxDQURjO0FBRXZCQyxzQkFBUyxDQUZjO0FBR3ZCQyxxQkFBUSxDQUhlO0FBSXZCQyxxQkFBUTtBQUplLFVBQTNCOztBQU9BLGVBQUtDLHdCQUFMLEdBQWdDLE1BQUtDLGtCQUFMLENBQXdCQyxJQUF4QixPQUFoQztBQTFDZTtBQTJDbEI7Ozs7MkNBRWlCO0FBQ2Qsb0JBQU87QUFDSGpCLDZCQUFZLEtBQUtBO0FBRGQsY0FBUDtBQUdIOzs7NkNBRW1CO0FBQ2hCLGlCQUFJLEtBQUtSLEtBQUwsQ0FBVzBCLGFBQWYsRUFBOEI7QUFDMUIsc0JBQUsxQixLQUFMLENBQVcwQixhQUFYLENBQXlCQyxnQkFBekIsQ0FBMEMsUUFBMUMsRUFBb0QsS0FBS0osd0JBQXpEO0FBQ0g7QUFDRCxrQkFBS0ssWUFBTCxHQUFvQiwwQkFBVyx3QkFBWSxLQUFLQyxPQUFqQixDQUFYLENBQXBCO0FBQ0Esa0JBQUtuQixlQUFMO0FBQ0g7OztnREFFc0I7QUFDbkIsaUJBQUksS0FBS1YsS0FBTCxDQUFXMEIsYUFBZixFQUE4QjtBQUMxQixzQkFBSzFCLEtBQUwsQ0FBVzBCLGFBQVgsQ0FBeUJJLG1CQUF6QixDQUE2QyxRQUE3QyxFQUF1RCxLQUFLUCx3QkFBNUQ7QUFDSDtBQUNKOzs7OENBRW9CO0FBQ2pCLGtCQUFLYixlQUFMO0FBQ0g7OztrQ0FFUTtBQUFBOztBQUFBLDBCQUN3RCxLQUFLVixLQUQ3RDtBQUFBLGlCQUNBK0IsUUFEQSxVQUNBQSxRQURBO0FBQUEsaUJBQ1VDLFNBRFYsVUFDVUEsU0FEVjtBQUFBLGlCQUNxQkMsZ0JBRHJCLFVBQ3FCQSxnQkFEckI7QUFBQSxpQkFDdUNDLGFBRHZDLFVBQ3VDQSxhQUR2Qzs7QUFFTCxpQkFBSUMsYUFBYSxLQUFLbkMsS0FBTCxDQUFXb0MsZUFBWCxLQUNaLEtBQUtuQyxLQUFMLENBQVdvQyxTQUFYLEtBQXlCNUMsV0FBV0MsS0FBcEMsSUFBNkMsS0FBS08sS0FBTCxDQUFXb0MsU0FBWCxLQUF5QjVDLFdBQVdFLEdBQWpGLElBQXdGLEtBQUtNLEtBQUwsQ0FBV29DLFNBQVgsS0FBeUI1QyxXQUFXSSxRQUE1SCxJQUNELEtBQUtJLEtBQUwsQ0FBV29DLFNBQVgsS0FBeUI1QyxXQUFXTSxRQUZ2QixDQUFqQjs7QUFJQSxpQkFBSXVDLGFBQWEsS0FBS0MsVUFBTCxLQUNiLDhCQUFDLG1CQUFEO0FBQ0ksZ0NBQWVMLGFBRG5CO0FBRUksMkJBQVUsS0FBS2pDLEtBQUwsQ0FBV0csVUFGekI7QUFHSSxnQ0FBZSxLQUFLSCxLQUFMLENBQVdJLGVBSDlCO0FBSUksMkJBQVUsS0FBS0osS0FBTCxDQUFXQyxXQUp6QjtBQUtJLHlCQUFRLEtBQUtzQyxtQkFBTCxDQUF5QmYsSUFBekIsQ0FBOEIsSUFBOUIsQ0FMWjtBQU1JLG1DQUFrQixLQUFLZ0IsOEJBQUwsQ0FBb0NoQixJQUFwQyxDQUF5QyxJQUF6QyxDQU50QjtBQU9JLGlDQUFnQixLQUFLekIsS0FBTCxDQUFXMEMsc0JBUC9CO0FBUUksaUNBQWdCLEtBQUsxQyxLQUFMLENBQVcyQyxzQkFSL0I7QUFTSSxrQ0FBaUJSLFVBVHJCO0FBVUksZ0NBQWUsS0FBS25DLEtBQUwsQ0FBVzRDLGFBVjlCO0FBV0ksMEJBQVMsS0FBS0MsWUFBTCxDQUFrQnBCLElBQWxCLENBQXVCLElBQXZCLENBWGI7QUFZSSx1QkFBSyxVQVpULEdBRGEsR0FjYixJQWRKOztBQWdCQSxpQkFBSXFCLGFBQWEsS0FBS0MsVUFBTCxLQUNiLDhCQUFDLG1CQUFEO0FBQ0ksZ0NBQWViLGFBRG5CO0FBRUksMkJBQVUsS0FBS2pDLEtBQUwsQ0FBV0ssU0FGekI7QUFHSSxnQ0FBZSxLQUFLTCxLQUFMLENBQVdNLGNBSDlCO0FBSUksMkJBQVUsS0FBS04sS0FBTCxDQUFXRSxZQUp6QjtBQUtJLHlCQUFRLEtBQUtxQyxtQkFBTCxDQUF5QmYsSUFBekIsQ0FBOEIsSUFBOUIsQ0FMWjtBQU1JLG1DQUFrQixLQUFLdUIsOEJBQUwsQ0FBb0N2QixJQUFwQyxDQUF5QyxJQUF6QyxDQU50QjtBQU9JLGlDQUFnQixLQUFLekIsS0FBTCxDQUFXaUQsd0JBUC9CO0FBUUksaUNBQWdCLEtBQUtqRCxLQUFMLENBQVdrRCx3QkFSL0I7QUFTSSxrQ0FBaUJmLFVBVHJCO0FBVUksZ0NBQWUsS0FBS25DLEtBQUwsQ0FBVzRDLGFBVjlCO0FBV0ksMEJBQVMsS0FBS0MsWUFBTCxDQUFrQnBCLElBQWxCLENBQXVCLElBQXZCLENBWGI7QUFZSSx1QkFBSyxZQVpULEdBRGEsR0FjYixJQWRKOztBQWdCQSxpQkFBSSxPQUFPTSxRQUFQLEtBQW9CLFVBQXhCLEVBQW9DO0FBQ2hDO0FBQ0FBLDRCQUFXQSxVQUFYO0FBQ0gsY0FIRCxNQUdPO0FBQ0g7QUFDSDs7QUFFRCxpQkFBSW9CLFVBQVUsaUJBQWlCbkIsYUFBYSxFQUE5QixDQUFkO0FBQ0EsaUJBQUlvQixpQkFBaUIseUJBQXlCbkIsb0JBQW9CLEVBQTdDLENBQXJCOztBQUVBLGlCQUFJb0IsZUFBZTtBQUNmQyw0QkFBVyxDQUFDLEtBQUtyRCxLQUFMLENBQVdDLFdBRFI7QUFFZnFELDZCQUFZLENBQUMsS0FBS3RELEtBQUwsQ0FBV0U7QUFGVCxjQUFuQjtBQUlBLGlCQUFJcUQsMEJBQTBCckIsYUFBYSw0QkFBZ0JrQixZQUFoQixFQUE4QjtBQUFBLHdCQUFLLHlCQUFPSSxDQUFQLENBQUw7QUFBQSxjQUE5QixDQUFiLEdBQTZESixZQUEzRjs7QUFFQSxvQkFDSTtBQUFDLG9DQUFEO0FBQUEsbUJBQVEsT0FBT0csdUJBQWY7QUFDTTtBQUFBLDRCQUNFO0FBQUE7QUFBQTtBQUNJLGtDQUFLO0FBQUEsd0NBQUssT0FBS0UsT0FBTCxHQUFlRCxDQUFwQjtBQUFBLDhCQURUO0FBRUksd0NBQVdOLE9BRmY7QUFHSSxvQ0FBTyxPQUFLbkQsS0FBTCxDQUFXMkQsS0FIdEI7QUFJSSxzQ0FBUyxPQUFLQyxXQUFMLENBQWlCbkMsSUFBakIsQ0FBc0IsTUFBdEI7QUFKYjtBQU1JO0FBQUE7QUFBQTtBQUNJLHNDQUFLO0FBQUEsNENBQUssT0FBS0ksT0FBTCxHQUFlNEIsQ0FBcEI7QUFBQSxrQ0FEVDtBQUVJLHFEQUFZLE9BQUt6RCxLQUFMLENBQVdxRCxZQUF2QixFQUF3Q00sS0FBeEMsQ0FGSjtBQUdJLDRDQUFXUCxjQUhmO0FBSUksK0NBQWMsT0FBS1MsZ0JBQUwsQ0FBc0JwQyxJQUF0QixDQUEyQixNQUEzQixDQUpsQjtBQUtJLDhDQUFhLE9BQUtxQyxlQUFMLENBQXFCckMsSUFBckIsQ0FBMEIsTUFBMUIsQ0FMakI7QUFNSSw2Q0FBWSxPQUFLc0MsY0FBTCxDQUFvQnRDLElBQXBCLENBQXlCLE1BQXpCLENBTmhCO0FBT0ksNENBQVcsT0FBS3VDLGFBQUwsQ0FBbUJ2QyxJQUFuQixDQUF3QixNQUF4QixDQVBmO0FBUUksMkNBQVUsT0FBS3pCLEtBQUwsQ0FBV2lFO0FBUnpCO0FBVUtsQztBQVZMLDBCQU5KO0FBa0JLTyxtQ0FsQkw7QUFtQktRO0FBbkJMLHNCQURGO0FBQUE7QUFETixjQURKO0FBMkJIOzs7MkNBRWlCb0IsUSxFQUFVN0IsUyxFQUFXO0FBQ25DLGlCQUFJLEtBQUtyQyxLQUFMLENBQVdtRSxRQUFmLEVBQXlCO0FBQ3JCLHNCQUFLbkUsS0FBTCxDQUFXbUUsUUFBWCxDQUFvQkQsUUFBcEI7QUFDSDtBQUNELGtCQUFLRSxRQUFMLGNBQWtCRixRQUFsQixJQUE0QjdCLG9CQUE1QjtBQUNIOzs7MENBRWdCZ0MsQyxFQUFHO0FBQUEsaUJBQ1hDLE9BRFcsR0FDQUQsQ0FEQSxDQUNYQyxPQURXOztBQUVoQixpQkFBSUEsUUFBUUMsTUFBUixLQUFtQixDQUF2QixFQUEwQjtBQUFBLGlDQUNHRCxRQUFRLENBQVIsQ0FESDtBQUFBLHFCQUNqQm5ELE9BRGlCLGFBQ2pCQSxPQURpQjtBQUFBLHFCQUNSQyxPQURRLGFBQ1JBLE9BRFE7O0FBRXRCLHNCQUFLb0QsbUJBQUwsZ0JBQ08sS0FBS0EsbUJBRFo7QUFFSXBELHFDQUZKO0FBR0lELHFDQUhKO0FBSUlzRCxnQ0FBV0MsS0FBS0MsR0FBTDtBQUpmO0FBTUg7QUFDSjs7O3lDQUVlTixDLEVBQUc7QUFDZixpQkFBSSxLQUFLTyxTQUFMLEVBQUosRUFBc0I7QUFDbEJQLG1CQUFFUSxjQUFGO0FBQ0FSLG1CQUFFUyxlQUFGO0FBQ0g7O0FBSmMsaUJBTVZSLE9BTlUsR0FNQ0QsQ0FORCxDQU1WQyxPQU5VOztBQU9mLGlCQUFJQSxRQUFRQyxNQUFSLEtBQW1CLENBQXZCLEVBQTBCO0FBQUEsa0NBQ0dELFFBQVEsQ0FBUixDQURIO0FBQUEscUJBQ2pCbkQsT0FEaUIsY0FDakJBLE9BRGlCO0FBQUEscUJBQ1JDLE9BRFEsY0FDUkEsT0FEUTs7O0FBR3RCLHFCQUFJRSxTQUFTLEtBQUtrRCxtQkFBTCxDQUF5QnBELE9BQXpCLEdBQW1DQSxPQUFoRDtBQUNBLHFCQUFJQyxTQUFTLEtBQUttRCxtQkFBTCxDQUF5QnJELE9BQXpCLEdBQW1DQSxPQUFoRDs7QUFFQSxzQkFBS3FELG1CQUFMLGdCQUNPLEtBQUtBLG1CQURaO0FBRUlsRCxtQ0FGSjtBQUdJRCxtQ0FISjtBQUlJRCxxQ0FKSjtBQUtJRCxxQ0FMSjtBQU1Jc0QsZ0NBQVdDLEtBQUtDLEdBQUw7QUFOZjs7QUFTQSxzQkFBS0ksaUJBQUwsQ0FBdUIsS0FBS0MsZUFBTCxDQUFxQixDQUFDM0QsTUFBdEIsRUFBOEIsQ0FBQ0MsTUFBL0IsQ0FBdkI7QUFDSDtBQUNKOzs7d0NBRWMrQyxDLEVBQUc7QUFBQSx3Q0FDb0IsS0FBS0csbUJBRHpCO0FBQUEsaUJBQ1RuRCxNQURTLHdCQUNUQSxNQURTO0FBQUEsaUJBQ0RDLE1BREMsd0JBQ0RBLE1BREM7QUFBQSxpQkFDT21ELFNBRFAsd0JBQ09BLFNBRFA7O0FBRWQsaUJBQUksT0FBT3BELE1BQVAsS0FBa0IsV0FBdEIsRUFBbUNBLFNBQVMsQ0FBVDtBQUNuQyxpQkFBSSxPQUFPQyxNQUFQLEtBQWtCLFdBQXRCLEVBQW1DQSxTQUFTLENBQVQ7QUFDbkMsaUJBQUlvRCxLQUFLQyxHQUFMLEtBQWFGLFNBQWIsR0FBeUIsR0FBN0IsRUFBa0M7QUFDOUIsc0JBQUtNLGlCQUFMLENBQXVCLEtBQUtDLGVBQUwsQ0FBcUIsQ0FBQzNELE1BQUQsR0FBVSxFQUEvQixFQUFtQyxDQUFDQyxNQUFELEdBQVUsRUFBN0MsQ0FBdkIsRUFBeUU3QixXQUFXSSxRQUFwRjtBQUNIOztBQUVELGtCQUFLMkUsbUJBQUwsZ0JBQ08sS0FBS0EsbUJBRFo7QUFFSWxELHlCQUFRLENBRlo7QUFHSUQseUJBQVE7QUFIWjtBQUtIOzs7NkNBRW1CQyxNLEVBQVFELE0sRUFBUTtBQUNoQyxrQkFBSzBELGlCQUFMLENBQXVCLEtBQUtDLGVBQUwsQ0FBcUIzRCxNQUFyQixFQUE2QkMsTUFBN0IsQ0FBdkI7QUFDSDs7O3dEQUU4QlIsUSxFQUFVO0FBQ3JDLGtCQUFLRyxTQUFMLENBQWVILFFBQWY7QUFDSDs7O3dEQUU4QkEsUSxFQUFVO0FBQ3JDLGtCQUFLRCxTQUFMLENBQWVDLFFBQWY7QUFDSDs7O3FDQUVXdUQsQyxFQUFHO0FBQ1gsaUJBQUkvQyxTQUFTK0MsRUFBRS9DLE1BQWY7QUFDQSxpQkFBSUQsU0FBU2dELEVBQUVoRCxNQUFmOztBQUVBLGlCQUFJLEtBQUtyQixLQUFMLENBQVdpRixhQUFmLEVBQThCO0FBQUEsNEJBQ1AsQ0FBQzVELE1BQUQsRUFBU0MsTUFBVCxDQURPO0FBQ3pCQSx1QkFEeUI7QUFDakJELHVCQURpQjtBQUU3Qjs7QUFFRDs7Ozs7O0FBTUEsaUJBQUlnRCxFQUFFYSxTQUFGLEtBQWdCLENBQXBCLEVBQXVCO0FBQ25CNUQsMEJBQVNBLFNBQVMsS0FBS00sWUFBdkI7QUFDQVAsMEJBQVNBLFNBQVMsS0FBS08sWUFBdkI7QUFDSDs7QUFFRE4sc0JBQVNBLFNBQVMsS0FBS3RCLEtBQUwsQ0FBV21GLEtBQTdCO0FBQ0E5RCxzQkFBU0EsU0FBUyxLQUFLckIsS0FBTCxDQUFXbUYsS0FBN0I7O0FBRUEsaUJBQUlqQixXQUFXLEtBQUtjLGVBQUwsQ0FBcUIsQ0FBQzNELE1BQXRCLEVBQThCLENBQUNDLE1BQS9CLENBQWY7O0FBRUEsaUJBQUs0QyxTQUFTaEUsV0FBVCxJQUF3QixLQUFLRCxLQUFMLENBQVdDLFdBQVgsS0FBMkJnRSxTQUFTaEUsV0FBN0QsSUFDQ2dFLFNBQVMvRCxZQUFULElBQXlCLEtBQUtGLEtBQUwsQ0FBV0UsWUFBWCxLQUE0QitELFNBQVMvRCxZQUQvRCxJQUVBLEtBQUtILEtBQUwsQ0FBV29GLHFCQUZmLEVBRXNDO0FBQ2xDZixtQkFBRVEsY0FBRjtBQUNBUixtQkFBRVMsZUFBRjtBQUNIOztBQUVELGtCQUFLQyxpQkFBTCxDQUF1QmIsUUFBdkIsRUFBaUN6RSxXQUFXQyxLQUE1QztBQUNBLGtCQUFLbUQsWUFBTDtBQUNIOzs7dUNBRWF3QixDLEVBQUc7QUFDYjtBQUNBLGlCQUFJQSxFQUFFZ0IsTUFBRixDQUFTQyxPQUFULENBQWlCQyxXQUFqQixPQUFtQyxPQUFuQyxJQUE4Q2xCLEVBQUVnQixNQUFGLENBQVNDLE9BQVQsQ0FBaUJDLFdBQWpCLE9BQW1DLFVBQWpGLElBQStGLENBQUNsQixFQUFFZ0IsTUFBRixDQUFTRyxpQkFBN0csRUFBZ0k7QUFDNUgscUJBQUlsRSxTQUFTLENBQWI7QUFDQSxxQkFBSUQsU0FBUyxDQUFiO0FBQ0EscUJBQUlvRSxjQUFhLEtBQUs3RCxZQUFMLEdBQW9CLEtBQUtBLFlBQXpCLEdBQXdDLEVBQXpEOztBQUVBLHlCQUFReUMsRUFBRXFCLE9BQVY7QUFDSSwwQkFBSyxFQUFMO0FBQVM7QUFDTHBFLGtDQUFTLEtBQUtyQixLQUFMLENBQVdJLGVBQVgsR0FBNkJvRixXQUF0QztBQUNBO0FBQ0osMEJBQUssRUFBTDtBQUFTO0FBQ0xuRSxrQ0FBUyxDQUFDLEtBQUtyQixLQUFMLENBQVdJLGVBQVosR0FBOEJvRixXQUF2QztBQUNBO0FBQ0osMEJBQUssRUFBTDtBQUFTO0FBQ0xwRSxrQ0FBU29FLFdBQVQ7QUFDQTtBQUNKLDBCQUFLLEVBQUw7QUFBUztBQUNMbkUsa0NBQVNtRSxXQUFUO0FBQ0E7QUFDSiwwQkFBSyxFQUFMO0FBQVM7QUFDTHBFLGtDQUFTLENBQUNvRSxXQUFWO0FBQ0E7QUFDSiwwQkFBSyxFQUFMO0FBQVM7QUFDTG5FLGtDQUFTLENBQUNtRSxXQUFWO0FBQ0E7QUFsQlI7O0FBcUJBO0FBQ0EscUJBQUluRSxXQUFXLENBQVgsSUFBZ0JELFdBQVcsQ0FBL0IsRUFBa0M7QUFDOUIseUJBQUk2QyxXQUFXLEtBQUtjLGVBQUwsQ0FBcUIzRCxNQUFyQixFQUE2QkMsTUFBN0IsQ0FBZjs7QUFFQStDLHVCQUFFUSxjQUFGO0FBQ0FSLHVCQUFFUyxlQUFGOztBQUVBLDBCQUFLQyxpQkFBTCxDQUF1QmIsUUFBdkIsRUFBaUN6RSxXQUFXTSxRQUE1QztBQUNIO0FBQ0o7QUFDSjs7OzhDQUVvQjtBQUNqQixpQkFBSW1FLFdBQVcsS0FBS3lCLFlBQUwsRUFBZjtBQUNBekIsd0JBQVcsS0FBSzBCLDRCQUFMLENBQWtDMUIsUUFBbEMsQ0FBWDtBQUNBLGtCQUFLYSxpQkFBTCxDQUF1QmIsUUFBdkI7QUFDSDs7O3lDQUVlN0MsTSxFQUFRQyxNLEVBQVE7QUFDNUIsaUJBQUk0QyxXQUFXLEtBQUt5QixZQUFMLEVBQWY7O0FBRUEsaUJBQUksS0FBS3BELFVBQUwsQ0FBZ0IyQixRQUFoQixDQUFKLEVBQStCO0FBQzNCQSwwQkFBU2hFLFdBQVQsR0FBdUIsS0FBSzJGLGtCQUFMLENBQXdCdkUsTUFBeEIsRUFBZ0M0QyxRQUFoQyxDQUF2QjtBQUNILGNBRkQsTUFFTztBQUNMQSwwQkFBU2hFLFdBQVQsR0FBdUIsQ0FBdkI7QUFDRDtBQUNELGlCQUFJLEtBQUs2QyxVQUFMLENBQWdCbUIsUUFBaEIsQ0FBSixFQUErQjtBQUMzQkEsMEJBQVMvRCxZQUFULEdBQXdCLEtBQUsyRixtQkFBTCxDQUF5QnpFLE1BQXpCLEVBQWlDNkMsUUFBakMsQ0FBeEI7QUFDSDs7QUFFRCxvQkFBT0EsUUFBUDtBQUNIOzs7NENBRWtCNUMsTSxFQUFReUUsSyxFQUFPO0FBQzlCLGlCQUFJQyxpQkFBaUIsS0FBSy9GLEtBQUwsQ0FBV0MsV0FBWCxHQUF5Qm9CLE1BQTlDO0FBQ0Esb0JBQU8sS0FBSzJFLG9CQUFMLENBQTBCRCxjQUExQixFQUEwQ0QsS0FBMUMsQ0FBUDtBQUNIOzs7NkNBRW1CMUUsTSxFQUFRMEUsSyxFQUFPO0FBQy9CLGlCQUFJRyxrQkFBa0IsS0FBS2pHLEtBQUwsQ0FBV0UsWUFBWCxHQUEwQmtCLE1BQWhEO0FBQ0Esb0JBQU8sS0FBSzhFLHFCQUFMLENBQTJCRCxlQUEzQixFQUE0Q0gsS0FBNUMsQ0FBUDtBQUNIOzs7OENBRW9CQyxjLEVBQWdCRCxLLEVBQU87QUFDeEMsaUJBQUlDLGlCQUFpQkQsTUFBTTNGLFVBQU4sR0FBbUIyRixNQUFNMUYsZUFBOUMsRUFBK0Q7QUFDM0QyRixrQ0FBaUJELE1BQU0zRixVQUFOLEdBQW1CMkYsTUFBTTFGLGVBQTFDO0FBQ0g7QUFDRCxpQkFBSTJGLGlCQUFpQixDQUFyQixFQUF3QjtBQUNwQkEsa0NBQWlCLENBQWpCO0FBQ0g7QUFDRCxvQkFBT0EsY0FBUDtBQUNIOzs7K0NBRXFCRSxlLEVBQWlCSCxLLEVBQU87QUFDMUMsaUJBQUlHLGtCQUFrQkgsTUFBTXpGLFNBQU4sR0FBa0J5RixNQUFNeEYsY0FBOUMsRUFBOEQ7QUFDMUQyRixtQ0FBa0JILE1BQU16RixTQUFOLEdBQWtCeUYsTUFBTXhGLGNBQTFDO0FBQ0gsY0FGRCxNQUVPLElBQUkyRixrQkFBa0IsQ0FBdEIsRUFBeUI7QUFDNUJBLG1DQUFrQixDQUFsQjtBQUNIOztBQUVELG9CQUFPQSxlQUFQO0FBQ0g7Ozt3Q0FFYztBQUNYLGlCQUFJOUYsYUFBYyxLQUFLeUIsT0FBTixHQUFpQixLQUFLQSxPQUFMLENBQWF1RSxZQUE5QixHQUE2QyxDQUE5RDtBQUNBLGlCQUFJL0Ysa0JBQW1CLEtBQUtxRCxPQUFOLEdBQWlCLEtBQUtBLE9BQUwsQ0FBYTBDLFlBQTlCLEdBQTZDLENBQW5FO0FBQ0EsaUJBQUk5RixZQUFhLEtBQUt1QixPQUFOLEdBQWlCLEtBQUtBLE9BQUwsQ0FBYXdFLFdBQTlCLEdBQTRDLENBQTVEO0FBQ0EsaUJBQUk5RixpQkFBa0IsS0FBS3NCLE9BQU4sR0FBaUIsS0FBSzZCLE9BQUwsQ0FBYTJDLFdBQTlCLEdBQTRDLENBQWpFOztBQUVBLG9CQUFPO0FBQ0hqRyw2QkFBWUEsVUFEVDtBQUVIQyxrQ0FBaUJBLGVBRmQ7QUFHSEMsNEJBQVdBLFNBSFI7QUFJSEMsaUNBQWdCQTtBQUpiLGNBQVA7QUFNSDs7OzJDQUVpQjtBQUNkLGlCQUFJd0YsUUFBUSxLQUFLSixZQUFMLEVBQVo7QUFDQSxpQkFBSUksTUFBTTNGLFVBQU4sS0FBcUIsS0FBS0gsS0FBTCxDQUFXRyxVQUFoQyxJQUE4QzJGLE1BQU16RixTQUFOLEtBQW9CLEtBQUtMLEtBQUwsQ0FBV0ssU0FBakYsRUFBNEY7QUFDeEYsc0JBQUt5RSxpQkFBTCxDQUF1QixLQUFLYSw0QkFBTCxDQUFrQ0csS0FBbEMsQ0FBdkI7QUFDSDtBQUNKOzs7cUNBRVc7QUFDUixrQkFBS2xGLFNBQUwsQ0FBZSxDQUFmO0FBQ0g7Ozt3Q0FFYztBQUNYLGtCQUFLQSxTQUFMLENBQWdCLEtBQUtaLEtBQUwsQ0FBV0csVUFBWCxHQUF3QixLQUFLSCxLQUFMLENBQVdJLGVBQW5EO0FBQ0g7OztzQ0FFWTtBQUNULGtCQUFLWSxTQUFMLENBQWUsQ0FBZjtBQUNIOzs7dUNBRWE7QUFDVixrQkFBS0EsU0FBTCxDQUFnQixLQUFLaEIsS0FBTCxDQUFXSyxTQUFYLEdBQXVCLEtBQUtMLEtBQUwsQ0FBV00sY0FBbEQ7QUFDSDs7O21DQUVTTCxXLEVBQWE7QUFDbkIsaUJBQUksS0FBS3FDLFVBQUwsRUFBSixFQUF1QjtBQUNuQixxQkFBSXpCLFdBQVcsS0FBS21GLG9CQUFMLENBQTBCL0YsV0FBMUIsRUFBdUMsS0FBS3lGLFlBQUwsRUFBdkMsQ0FBZjtBQUNBLHNCQUFLWixpQkFBTCxDQUF1QixFQUFDN0UsYUFBYVksUUFBZCxFQUF2QixFQUFnRHJCLFdBQVdFLEdBQTNEO0FBQ0g7QUFDSjs7O21DQUVTUSxZLEVBQWM7QUFDcEIsaUJBQUksS0FBSzRDLFVBQUwsRUFBSixFQUF1QjtBQUNuQixxQkFBSWpDLFdBQVcsS0FBS3FGLHFCQUFMLENBQTJCaEcsWUFBM0IsRUFBeUMsS0FBS3dGLFlBQUwsRUFBekMsQ0FBZjtBQUNBLHNCQUFLWixpQkFBTCxDQUF1QixFQUFDNUUsY0FBY1csUUFBZixFQUF2QixFQUFpRHJCLFdBQVdFLEdBQTVEO0FBQ0g7QUFDSjs7O3NDQUU4QjtBQUFBLGlCQUFwQk0sS0FBb0IsdUVBQVosS0FBS0EsS0FBTzs7QUFDM0IsaUJBQUlxRyxjQUFjckcsTUFBTUcsVUFBTixHQUFtQkgsTUFBTUksZUFBM0M7QUFDQSxvQkFBT2lHLGVBQWUsS0FBS3RHLEtBQUwsQ0FBV3VHLFFBQWpDO0FBQ0g7OztzQ0FFOEI7QUFBQSxpQkFBcEJ0RyxLQUFvQix1RUFBWixLQUFLQSxLQUFPOztBQUMzQixpQkFBSXVHLGNBQWN2RyxNQUFNSyxTQUFOLEdBQWtCTCxNQUFNTSxjQUExQztBQUNBLG9CQUFPaUcsZUFBZSxLQUFLeEcsS0FBTCxDQUFXeUcsVUFBakM7QUFDSDs7O3FDQUU2QjtBQUFBLGlCQUFwQnhHLEtBQW9CLHVFQUFaLEtBQUtBLEtBQU87O0FBQzFCLG9CQUFPLEtBQUtzQyxVQUFMLENBQWdCdEMsS0FBaEIsS0FBMEIsS0FBSzhDLFVBQUwsQ0FBZ0I5QyxLQUFoQixDQUFqQztBQUNIOzs7c0RBRTRCaUUsUSxFQUFVO0FBQ25DLGlCQUFJd0MsaUJBQWlCeEMsU0FBUzlELFVBQVQsR0FBc0I4RCxTQUFTN0QsZUFBcEQ7QUFDQSxpQkFBSSxLQUFLSixLQUFMLENBQVdDLFdBQVgsSUFBMEJ3RyxjQUE5QixFQUE4QztBQUMxQ3hDLDBCQUFTaEUsV0FBVCxHQUF1QixLQUFLcUMsVUFBTCxDQUFnQjJCLFFBQWhCLElBQTRCLDJCQUFld0MsY0FBZixDQUE1QixHQUE2RCxDQUFwRjtBQUNIOztBQUVELGlCQUFJQyxnQkFBZ0J6QyxTQUFTNUQsU0FBVCxHQUFxQjRELFNBQVMzRCxjQUFsRDtBQUNBLGlCQUFJLEtBQUtOLEtBQUwsQ0FBV0UsWUFBWCxJQUEyQndHLGFBQS9CLEVBQThDO0FBQzFDekMsMEJBQVMvRCxZQUFULEdBQXdCLEtBQUs0QyxVQUFMLENBQWdCbUIsUUFBaEIsSUFBNEIsMkJBQWV5QyxhQUFmLENBQTVCLEdBQTRELENBQXBGO0FBQ0g7O0FBRUQsb0JBQU96QyxRQUFQO0FBQ0g7Ozt3Q0FFYztBQUNYLGlCQUFHLEtBQUtyQyxPQUFSLEVBQWlCO0FBQ2IseUNBQVksS0FBS0EsT0FBakIsRUFBMEIrRSxLQUExQjtBQUNIO0FBQ0o7Ozs7R0FuYm1DQyxnQkFBTUMsUzs7bUJBQXpCdEgsVTs7O0FBc2JyQkEsWUFBV3VILGlCQUFYLEdBQStCO0FBQzNCdkcsaUJBQVl3RyxvQkFBVUM7QUFESyxFQUEvQjs7QUFJQXpILFlBQVcwSCxTQUFYLEdBQXVCO0FBQ25CbEYsZ0JBQVdnRixvQkFBVUcsTUFERjtBQUVuQnhELFlBQU9xRCxvQkFBVUMsTUFGRTtBQUduQjlCLFlBQU82QixvQkFBVUksTUFIRTtBQUluQm5GLHVCQUFrQitFLG9CQUFVRyxNQUpUO0FBS25COUQsbUJBQWMyRCxvQkFBVUMsTUFMTDtBQU1uQlYsZUFBVVMsb0JBQVVLLElBTkQ7QUFPbkIzRSw2QkFBd0JzRSxvQkFBVUMsTUFQZjtBQVFuQnRFLDZCQUF3QnFFLG9CQUFVQyxNQVJmO0FBU25CUixpQkFBWU8sb0JBQVVLLElBVEg7QUFVbkJwRSwrQkFBMEIrRCxvQkFBVUMsTUFWakI7QUFXbkIvRCwrQkFBMEI4RCxvQkFBVUMsTUFYakI7QUFZbkI5QyxlQUFVNkMsb0JBQVVNLElBWkQ7QUFhbkI1RixvQkFBZXNGLG9CQUFVTyxHQWJOO0FBY25CckYsb0JBQWU4RSxvQkFBVU8sR0FkTjtBQWVuQm5GLHNCQUFpQjRFLG9CQUFVSyxJQWZSO0FBZ0JuQnpFLG9CQUFlb0Usb0JBQVVJLE1BaEJOO0FBaUJuQm5DLG9CQUFlK0Isb0JBQVVLLElBakJOO0FBa0JuQmpDLDRCQUF1QjRCLG9CQUFVSyxJQWxCZDtBQW1CbkJwRCx3QkFBbUIrQyxvQkFBVUk7QUFuQlYsRUFBdkI7O0FBc0JBNUgsWUFBV2dJLFlBQVgsR0FBMEI7QUFDdEJyQyxZQUFPLENBRGU7QUFFdEJvQixlQUFVLElBRlk7QUFHdEJFLGlCQUFZLElBSFU7QUFJdEJyRSxzQkFBaUIsS0FKSztBQUt0QjZDLG9CQUFlLEtBTE87QUFNdEJ2RCxvQkFBZ0IsUUFBTytGLE1BQVAseUNBQU9BLE1BQVAsT0FBa0IsUUFBbkIsR0FBK0JBLE1BQS9CLEdBQXdDQyxTQU5qQztBQU90QnhGLG9CQUFnQixRQUFPeUYsUUFBUCx5Q0FBT0EsUUFBUCxPQUFvQixRQUFyQixHQUFpQ0EsUUFBakMsR0FBNENELFNBUHJDO0FBUXRCekQsd0JBQW1CO0FBUkcsRUFBMUIsQzs7Ozs7O0FDbmVBLGdEOzs7Ozs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQzNCQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBLEVBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFxQjtBQUNyQjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0NBQXFDOztBQUVyQztBQUNBO0FBQ0E7O0FBRUEsNEJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBLDZCQUE0QixVQUFVOzs7Ozs7O0FDdkx0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJDQUEwQzs7QUFFMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWEsUUFBUTtBQUNyQixlQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVTtBQUNWLDhCQUE2QjtBQUM3QixTQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBK0IsS0FBSztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNULDZCQUE0QjtBQUM1QixRQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUIsc0JBQXNCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0JBQXFCLDJCQUEyQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW1CLGdDQUFnQztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzQkFBcUIsZ0NBQWdDO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7OztBQzFpQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGlDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNILG1DQUFrQztBQUNsQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWdCLHNCQUFzQjtBQUN0Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBa0Isb0JBQW9CO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7Ozs7OztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVcsT0FBTztBQUNsQixZQUFXLE9BQU87QUFDbEIsWUFBVyxPQUFPO0FBQ2xCLFlBQVcsT0FBTztBQUNsQixZQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkdBQTRHO0FBQzVHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTJEO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7Ozs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUMxREE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsWUFBVyxZQUFZO0FBQ3ZCLGNBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQTZCOztBQUU3QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkI7Ozs7OztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTs7QUFFQTs7Ozs7OztBQzFCQTs7QUFFQTs7QUFFQSxnQ0FBK0IscURBQXFEOztBQUVwRjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSxxRDs7Ozs7O0FDbENBOztBQUVBOztBQUVBLG9EQUFtRCxnQkFBZ0Isc0JBQXNCLE9BQU8sMkJBQTJCLDBCQUEwQix5REFBeUQsMkJBQTJCLEVBQUUsRUFBRSxFQUFFLGVBQWU7O0FBRTlQLGtDQUFpQywyQ0FBMkMsZ0JBQWdCLGtCQUFrQixPQUFPLDJCQUEyQix3REFBd0QsZ0NBQWdDLHVEQUF1RCwyREFBMkQsRUFBRSxFQUFFLHlEQUF5RCxxRUFBcUUsNkRBQTZELG9CQUFvQixHQUFHLEVBQUU7O0FBRWxqQix1Q0FBc0MsdUNBQXVDLGtCQUFrQjs7QUFFL0Ysa0RBQWlELDBDQUEwQywwREFBMEQsRUFBRTs7QUFFdkosMkNBQTBDLCtEQUErRCxxR0FBcUcsRUFBRSx5RUFBeUUsZUFBZSx5RUFBeUUsRUFBRSxFQUFFLHVIQUF1SDs7QUFFNWU7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0EsSUFBRzs7QUFFSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUFzQztBQUN0QywwQ0FBeUM7QUFDekMseUNBQXdDO0FBQ3hDLDRDQUEyQztBQUMzQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBd0IscUlBQXFJO0FBQzdKO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBK0IsTUFBTSxjQUFjLE1BQU07QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaURBQWdEO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVztBQUNYO0FBQ0E7QUFDQSw0QkFBMkIscUJBQXFCO0FBQ2hEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7O0FBRVQ7O0FBRUE7QUFDQSxRQUFPO0FBQ1A7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOERBQTZEO0FBQzdEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsVzs7Ozs7Ozs7QUN4UUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxxQzs7Ozs7OztBQ2pCQSxVQUFTLElBQUksaUNBQWlDLE9BQU87QUFDckQsTUFBSyxjQUFjLHlCQUF5QixRQUFRLFFBQVE7O0FBRTVEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUM7Ozs7Ozs7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyQjs7Ozs7O0FDMUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEVBQUM7Ozs7Ozs7O0FDL0JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFjLDRCQUE0QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUFzQixlQUFlO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBLGNBQWE7QUFDYixzQ0FBcUMsVUFBVTtBQUMvQztBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsbUJBQWtCLGtCQUFrQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDMUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxFQUFDOztBQUVEOzs7Ozs7Ozs7O0FDakNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEscUM7Ozs7OztBQzlCQTs7QUFFQTs7QUFFQSxvREFBbUQsZ0JBQWdCLHNCQUFzQixPQUFPLDJCQUEyQiwwQkFBMEIseURBQXlELDJCQUEyQixFQUFFLEVBQUUsRUFBRSxlQUFlOztBQUU5UCxrQ0FBaUMsMkNBQTJDLGdCQUFnQixrQkFBa0IsT0FBTywyQkFBMkIsd0RBQXdELGdDQUFnQyx1REFBdUQsMkRBQTJELEVBQUUsRUFBRSx5REFBeUQscUVBQXFFLDZEQUE2RCxvQkFBb0IsR0FBRyxFQUFFOztBQUVsakIsdUNBQXNDLHVDQUF1QyxrQkFBa0I7O0FBRS9GLGtEQUFpRCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRXZKLDJDQUEwQywrREFBK0QscUdBQXFHLEVBQUUseUVBQXlFLGVBQWUseUVBQXlFLEVBQUUsRUFBRSx1SEFBdUg7O0FBRTVlOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0Esa0JBQWlCLDBCQUEwQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBLElBQUc7O0FBRUg7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNCQUFxQiw2QkFBNkI7QUFDbEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTRDO0FBQzVDLGlEQUFnRDtBQUNoRCwrQ0FBOEM7QUFDOUMsbURBQWtEO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBd0IsaUpBQWlKO0FBQ3pLO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBK0IsTUFBTSxjQUFjLE1BQU07QUFDekQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdCQUF1Qix1QkFBdUI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFhO0FBQ2I7QUFDQTtBQUNBLDhCQUE2QixxQkFBcUI7QUFDbEQ7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTOztBQUVUOztBQUVBO0FBQ0EsUUFBTztBQUNQOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4REFBNkQ7QUFDN0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFc7Ozs7OztBQy9SQTs7QUFFQTs7QUFFQSxvREFBbUQsZ0JBQWdCLHNCQUFzQixPQUFPLDJCQUEyQiwwQkFBMEIseURBQXlELDJCQUEyQixFQUFFLEVBQUUsRUFBRSxlQUFlOztBQUU5UCxrQ0FBaUMsMkNBQTJDLGdCQUFnQixrQkFBa0IsT0FBTywyQkFBMkIsd0RBQXdELGdDQUFnQyx1REFBdUQsMkRBQTJELEVBQUUsRUFBRSx5REFBeUQscUVBQXFFLDZEQUE2RCxvQkFBb0IsR0FBRyxFQUFFOztBQUVsakIsdUNBQXNDLHVDQUF1QyxrQkFBa0I7O0FBRS9GLGtEQUFpRCwwQ0FBMEMsMERBQTBELEVBQUU7O0FBRXZKLDJDQUEwQywrREFBK0QscUdBQXFHLEVBQUUseUVBQXlFLGVBQWUseUVBQXlFLEVBQUUsRUFBRSx1SEFBdUg7O0FBRTVlOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxLQUFJLDJDQUEyQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBLG9CQUFtQiw4QkFBOEI7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQVk7QUFDWixJQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0JBQWlCLDhCQUE4QjtBQUMvQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQkFBaUIsOEJBQThCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsa0RBQWlELEtBQUssd0JBQXdCO0FBQzlFLE1BQUssNkNBQTZDO0FBQ2xEOztBQUVBO0FBQ0EsNEJBQTJCO0FBQzNCO0FBQ0EscUVBQW9FLEtBQUssS0FBSztBQUM5RSw2Q0FBNEMsS0FBSyxPQUFPO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBZ0IsK0RBQStEO0FBQy9FO0FBQ0E7QUFDQTtBQUNBLGlCQUFnQiwrREFBK0Q7QUFDL0U7QUFDQTtBQUNBLGFBQVk7QUFDWixJQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWlCLGlDQUFpQztBQUNsRDtBQUNBO0FBQ0Esb0JBQW1CLGlDQUFpQztBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBLE1BQUs7QUFDTDtBQUNBLElBQUc7O0FBRUg7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHNCQUFxQiw2QkFBNkI7QUFDbEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE0QztBQUM1QyxpREFBZ0Q7QUFDaEQsK0NBQThDO0FBQzlDLG1EQUFrRDtBQUNsRDtBQUNBO0FBQ0E7QUFDQSxtQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdDQUErQixNQUFNLGNBQWMsTUFBTTtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlEQUFnRDtBQUNoRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsd0JBQXVCLGlDQUFpQztBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWE7QUFDYjtBQUNBO0FBQ0EsOEJBQTZCLHFCQUFxQjtBQUNsRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUzs7QUFFVDs7QUFFQTtBQUNBLFFBQU87QUFDUDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx3QkFBdUIsS0FBSyw2QkFBNkIsS0FBSztBQUM5RCwyQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSx3QkFBdUIsdUJBQXVCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQSxNQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhEQUE2RDtBQUM3RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0VBQXVFO0FBQ3ZFLG9EQUFtRDtBQUNuRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDOzs7Ozs7OztBQ3ZnQkE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTRCOztBQUU1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWlCLGlCQUFpQjtBQUNsQztBQUNBO0FBQ0E7QUFDQSxrQkFBaUIsaUJBQWlCO0FBQ2xDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBaUIsaUJBQWlCO0FBQ2xDO0FBQ0E7QUFDQSxrQkFBaUIsaUJBQWlCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBcUIsaUJBQWlCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBbUIsaUJBQWlCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIOztBQUVBO0FBQ0EsMkU7Ozs7OztBQzNHQTs7QUFFQTs7QUFFQSxvREFBbUQsZ0JBQWdCLHNCQUFzQixPQUFPLDJCQUEyQiwwQkFBMEIseURBQXlELDJCQUEyQixFQUFFLEVBQUUsRUFBRSxlQUFlOztBQUU5UDs7QUFFQSx1Q0FBc0MsdUNBQXVDLGtCQUFrQjs7QUFFL0Y7O0FBRUE7O0FBRUEsZ0NBQStCO0FBQy9CO0FBQ0EsRUFBQzs7QUFFRDtBQUNBLHFCQUFvQiwwQkFBMEIsV0FBVztBQUN6RDs7QUFFQSxxQzs7Ozs7O0FDdEJBOztBQUVBO0FBQ0E7QUFDQSxjQUFhLDhCQUE4QjtBQUMzQyxZQUFXLDhCQUE4QjtBQUN6QyxZQUFXLDhCQUE4QjtBQUN6QyxXQUFVO0FBQ1Y7QUFDQSxxQzs7Ozs7O0FDVEE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFDOzs7Ozs7Ozs7Ozs7U0NYZ0IyRCxXLEdBQUFBLFc7U0FRQUMsc0IsR0FBQUEsc0I7U0FTQUMscUIsR0FBQUEscUI7U0FTQUMsYyxHQUFBQSxjO1NBSUFDLGUsR0FBQUEsZTtTQVNBQyxTLEdBQUFBLFM7O0FBNUNoQjs7Ozs7O0FBRUEsS0FBTUMsVUFBVUQsVUFBVXBCLGVBQVYsQ0FBaEI7QUFDQSxLQUFJc0Isb0JBQW9CLEtBQXhCOztBQUVPLFVBQVNQLFdBQVQsQ0FBcUJRLFNBQXJCLEVBQStCO0FBQ2xDLFNBQUcsQ0FBQ0YsT0FBSixFQUFZO0FBQ1IsZ0JBQU9FLFNBQVA7QUFDSCxNQUZELE1BRUs7QUFDRCxnQkFBT3ZCLGdCQUFNZSxXQUFOLENBQWtCUSxTQUFsQixDQUFQO0FBQ0g7QUFDSjs7QUFFTSxVQUFTUCxzQkFBVCxHQUFrQztBQUNyQyxTQUFJTSxxQkFBcUJELE9BQXpCLEVBQWtDO0FBQ2hDO0FBQ0Q7O0FBRURDLHlCQUFvQixJQUFwQjtBQUNBRSxhQUFRQyxLQUFSLENBQWMsb0dBQWQ7QUFDRDs7QUFFSSxVQUFTUixxQkFBVCxHQUFpQztBQUNwQyxTQUFJSyxxQkFBcUIsQ0FBQ0QsT0FBMUIsRUFBbUM7QUFDN0I7QUFDTDs7QUFFREMseUJBQW9CLElBQXBCO0FBQ0FFLGFBQVFDLEtBQVIsQ0FBZSx1RUFBZjtBQUNEOztBQUVJLFVBQVNQLGNBQVQsQ0FBd0JYLE1BQXhCLEVBQStCO0FBQ2xDLFlBQU9BLFNBQVMsQ0FBVCxHQUFhLENBQWIsR0FBaUJBLE1BQXhCO0FBQ0g7O0FBRU0sVUFBU1ksZUFBVCxDQUEwQk8sR0FBMUIsRUFBaUQ7QUFBQSxTQUFsQkMsUUFBa0IsdUVBQVA7QUFBQSxnQkFBSy9FLENBQUw7QUFBQSxNQUFPOztBQUNwRCxTQUFJZ0YsY0FBYyxFQUFsQjtBQUNBLFVBQUksSUFBSUMsR0FBUixJQUFlSCxHQUFmLEVBQW1CO0FBQ2YsYUFBR0EsSUFBSUksY0FBSixDQUFtQkQsR0FBbkIsQ0FBSCxFQUE0QkQsWUFBWUMsR0FBWixJQUFtQkYsU0FBU0QsSUFBSUcsR0FBSixDQUFULENBQW5CO0FBQy9COztBQUVELFlBQU9ELFdBQVA7QUFDSDs7QUFFTSxVQUFTUixTQUFULENBQW1CcEIsS0FBbkIsRUFBMEI7QUFBQSxTQUNyQitCLE9BRHFCLEdBQ1QvQixLQURTLENBQ3JCK0IsT0FEcUI7O0FBRTdCLFNBQUksT0FBT0EsT0FBUCxLQUFtQixRQUF2QixFQUFpQztBQUM3QixnQkFBTyxJQUFQO0FBQ0g7O0FBRUQsU0FBTUMsUUFBUUQsUUFBUUUsS0FBUixDQUFjLEdBQWQsQ0FBZDtBQUNBLFNBQU1DLFFBQVFDLFNBQVNILE1BQU0sQ0FBTixDQUFULEVBQW1CLEVBQW5CLENBQWQ7QUFDQSxTQUFNSSxRQUFRRCxTQUFTSCxNQUFNLENBQU4sQ0FBVCxFQUFtQixFQUFuQixDQUFkOztBQUVBLFlBQU9FLFVBQVUsQ0FBVixJQUFlRSxVQUFVLEVBQWhDO0FBQ0gsRTs7Ozs7Ozs7Ozs7Ozs7OztBQ3ZERDs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7S0FFTUMsUzs7O0FBQ0Ysd0JBQVlsSixLQUFaLEVBQWtCO0FBQUE7O0FBQUEsMkhBQ1JBLEtBRFE7O0FBRWQsYUFBSWtFLFdBQVcsTUFBS2lGLGNBQUwsQ0FBb0JuSixLQUFwQixDQUFmO0FBQ0EsZUFBS0MsS0FBTCxHQUFhO0FBQ1RhLHVCQUFVb0QsU0FBU3BELFFBRFY7QUFFVHNJLHlCQUFZbEYsU0FBU2tGLFVBRlo7QUFHVEMseUJBQVksS0FISDtBQUlUQyxpQ0FBb0I7QUFKWCxVQUFiOztBQU9BLGFBQUd0SixNQUFNdUosSUFBTixLQUFlLFVBQWxCLEVBQTZCO0FBQ3pCLG1CQUFLQyxxQkFBTCxHQUE2QixNQUFLQywwQkFBTCxDQUFnQ2hJLElBQWhDLE9BQTdCO0FBQ0gsVUFGRCxNQUVPO0FBQ0gsbUJBQUsrSCxxQkFBTCxHQUE2QixNQUFLRSw0QkFBTCxDQUFrQ2pJLElBQWxDLE9BQTdCO0FBQ0g7O0FBRUQsZUFBS2tJLG1CQUFMLEdBQTJCLE1BQUtDLGFBQUwsQ0FBbUJuSSxJQUFuQixPQUEzQjtBQWhCYztBQWlCakI7Ozs7NkNBRWtCO0FBQ2YsaUJBQUksS0FBS3pCLEtBQUwsQ0FBV2tDLGFBQWYsRUFBOEI7QUFDMUIsc0JBQUtsQyxLQUFMLENBQVdrQyxhQUFYLENBQXlCUCxnQkFBekIsQ0FBMEMsV0FBMUMsRUFBdUQsS0FBSzZILHFCQUE1RDtBQUNBLHNCQUFLeEosS0FBTCxDQUFXa0MsYUFBWCxDQUF5QlAsZ0JBQXpCLENBQTBDLFNBQTFDLEVBQXFELEtBQUtnSSxtQkFBMUQ7QUFDSDtBQUNKOzs7bURBRXlCRSxTLEVBQVU7QUFDaEMsa0JBQUt6RixRQUFMLENBQWMsS0FBSytFLGNBQUwsQ0FBb0JVLFNBQXBCLENBQWQ7QUFDSDs7O2dEQUVxQjtBQUNsQixpQkFBSSxLQUFLN0osS0FBTCxDQUFXa0MsYUFBZixFQUE4QjtBQUMxQixzQkFBS2xDLEtBQUwsQ0FBV2tDLGFBQVgsQ0FBeUJKLG1CQUF6QixDQUE2QyxXQUE3QyxFQUEwRCxLQUFLMEgscUJBQS9EO0FBQ0Esc0JBQUt4SixLQUFMLENBQVdrQyxhQUFYLENBQXlCSixtQkFBekIsQ0FBNkMsU0FBN0MsRUFBd0QsS0FBSzZILG1CQUE3RDtBQUNIO0FBQ0o7OztxREFFMkJHLGUsRUFBaUJDLGEsRUFBZUMsZSxFQUFnQjtBQUN4RSxpQkFBSUMsZUFBZUgsa0JBQWtCQyxhQUFyQzs7QUFFQSxvQkFBTyxJQUFLLENBQUNFLGVBQWVELGVBQWhCLElBQW1DQyxZQUEvQztBQUNIOzs7d0NBRWNqSyxLLEVBQU07QUFDakIsaUJBQUlrSyxxQkFBcUIsS0FBS0MsMkJBQUwsQ0FBaUNuSyxNQUFNb0ssUUFBdkMsRUFBaURwSyxNQUFNK0osYUFBdkQsRUFBc0UvSixNQUFNYyxRQUE1RSxDQUF6QjtBQUNBLGlCQUFJdUosK0JBQStCckssTUFBTStKLGFBQU4sR0FBc0IvSixNQUFNK0osYUFBNUIsR0FBNEMvSixNQUFNb0ssUUFBckY7QUFDQSxpQkFBSWhCLGFBQWFpQiwrQkFBK0JySyxNQUFNNEMsYUFBckMsR0FBcUQ1QyxNQUFNNEMsYUFBM0QsR0FBMkV5SCw0QkFBNUY7O0FBRUEsaUJBQUlDLGlCQUFpQixDQUFDdEssTUFBTStKLGFBQU4sR0FBc0JYLFVBQXZCLElBQXFDYyxrQkFBMUQ7QUFDQSxvQkFBTztBQUNIZCw2QkFBWUEsVUFEVDtBQUVIdEksMkJBQVV5SixLQUFLQyxLQUFMLENBQVdGLGNBQVg7QUFGUCxjQUFQO0FBSUg7OztrQ0FFTztBQUFBOztBQUFBLDBCQUNzRSxLQUFLdEssS0FEM0U7QUFBQSxpQkFDQ29DLGVBREQsVUFDQ0EsZUFERDtBQUFBLGlCQUNrQmlILFVBRGxCLFVBQ2tCQSxVQURsQjtBQUFBLGlCQUM4QkUsSUFEOUIsVUFDOEJBLElBRDlCO0FBQUEsaUJBQ29Da0IsY0FEcEMsVUFDb0NBLGNBRHBDO0FBQUEsaUJBQ29EQyxjQURwRCxVQUNvREEsY0FEcEQ7O0FBRUosaUJBQUlDLGdCQUFnQnBCLFNBQVMsWUFBN0I7QUFDQSxpQkFBSXFCLGFBQWFyQixTQUFTLFVBQTFCO0FBQ0EsaUJBQUlzQixlQUFlLEtBQUtDLGtCQUFMLEVBQW5CO0FBQ0EsaUJBQUlDLDBCQUEwQjNJLGtCQUFrQiw0QkFBZ0J5SSxZQUFoQixFQUE4QjtBQUFBLHdCQUFLLHlCQUFPcEgsQ0FBUCxDQUFMO0FBQUEsY0FBOUIsQ0FBbEIsR0FBa0VvSCxZQUFoRzs7QUFFQSxpQkFBSUcsNkNBQTBDM0IsYUFBYSxRQUFiLEdBQXdCLEVBQWxFLFdBQXdFc0IsZ0JBQWdCLFlBQWhCLEdBQStCLEVBQXZHLFdBQTZHQyxhQUFhLFVBQWIsR0FBMEIsRUFBdkksQ0FBSjs7QUFFQSxvQkFDSTtBQUFDLG9DQUFEO0FBQUEsbUJBQVEsT0FBT0csdUJBQWY7QUFDTTtBQUFBLDRCQUNFO0FBQUE7QUFBQTtBQUNJLHdDQUFXQyxnQkFEZjtBQUVJLG9DQUFPTixjQUZYO0FBR0ksMENBQWEsT0FBS08sNkJBQUwsQ0FBbUN4SixJQUFuQyxDQUF3QyxNQUF4QyxDQUhqQjtBQUlJLGtDQUFNO0FBQUEsd0NBQUssT0FBS3lKLGtCQUFMLEdBQTBCekgsQ0FBL0I7QUFBQTtBQUpWO0FBTUk7QUFDSSx3Q0FBVSxXQURkO0FBRUksaURBQVlnSCxjQUFaLEVBQStCOUcsS0FBL0IsQ0FGSjtBQUdJLDBDQUFhLE9BQUt3SCxlQUFMLENBQXFCMUosSUFBckIsQ0FBMEIsTUFBMUI7QUFIakI7QUFOSixzQkFERjtBQUFBO0FBRE4sY0FESjtBQWtCSDs7O3VEQUU2QjRDLEMsRUFBRztBQUM3QkEsZUFBRVEsY0FBRjtBQUNBLGlCQUFJdUcsYUFBYSxLQUFLQyxpQkFBTCxFQUFqQjtBQUNBLGlCQUFJQyxpQkFBaUIsS0FBS1YsVUFBTCxLQUFvQnZHLEVBQUVqRCxPQUF0QixHQUFnQ2lELEVBQUVsRCxPQUF2RDs7QUFINkIseUNBSVQsS0FBSytKLGtCQUFMLENBQXdCSyxxQkFBeEIsRUFKUztBQUFBLGlCQUl2QkMsR0FKdUIseUJBSXZCQSxHQUp1QjtBQUFBLGlCQUlsQkMsSUFKa0IseUJBSWxCQSxJQUprQjs7QUFLN0IsaUJBQUlDLHVCQUF1QixLQUFLZCxVQUFMLEtBQW9CWSxHQUFwQixHQUEwQkMsSUFBckQ7O0FBRUEsaUJBQUkzSyxXQUFXd0ssaUJBQWlCSSxvQkFBaEM7QUFDQSxpQkFBSXJCLCtCQUErQixLQUFLckssS0FBTCxDQUFXK0osYUFBWCxHQUEyQixLQUFLL0osS0FBTCxDQUFXK0osYUFBdEMsR0FBc0QsS0FBSy9KLEtBQUwsQ0FBV29LLFFBQXBHOztBQUVBLGtCQUFLaEcsUUFBTCxDQUFjLEVBQUNpRixZQUFZLElBQWIsRUFBbUJDLG9CQUFvQmdDLGNBQXZDLEVBQWQ7QUFDQSxrQkFBS3RMLEtBQUwsQ0FBVzJMLGdCQUFYLENBQTRCLENBQUM3SyxXQUFXdUosK0JBQStCLENBQTNDLElBQWdEZSxVQUE1RTtBQUNIOzs7c0RBRTRCL0csQyxFQUFFO0FBQzNCLGlCQUFJK0csYUFBYSxLQUFLQyxpQkFBTCxFQUFqQjs7QUFFQSxpQkFBRyxLQUFLcEwsS0FBTCxDQUFXb0osVUFBZCxFQUF5QjtBQUNyQmhGLG1CQUFFUSxjQUFGO0FBQ0EscUJBQUl4RCxTQUFTLEtBQUtwQixLQUFMLENBQVdxSixrQkFBWCxHQUFnQ2pGLEVBQUVsRCxPQUEvQztBQUNBLHNCQUFLaUQsUUFBTCxDQUFjLEVBQUVrRixvQkFBb0JqRixFQUFFbEQsT0FBeEIsRUFBZDtBQUNBLHNCQUFLbkIsS0FBTCxDQUFXNEwsTUFBWCxDQUFrQixDQUFsQixFQUFxQnZLLFNBQVMrSixVQUE5QjtBQUNIO0FBQ0o7OztvREFFMEIvRyxDLEVBQUU7QUFDekIsaUJBQUkrRyxhQUFhLEtBQUtDLGlCQUFMLEVBQWpCOztBQUVBLGlCQUFHLEtBQUtwTCxLQUFMLENBQVdvSixVQUFkLEVBQXlCO0FBQ3JCaEYsbUJBQUVRLGNBQUY7QUFDQSxxQkFBSXZELFNBQVMsS0FBS3JCLEtBQUwsQ0FBV3FKLGtCQUFYLEdBQWdDakYsRUFBRWpELE9BQS9DO0FBQ0Esc0JBQUtnRCxRQUFMLENBQWMsRUFBRWtGLG9CQUFvQmpGLEVBQUVqRCxPQUF4QixFQUFkO0FBQ0Esc0JBQUtwQixLQUFMLENBQVc0TCxNQUFYLENBQWtCdEssU0FBUzhKLFVBQTNCLEVBQXVDLENBQXZDO0FBQ0g7QUFDSjs7O3lDQUVlL0csQyxFQUFFO0FBQ2RBLGVBQUVRLGNBQUY7QUFDQVIsZUFBRVMsZUFBRjtBQUNBLGlCQUFJd0UscUJBQXFCLEtBQUtzQixVQUFMLEtBQW9CdkcsRUFBRWpELE9BQXRCLEdBQStCaUQsRUFBRWxELE9BQTFEO0FBQ0Esa0JBQUtpRCxRQUFMLENBQWMsRUFBQ2lGLFlBQVksSUFBYixFQUFtQkMsb0JBQW9CQSxrQkFBdkMsRUFBZDs7QUFFQSxrQkFBS3RKLEtBQUwsQ0FBVzZMLE9BQVg7QUFDSDs7O3VDQUVheEgsQyxFQUFFO0FBQ1osaUJBQUksS0FBS3BFLEtBQUwsQ0FBV29KLFVBQWYsRUFBMkI7QUFDdkJoRixtQkFBRVEsY0FBRjtBQUNBLHNCQUFLVCxRQUFMLENBQWMsRUFBQ2lGLFlBQVksS0FBYixFQUFkO0FBQ0g7QUFDSjs7OzhDQUVtQjtBQUNoQixpQkFBRyxLQUFLckosS0FBTCxDQUFXdUosSUFBWCxLQUFvQixVQUF2QixFQUFrQztBQUM5Qix3QkFBTztBQUNIdUMsNkJBQVEsS0FBSzdMLEtBQUwsQ0FBV21KLFVBRGhCO0FBRUg5RixnQ0FBVyxLQUFLckQsS0FBTCxDQUFXYTtBQUZuQixrQkFBUDtBQUlILGNBTEQsTUFLTztBQUNILHdCQUFPO0FBQ0hpTCw0QkFBTyxLQUFLOUwsS0FBTCxDQUFXbUosVUFEZjtBQUVIN0YsaUNBQVksS0FBS3RELEtBQUwsQ0FBV2E7QUFGcEIsa0JBQVA7QUFJSDtBQUNKOzs7NkNBRWtCO0FBQ2Ysb0JBQVEsS0FBS2QsS0FBTCxDQUFXK0osYUFBWixHQUE2QixLQUFLL0osS0FBTCxDQUFXb0ssUUFBL0M7QUFDSDs7O3NDQUVXO0FBQ1Qsb0JBQU8sS0FBS3BLLEtBQUwsQ0FBV3VKLElBQVgsS0FBb0IsVUFBM0I7QUFDRjs7OztHQTdKbUIxQyxnQkFBTUMsUzs7QUFnSzlCb0MsV0FBVWhDLFNBQVYsR0FBc0I7QUFDbEIwRSxhQUFRNUUsb0JBQVVNLElBREE7QUFFbEJxRSx1QkFBa0IzRSxvQkFBVU0sSUFGVjtBQUdsQnVFLGNBQVM3RSxvQkFBVU0sSUFIRDtBQUlsQjhDLGVBQVVwRCxvQkFBVUksTUFKRjtBQUtsQjJDLG9CQUFlL0Msb0JBQVVJLE1BTFA7QUFNbEJ0RyxlQUFVa0csb0JBQVVJLE1BTkY7QUFPbEJzRCxxQkFBZ0IxRCxvQkFBVUMsTUFQUjtBQVFsQndELHFCQUFnQnpELG9CQUFVQyxNQVJSO0FBU2xCc0MsV0FBTXZDLG9CQUFVZ0YsS0FBVixDQUFnQixDQUFDLFVBQUQsRUFBYSxZQUFiLENBQWhCLENBVFk7QUFVbEI5SixvQkFBZThFLG9CQUFVTyxHQVZQO0FBV2xCbkYsc0JBQWlCNEUsb0JBQVVLLElBWFQ7QUFZbEJ6RSxvQkFBZW9FLG9CQUFVSTtBQVpQLEVBQXRCOztBQWVBOEIsV0FBVTFCLFlBQVYsR0FBeUI7QUFDckIrQixXQUFPLFVBRGM7QUFFckJuSCxzQkFBaUI7QUFGSSxFQUF6Qjs7bUJBS2U4RyxTIiwiZmlsZSI6ImIyMjU2NmQ1YWEyM2YzMGJjOTUyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwicmVhY3RcIikpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW1wicmVhY3RcIl0sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wiU2Nyb2xsQXJlYVwiXSA9IGZhY3RvcnkocmVxdWlyZShcInJlYWN0XCIpKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJTY3JvbGxBcmVhXCJdID0gZmFjdG9yeShyb290W1wiUmVhY3RcIl0pO1xufSkodGhpcywgZnVuY3Rpb24oX19XRUJQQUNLX0VYVEVSTkFMX01PRFVMRV8yX18pIHtcbnJldHVybiBcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pXG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG5cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGV4cG9ydHM6IHt9LFxuIFx0XHRcdGlkOiBtb2R1bGVJZCxcbiBcdFx0XHRsb2FkZWQ6IGZhbHNlXG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgYjIyNTY2ZDVhYTIzZjMwYmM5NTIiLCJpbXBvcnQgU2Nyb2xsQXJlYSBmcm9tICcuL1Njcm9sbEFyZWEuanN4JztcblxuZXhwb3J0IGRlZmF1bHQgU2Nyb2xsQXJlYTtcblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvanMvU2Nyb2xsQXJlYVdpdGhvdXRDc3MuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBsaW5lSGVpZ2h0IGZyb20gJ2xpbmUtaGVpZ2h0JztcbmltcG9ydCB7IE1vdGlvbiwgc3ByaW5nIH0gZnJvbSAncmVhY3QtbW90aW9uJztcblxuaW1wb3J0IHtcbiAgZmluZERPTU5vZGUsIHdhcm5BYm91dEZ1bmN0aW9uQ2hpbGQsIHdhcm5BYm91dEVsZW1lbnRDaGlsZCwgcG9zaXRpdmVPclplcm8sIG1vZGlmeU9ialZhbHVlcyxcbn0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgU2Nyb2xsQmFyIGZyb20gJy4vU2Nyb2xsYmFyJztcblxuY29uc3QgZXZlbnRUeXBlcyA9IHtcbiAgICB3aGVlbDogJ3doZWVsJyxcbiAgICBhcGk6ICdhcGknLFxuICAgIHRvdWNoOiAndG91Y2gnLFxuICAgIHRvdWNoRW5kOiAndG91Y2hFbmQnLFxuICAgIG1vdXNlbW92ZTogJ21vdXNlbW92ZScsXG4gICAga2V5UHJlc3M6ICdrZXlwcmVzcydcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjcm9sbEFyZWEgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIHRvcFBvc2l0aW9uOiAwLFxuICAgICAgICAgICAgbGVmdFBvc2l0aW9uOiAwLFxuICAgICAgICAgICAgcmVhbEhlaWdodDogMCxcbiAgICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogMCxcbiAgICAgICAgICAgIHJlYWxXaWR0aDogMCxcbiAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAwXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zY3JvbGxBcmVhID0ge1xuICAgICAgICAgICAgcmVmcmVzaDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U2l6ZXNUb1N0YXRlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2Nyb2xsVG9wOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxUb3AoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzY3JvbGxCb3R0b206ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbEJvdHRvbSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNjcm9sbFlUbzogKHBvc2l0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxZVG8ocG9zaXRpb24pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNjcm9sbExlZnQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbExlZnQoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzY3JvbGxSaWdodDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsUmlnaHQoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzY3JvbGxYVG86IChwb3NpdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsWFRvKHBvc2l0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLmV2bnRzUHJldmlvdXNWYWx1ZXMgPSB7XG4gICAgICAgICAgICBjbGllbnRYOiAwLFxuICAgICAgICAgICAgY2xpZW50WTogMCxcbiAgICAgICAgICAgIGRlbHRhWDogMCxcbiAgICAgICAgICAgIGRlbHRhWTogMFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuYmluZGVkSGFuZGxlV2luZG93UmVzaXplID0gdGhpcy5oYW5kbGVXaW5kb3dSZXNpemUuYmluZCh0aGlzKTtcbiAgICB9XG5cbiAgICBnZXRDaGlsZENvbnRleHQoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzY3JvbGxBcmVhOiB0aGlzLnNjcm9sbEFyZWFcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuY29udGVudFdpbmRvdykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250ZW50V2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgdGhpcy5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGluZUhlaWdodFB4ID0gbGluZUhlaWdodChmaW5kRE9NTm9kZSh0aGlzLmNvbnRlbnQpKTtcbiAgICAgICAgdGhpcy5zZXRTaXplc1RvU3RhdGUoKTtcbiAgICB9XG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuY29udGVudFdpbmRvdykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250ZW50V2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwgdGhpcy5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlKCkge1xuICAgICAgICB0aGlzLnNldFNpemVzVG9TdGF0ZSgpO1xuICAgIH1cblxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHtjaGlsZHJlbiwgY2xhc3NOYW1lLCBjb250ZW50Q2xhc3NOYW1lLCBvd25lckRvY3VtZW50fSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGxldCB3aXRoTW90aW9uID0gdGhpcy5wcm9wcy5zbW9vdGhTY3JvbGxpbmcgJiZcbiAgICAgICAgICAgICh0aGlzLnN0YXRlLmV2ZW50VHlwZSA9PT0gZXZlbnRUeXBlcy53aGVlbCB8fCB0aGlzLnN0YXRlLmV2ZW50VHlwZSA9PT0gZXZlbnRUeXBlcy5hcGkgfHwgdGhpcy5zdGF0ZS5ldmVudFR5cGUgPT09IGV2ZW50VHlwZXMudG91Y2hFbmQgfHxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZXZlbnRUeXBlID09PSBldmVudFR5cGVzLmtleVByZXNzKTtcblxuICAgICAgICBsZXQgc2Nyb2xsYmFyWSA9IHRoaXMuY2FuU2Nyb2xsWSgpID8gKFxuICAgICAgICAgICAgPFNjcm9sbEJhclxuICAgICAgICAgICAgICAgIG93bmVyRG9jdW1lbnQ9e293bmVyRG9jdW1lbnR9XG4gICAgICAgICAgICAgICAgcmVhbFNpemU9e3RoaXMuc3RhdGUucmVhbEhlaWdodH1cbiAgICAgICAgICAgICAgICBjb250YWluZXJTaXplPXt0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodH1cbiAgICAgICAgICAgICAgICBwb3NpdGlvbj17dGhpcy5zdGF0ZS50b3BQb3NpdGlvbn1cbiAgICAgICAgICAgICAgICBvbk1vdmU9e3RoaXMuaGFuZGxlU2Nyb2xsYmFyTW92ZS5iaW5kKHRoaXMpfVxuICAgICAgICAgICAgICAgIG9uUG9zaXRpb25DaGFuZ2U9e3RoaXMuaGFuZGxlU2Nyb2xsYmFyWVBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyl9XG4gICAgICAgICAgICAgICAgY29udGFpbmVyU3R5bGU9e3RoaXMucHJvcHMudmVydGljYWxDb250YWluZXJTdHlsZX1cbiAgICAgICAgICAgICAgICBzY3JvbGxiYXJTdHlsZT17dGhpcy5wcm9wcy52ZXJ0aWNhbFNjcm9sbGJhclN0eWxlfVxuICAgICAgICAgICAgICAgIHNtb290aFNjcm9sbGluZz17d2l0aE1vdGlvbn1cbiAgICAgICAgICAgICAgICBtaW5TY3JvbGxTaXplPXt0aGlzLnByb3BzLm1pblNjcm9sbFNpemV9XG4gICAgICAgICAgICAgICAgb25Gb2N1cz17dGhpcy5mb2N1c0NvbnRlbnQuYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICB0eXBlPVwidmVydGljYWxcIi8+XG4gICAgICAgICkgOiBudWxsO1xuXG4gICAgICAgIGxldCBzY3JvbGxiYXJYID0gdGhpcy5jYW5TY3JvbGxYKCkgPyAoXG4gICAgICAgICAgICA8U2Nyb2xsQmFyXG4gICAgICAgICAgICAgICAgb3duZXJEb2N1bWVudD17b3duZXJEb2N1bWVudH1cbiAgICAgICAgICAgICAgICByZWFsU2l6ZT17dGhpcy5zdGF0ZS5yZWFsV2lkdGh9XG4gICAgICAgICAgICAgICAgY29udGFpbmVyU2l6ZT17dGhpcy5zdGF0ZS5jb250YWluZXJXaWR0aH1cbiAgICAgICAgICAgICAgICBwb3NpdGlvbj17dGhpcy5zdGF0ZS5sZWZ0UG9zaXRpb259XG4gICAgICAgICAgICAgICAgb25Nb3ZlPXt0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICBvblBvc2l0aW9uQ2hhbmdlPXt0aGlzLmhhbmRsZVNjcm9sbGJhclhQb3NpdGlvbkNoYW5nZS5iaW5kKHRoaXMpfVxuICAgICAgICAgICAgICAgIGNvbnRhaW5lclN0eWxlPXt0aGlzLnByb3BzLmhvcml6b250YWxDb250YWluZXJTdHlsZX1cbiAgICAgICAgICAgICAgICBzY3JvbGxiYXJTdHlsZT17dGhpcy5wcm9wcy5ob3Jpem9udGFsU2Nyb2xsYmFyU3R5bGV9XG4gICAgICAgICAgICAgICAgc21vb3RoU2Nyb2xsaW5nPXt3aXRoTW90aW9ufVxuICAgICAgICAgICAgICAgIG1pblNjcm9sbFNpemU9e3RoaXMucHJvcHMubWluU2Nyb2xsU2l6ZX1cbiAgICAgICAgICAgICAgICBvbkZvY3VzPXt0aGlzLmZvY3VzQ29udGVudC5iaW5kKHRoaXMpfVxuICAgICAgICAgICAgICAgIHR5cGU9XCJob3Jpem9udGFsXCIvPlxuICAgICAgICApIDogbnVsbDtcblxuICAgICAgICBpZiAodHlwZW9mIGNoaWxkcmVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB3YXJuQWJvdXRGdW5jdGlvbkNoaWxkKCk7XG4gICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3YXJuQWJvdXRFbGVtZW50Q2hpbGQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjbGFzc2VzID0gJ3Njcm9sbGFyZWEgJyArIChjbGFzc05hbWUgfHwgJycpO1xuICAgICAgICBsZXQgY29udGVudENsYXNzZXMgPSAnc2Nyb2xsYXJlYS1jb250ZW50ICcgKyAoY29udGVudENsYXNzTmFtZSB8fCAnJyk7XG5cbiAgICAgICAgbGV0IGNvbnRlbnRTdHlsZSA9IHtcbiAgICAgICAgICAgIG1hcmdpblRvcDogLXRoaXMuc3RhdGUudG9wUG9zaXRpb24sXG4gICAgICAgICAgICBtYXJnaW5MZWZ0OiAtdGhpcy5zdGF0ZS5sZWZ0UG9zaXRpb25cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHNwcmluZ2lmaWVkQ29udGVudFN0eWxlID0gd2l0aE1vdGlvbiA/IG1vZGlmeU9ialZhbHVlcyhjb250ZW50U3R5bGUsIHggPT4gc3ByaW5nKHgpKSA6IGNvbnRlbnRTdHlsZTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPE1vdGlvbiBzdHlsZT17c3ByaW5naWZpZWRDb250ZW50U3R5bGV9PlxuICAgICAgICAgICAgICAgIHsgc3R5bGUgPT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmPXt4ID0+IHRoaXMud3JhcHBlciA9IHh9XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT17dGhpcy5wcm9wcy5zdHlsZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uV2hlZWw9e3RoaXMuaGFuZGxlV2hlZWwuYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZj17eCA9PiB0aGlzLmNvbnRlbnQgPSB4fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPXt7IC4uLnRoaXMucHJvcHMuY29udGVudFN0eWxlLCAuLi5zdHlsZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y29udGVudENsYXNzZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFN0YXJ0PXt0aGlzLmhhbmRsZVRvdWNoU3RhcnQuYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblRvdWNoTW92ZT17dGhpcy5oYW5kbGVUb3VjaE1vdmUuYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblRvdWNoRW5kPXt0aGlzLmhhbmRsZVRvdWNoRW5kLmJpbmQodGhpcyl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25LZXlEb3duPXt0aGlzLmhhbmRsZUtleURvd24uYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJJbmRleD17dGhpcy5wcm9wcy5mb2N1c2FibGVUYWJJbmRleH1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2hpbGRyZW59XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtzY3JvbGxiYXJZfVxuICAgICAgICAgICAgICAgICAgICAgICAge3Njcm9sbGJhclh9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvTW90aW9uPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHNldFN0YXRlRnJvbUV2ZW50KG5ld1N0YXRlLCBldmVudFR5cGUpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25TY3JvbGwpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25TY3JvbGwobmV3U3RhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoey4uLm5ld1N0YXRlLCBldmVudFR5cGV9KTtcbiAgICB9XG5cbiAgICBoYW5kbGVUb3VjaFN0YXJ0KGUpIHtcbiAgICAgICAgbGV0IHt0b3VjaGVzfSA9IGU7XG4gICAgICAgIGlmICh0b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgbGV0IHtjbGllbnRYLCBjbGllbnRZfSA9IHRvdWNoZXNbMF07XG4gICAgICAgICAgICB0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMgPSB7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLFxuICAgICAgICAgICAgICAgIGNsaWVudFksXG4gICAgICAgICAgICAgICAgY2xpZW50WCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KClcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoYW5kbGVUb3VjaE1vdmUoZSkge1xuICAgICAgICBpZiAodGhpcy5jYW5TY3JvbGwoKSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB7dG91Y2hlc30gPSBlO1xuICAgICAgICBpZiAodG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIGxldCB7Y2xpZW50WCwgY2xpZW50WX0gPSB0b3VjaGVzWzBdO1xuXG4gICAgICAgICAgICBsZXQgZGVsdGFZID0gdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLmNsaWVudFkgLSBjbGllbnRZO1xuICAgICAgICAgICAgbGV0IGRlbHRhWCA9IHRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcy5jbGllbnRYIC0gY2xpZW50WDtcblxuICAgICAgICAgICAgdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzID0ge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcyxcbiAgICAgICAgICAgICAgICBkZWx0YVksXG4gICAgICAgICAgICAgICAgZGVsdGFYLFxuICAgICAgICAgICAgICAgIGNsaWVudFksXG4gICAgICAgICAgICAgICAgY2xpZW50WCxcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KClcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5jb21wb3NlTmV3U3RhdGUoLWRlbHRhWCwgLWRlbHRhWSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGFuZGxlVG91Y2hFbmQoZSkge1xuICAgICAgICBsZXQge2RlbHRhWCwgZGVsdGFZLCB0aW1lc3RhbXB9ID0gdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzO1xuICAgICAgICBpZiAodHlwZW9mIGRlbHRhWCA9PT0gJ3VuZGVmaW5lZCcpIGRlbHRhWCA9IDA7XG4gICAgICAgIGlmICh0eXBlb2YgZGVsdGFZID09PSAndW5kZWZpbmVkJykgZGVsdGFZID0gMDtcbiAgICAgICAgaWYgKERhdGUubm93KCkgLSB0aW1lc3RhbXAgPCAyMDApIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5jb21wb3NlTmV3U3RhdGUoLWRlbHRhWCAqIDEwLCAtZGVsdGFZICogMTApLCBldmVudFR5cGVzLnRvdWNoRW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcyA9IHtcbiAgICAgICAgICAgIC4uLnRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcyxcbiAgICAgICAgICAgIGRlbHRhWTogMCxcbiAgICAgICAgICAgIGRlbHRhWDogMFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGhhbmRsZVNjcm9sbGJhck1vdmUoZGVsdGFZLCBkZWx0YVgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZUZyb21FdmVudCh0aGlzLmNvbXBvc2VOZXdTdGF0ZShkZWx0YVgsIGRlbHRhWSkpO1xuICAgIH1cblxuICAgIGhhbmRsZVNjcm9sbGJhclhQb3NpdGlvbkNoYW5nZShwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnNjcm9sbFhUbyhwb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaGFuZGxlU2Nyb2xsYmFyWVBvc2l0aW9uQ2hhbmdlKHBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsWVRvKHBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBoYW5kbGVXaGVlbChlKSB7XG4gICAgICAgIGxldCBkZWx0YVkgPSBlLmRlbHRhWTtcbiAgICAgICAgbGV0IGRlbHRhWCA9IGUuZGVsdGFYO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLnN3YXBXaGVlbEF4ZXMpIHtcbiAgICAgICAgICAgIFtkZWx0YVksIGRlbHRhWF0gPSBbZGVsdGFYLCBkZWx0YVldO1xuICAgICAgICB9XG5cbiAgICAgICAgLypcbiAgICAgICAgICogV2hlZWxFdmVudC5kZWx0YU1vZGUgY2FuIGRpZmZlciBiZXR3ZWVuIGJyb3dzZXJzIGFuZCBtdXN0IGJlIG5vcm1hbGl6ZWRcbiAgICAgICAgICogZS5kZWx0YU1vZGUgPT09IDA6IFRoZSBkZWx0YSB2YWx1ZXMgYXJlIHNwZWNpZmllZCBpbiBwaXhlbHNcbiAgICAgICAgICogZS5kZWx0YU1vZGUgPT09IDE6IFRoZSBkZWx0YSB2YWx1ZXMgYXJlIHNwZWNpZmllZCBpbiBsaW5lc1xuICAgICAgICAgKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2hlZWxFdmVudC9kZWx0YU1vZGVcbiAgICAgICAgICovXG4gICAgICAgIGlmIChlLmRlbHRhTW9kZSA9PT0gMSkge1xuICAgICAgICAgICAgZGVsdGFZID0gZGVsdGFZICogdGhpcy5saW5lSGVpZ2h0UHg7XG4gICAgICAgICAgICBkZWx0YVggPSBkZWx0YVggKiB0aGlzLmxpbmVIZWlnaHRQeDtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbHRhWSA9IGRlbHRhWSAqIHRoaXMucHJvcHMuc3BlZWQ7XG4gICAgICAgIGRlbHRhWCA9IGRlbHRhWCAqIHRoaXMucHJvcHMuc3BlZWQ7XG5cbiAgICAgICAgbGV0IG5ld1N0YXRlID0gdGhpcy5jb21wb3NlTmV3U3RhdGUoLWRlbHRhWCwgLWRlbHRhWSk7XG5cbiAgICAgICAgaWYgKChuZXdTdGF0ZS50b3BQb3NpdGlvbiAmJiB0aGlzLnN0YXRlLnRvcFBvc2l0aW9uICE9PSBuZXdTdGF0ZS50b3BQb3NpdGlvbikgfHxcbiAgICAgICAgICAgIChuZXdTdGF0ZS5sZWZ0UG9zaXRpb24gJiYgdGhpcy5zdGF0ZS5sZWZ0UG9zaXRpb24gIT09IG5ld1N0YXRlLmxlZnRQb3NpdGlvbikgfHxcbiAgICAgICAgICAgIHRoaXMucHJvcHMuc3RvcFNjcm9sbFByb3BhZ2F0aW9uKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZUZyb21FdmVudChuZXdTdGF0ZSwgZXZlbnRUeXBlcy53aGVlbCk7XG4gICAgICAgIHRoaXMuZm9jdXNDb250ZW50KCk7XG4gICAgfVxuXG4gICAgaGFuZGxlS2V5RG93bihlKSB7XG4gICAgICAgIC8vIG9ubHkgaGFuZGxlIGlmIHNjcm9sbCBhcmVhIGlzIGluIGZvY3VzXG4gICAgICAgIGlmIChlLnRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICdpbnB1dCcgJiYgZS50YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAndGV4dGFyZWEnICYmICFlLnRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgICAgICAgbGV0IGRlbHRhWSA9IDA7XG4gICAgICAgICAgICBsZXQgZGVsdGFYID0gMDtcbiAgICAgICAgICAgIGxldCBsaW5lSGVpZ2h0ID0gdGhpcy5saW5lSGVpZ2h0UHggPyB0aGlzLmxpbmVIZWlnaHRQeCA6IDEwO1xuXG4gICAgICAgICAgICBzd2l0Y2ggKGUua2V5Q29kZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgMzM6IC8vIHBhZ2UgdXBcbiAgICAgICAgICAgICAgICAgICAgZGVsdGFZID0gdGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQgLSBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDM0OiAvLyBwYWdlIGRvd25cbiAgICAgICAgICAgICAgICAgICAgZGVsdGFZID0gLXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0ICsgbGluZUhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAzNzogLy8gbGVmdFxuICAgICAgICAgICAgICAgICAgICBkZWx0YVggPSBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDM4OiAvLyB1cFxuICAgICAgICAgICAgICAgICAgICBkZWx0YVkgPSBsaW5lSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDM5OiAvLyByaWdodFxuICAgICAgICAgICAgICAgICAgICBkZWx0YVggPSAtbGluZUhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA0MDogLy8gZG93blxuICAgICAgICAgICAgICAgICAgICBkZWx0YVkgPSAtbGluZUhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG9ubHkgY29tcG9zZSBuZXcgc3RhdGUgaWYga2V5IGNvZGUgbWF0Y2hlcyB0aG9zZSBhYm92ZVxuICAgICAgICAgICAgaWYgKGRlbHRhWSAhPT0gMCB8fCBkZWx0YVggIT09IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV3U3RhdGUgPSB0aGlzLmNvbXBvc2VOZXdTdGF0ZShkZWx0YVgsIGRlbHRhWSk7XG5cbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQobmV3U3RhdGUsIGV2ZW50VHlwZXMua2V5UHJlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGFuZGxlV2luZG93UmVzaXplKCkge1xuICAgICAgICBsZXQgbmV3U3RhdGUgPSB0aGlzLmNvbXB1dGVTaXplcygpO1xuICAgICAgICBuZXdTdGF0ZSA9IHRoaXMuZ2V0TW9kaWZpZWRQb3NpdGlvbnNJZk5lZWRlZChuZXdTdGF0ZSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQobmV3U3RhdGUpO1xuICAgIH1cblxuICAgIGNvbXBvc2VOZXdTdGF0ZShkZWx0YVgsIGRlbHRhWSkge1xuICAgICAgICBsZXQgbmV3U3RhdGUgPSB0aGlzLmNvbXB1dGVTaXplcygpO1xuXG4gICAgICAgIGlmICh0aGlzLmNhblNjcm9sbFkobmV3U3RhdGUpKSB7XG4gICAgICAgICAgICBuZXdTdGF0ZS50b3BQb3NpdGlvbiA9IHRoaXMuY29tcHV0ZVRvcFBvc2l0aW9uKGRlbHRhWSwgbmV3U3RhdGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1N0YXRlLnRvcFBvc2l0aW9uID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jYW5TY3JvbGxYKG5ld1N0YXRlKSkge1xuICAgICAgICAgICAgbmV3U3RhdGUubGVmdFBvc2l0aW9uID0gdGhpcy5jb21wdXRlTGVmdFBvc2l0aW9uKGRlbHRhWCwgbmV3U3RhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ld1N0YXRlO1xuICAgIH1cblxuICAgIGNvbXB1dGVUb3BQb3NpdGlvbihkZWx0YVksIHNpemVzKSB7XG4gICAgICAgIGxldCBuZXdUb3BQb3NpdGlvbiA9IHRoaXMuc3RhdGUudG9wUG9zaXRpb24gLSBkZWx0YVk7XG4gICAgICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZVRvcFBvc2l0aW9uKG5ld1RvcFBvc2l0aW9uLCBzaXplcyk7XG4gICAgfVxuXG4gICAgY29tcHV0ZUxlZnRQb3NpdGlvbihkZWx0YVgsIHNpemVzKSB7XG4gICAgICAgIGxldCBuZXdMZWZ0UG9zaXRpb24gPSB0aGlzLnN0YXRlLmxlZnRQb3NpdGlvbiAtIGRlbHRhWDtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsaXplTGVmdFBvc2l0aW9uKG5ld0xlZnRQb3NpdGlvbiwgc2l6ZXMpO1xuICAgIH1cblxuICAgIG5vcm1hbGl6ZVRvcFBvc2l0aW9uKG5ld1RvcFBvc2l0aW9uLCBzaXplcykge1xuICAgICAgICBpZiAobmV3VG9wUG9zaXRpb24gPiBzaXplcy5yZWFsSGVpZ2h0IC0gc2l6ZXMuY29udGFpbmVySGVpZ2h0KSB7XG4gICAgICAgICAgICBuZXdUb3BQb3NpdGlvbiA9IHNpemVzLnJlYWxIZWlnaHQgLSBzaXplcy5jb250YWluZXJIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5ld1RvcFBvc2l0aW9uIDwgMCkge1xuICAgICAgICAgICAgbmV3VG9wUG9zaXRpb24gPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdUb3BQb3NpdGlvbjtcbiAgICB9XG5cbiAgICBub3JtYWxpemVMZWZ0UG9zaXRpb24obmV3TGVmdFBvc2l0aW9uLCBzaXplcykge1xuICAgICAgICBpZiAobmV3TGVmdFBvc2l0aW9uID4gc2l6ZXMucmVhbFdpZHRoIC0gc2l6ZXMuY29udGFpbmVyV2lkdGgpIHtcbiAgICAgICAgICAgIG5ld0xlZnRQb3NpdGlvbiA9IHNpemVzLnJlYWxXaWR0aCAtIHNpemVzLmNvbnRhaW5lcldpZHRoO1xuICAgICAgICB9IGVsc2UgaWYgKG5ld0xlZnRQb3NpdGlvbiA8IDApIHtcbiAgICAgICAgICAgIG5ld0xlZnRQb3NpdGlvbiA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3TGVmdFBvc2l0aW9uO1xuICAgIH1cblxuICAgIGNvbXB1dGVTaXplcygpIHtcbiAgICAgICAgbGV0IHJlYWxIZWlnaHQgPSAodGhpcy5jb250ZW50KSA/IHRoaXMuY29udGVudC5vZmZzZXRIZWlnaHQgOiAwO1xuICAgICAgICBsZXQgY29udGFpbmVySGVpZ2h0ID0gKHRoaXMud3JhcHBlcikgPyB0aGlzLndyYXBwZXIub2Zmc2V0SGVpZ2h0IDogMDtcbiAgICAgICAgbGV0IHJlYWxXaWR0aCA9ICh0aGlzLmNvbnRlbnQpID8gdGhpcy5jb250ZW50Lm9mZnNldFdpZHRoIDogMDtcbiAgICAgICAgbGV0IGNvbnRhaW5lcldpZHRoID0gKHRoaXMuY29udGVudCkgPyB0aGlzLndyYXBwZXIub2Zmc2V0V2lkdGggOiAwO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZWFsSGVpZ2h0OiByZWFsSGVpZ2h0LFxuICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0OiBjb250YWluZXJIZWlnaHQsXG4gICAgICAgICAgICByZWFsV2lkdGg6IHJlYWxXaWR0aCxcbiAgICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiBjb250YWluZXJXaWR0aFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHNldFNpemVzVG9TdGF0ZSgpIHtcbiAgICAgICAgbGV0IHNpemVzID0gdGhpcy5jb21wdXRlU2l6ZXMoKTtcbiAgICAgICAgaWYgKHNpemVzLnJlYWxIZWlnaHQgIT09IHRoaXMuc3RhdGUucmVhbEhlaWdodCB8fCBzaXplcy5yZWFsV2lkdGggIT09IHRoaXMuc3RhdGUucmVhbFdpZHRoKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHRoaXMuZ2V0TW9kaWZpZWRQb3NpdGlvbnNJZk5lZWRlZChzaXplcykpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2Nyb2xsVG9wKCkge1xuICAgICAgICB0aGlzLnNjcm9sbFlUbygwKTtcbiAgICB9XG5cbiAgICBzY3JvbGxCb3R0b20oKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsWVRvKCh0aGlzLnN0YXRlLnJlYWxIZWlnaHQgLSB0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCkpO1xuICAgIH1cblxuICAgIHNjcm9sbExlZnQoKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsWFRvKDApO1xuICAgIH1cblxuICAgIHNjcm9sbFJpZ2h0KCkge1xuICAgICAgICB0aGlzLnNjcm9sbFhUbygodGhpcy5zdGF0ZS5yZWFsV2lkdGggLSB0aGlzLnN0YXRlLmNvbnRhaW5lcldpZHRoKSk7XG4gICAgfVxuXG4gICAgc2Nyb2xsWVRvKHRvcFBvc2l0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLmNhblNjcm9sbFkoKSkge1xuICAgICAgICAgICAgbGV0IHBvc2l0aW9uID0gdGhpcy5ub3JtYWxpemVUb3BQb3NpdGlvbih0b3BQb3NpdGlvbiwgdGhpcy5jb21wdXRlU2l6ZXMoKSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHt0b3BQb3NpdGlvbjogcG9zaXRpb259LCBldmVudFR5cGVzLmFwaSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzY3JvbGxYVG8obGVmdFBvc2l0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLmNhblNjcm9sbFgoKSkge1xuICAgICAgICAgICAgbGV0IHBvc2l0aW9uID0gdGhpcy5ub3JtYWxpemVMZWZ0UG9zaXRpb24obGVmdFBvc2l0aW9uLCB0aGlzLmNvbXB1dGVTaXplcygpKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQoe2xlZnRQb3NpdGlvbjogcG9zaXRpb259LCBldmVudFR5cGVzLmFwaSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYW5TY3JvbGxZKHN0YXRlID0gdGhpcy5zdGF0ZSkge1xuICAgICAgICBsZXQgc2Nyb2xsYWJsZVkgPSBzdGF0ZS5yZWFsSGVpZ2h0ID4gc3RhdGUuY29udGFpbmVySGVpZ2h0O1xuICAgICAgICByZXR1cm4gc2Nyb2xsYWJsZVkgJiYgdGhpcy5wcm9wcy52ZXJ0aWNhbDtcbiAgICB9XG5cbiAgICBjYW5TY3JvbGxYKHN0YXRlID0gdGhpcy5zdGF0ZSkge1xuICAgICAgICBsZXQgc2Nyb2xsYWJsZVggPSBzdGF0ZS5yZWFsV2lkdGggPiBzdGF0ZS5jb250YWluZXJXaWR0aDtcbiAgICAgICAgcmV0dXJuIHNjcm9sbGFibGVYICYmIHRoaXMucHJvcHMuaG9yaXpvbnRhbDtcbiAgICB9XG5cbiAgICBjYW5TY3JvbGwoc3RhdGUgPSB0aGlzLnN0YXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhblNjcm9sbFkoc3RhdGUpIHx8IHRoaXMuY2FuU2Nyb2xsWChzdGF0ZSk7XG4gICAgfVxuXG4gICAgZ2V0TW9kaWZpZWRQb3NpdGlvbnNJZk5lZWRlZChuZXdTdGF0ZSkge1xuICAgICAgICBsZXQgYm90dG9tUG9zaXRpb24gPSBuZXdTdGF0ZS5yZWFsSGVpZ2h0IC0gbmV3U3RhdGUuY29udGFpbmVySGVpZ2h0O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS50b3BQb3NpdGlvbiA+PSBib3R0b21Qb3NpdGlvbikge1xuICAgICAgICAgICAgbmV3U3RhdGUudG9wUG9zaXRpb24gPSB0aGlzLmNhblNjcm9sbFkobmV3U3RhdGUpID8gcG9zaXRpdmVPclplcm8oYm90dG9tUG9zaXRpb24pIDogMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByaWdodFBvc2l0aW9uID0gbmV3U3RhdGUucmVhbFdpZHRoIC0gbmV3U3RhdGUuY29udGFpbmVyV2lkdGg7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmxlZnRQb3NpdGlvbiA+PSByaWdodFBvc2l0aW9uKSB7XG4gICAgICAgICAgICBuZXdTdGF0ZS5sZWZ0UG9zaXRpb24gPSB0aGlzLmNhblNjcm9sbFgobmV3U3RhdGUpID8gcG9zaXRpdmVPclplcm8ocmlnaHRQb3NpdGlvbikgOiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ld1N0YXRlO1xuICAgIH1cblxuICAgIGZvY3VzQ29udGVudCgpIHtcbiAgICAgICAgaWYodGhpcy5jb250ZW50KSB7XG4gICAgICAgICAgICBmaW5kRE9NTm9kZSh0aGlzLmNvbnRlbnQpLmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cblNjcm9sbEFyZWEuY2hpbGRDb250ZXh0VHlwZXMgPSB7XG4gICAgc2Nyb2xsQXJlYTogUHJvcFR5cGVzLm9iamVjdCxcbn07XG5cblNjcm9sbEFyZWEucHJvcFR5cGVzID0ge1xuICAgIGNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZyxcbiAgICBzdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICBzcGVlZDogUHJvcFR5cGVzLm51bWJlcixcbiAgICBjb250ZW50Q2xhc3NOYW1lOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGNvbnRlbnRTdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICB2ZXJ0aWNhbDogUHJvcFR5cGVzLmJvb2wsXG4gICAgdmVydGljYWxDb250YWluZXJTdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICB2ZXJ0aWNhbFNjcm9sbGJhclN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIGhvcml6b250YWw6IFByb3BUeXBlcy5ib29sLFxuICAgIGhvcml6b250YWxDb250YWluZXJTdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcbiAgICBob3Jpem9udGFsU2Nyb2xsYmFyU3R5bGU6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgb25TY3JvbGw6IFByb3BUeXBlcy5mdW5jLFxuICAgIGNvbnRlbnRXaW5kb3c6IFByb3BUeXBlcy5hbnksXG4gICAgb3duZXJEb2N1bWVudDogUHJvcFR5cGVzLmFueSxcbiAgICBzbW9vdGhTY3JvbGxpbmc6IFByb3BUeXBlcy5ib29sLFxuICAgIG1pblNjcm9sbFNpemU6IFByb3BUeXBlcy5udW1iZXIsXG4gICAgc3dhcFdoZWVsQXhlczogUHJvcFR5cGVzLmJvb2wsXG4gICAgc3RvcFNjcm9sbFByb3BhZ2F0aW9uOiBQcm9wVHlwZXMuYm9vbCxcbiAgICBmb2N1c2FibGVUYWJJbmRleDogUHJvcFR5cGVzLm51bWJlcixcbn07XG5cblNjcm9sbEFyZWEuZGVmYXVsdFByb3BzID0ge1xuICAgIHNwZWVkOiAxLFxuICAgIHZlcnRpY2FsOiB0cnVlLFxuICAgIGhvcml6b250YWw6IHRydWUsXG4gICAgc21vb3RoU2Nyb2xsaW5nOiBmYWxzZSxcbiAgICBzd2FwV2hlZWxBeGVzOiBmYWxzZSxcbiAgICBjb250ZW50V2luZG93OiAodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIikgPyB3aW5kb3cgOiB1bmRlZmluZWQsXG4gICAgb3duZXJEb2N1bWVudDogKHR5cGVvZiBkb2N1bWVudCA9PT0gXCJvYmplY3RcIikgPyBkb2N1bWVudCA6IHVuZGVmaW5lZCxcbiAgICBmb2N1c2FibGVUYWJJbmRleDogMSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvanMvU2Nyb2xsQXJlYS5qc3giLCJtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfMl9fO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIHtcInJvb3RcIjpcIlJlYWN0XCIsXCJjb21tb25qczJcIjpcInJlYWN0XCIsXCJjb21tb25qc1wiOlwicmVhY3RcIixcImFtZFwiOlwicmVhY3RcIn1cbi8vIG1vZHVsZSBpZCA9IDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB2YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiZcbiAgICBTeW1ib2wuZm9yICYmXG4gICAgU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpKSB8fFxuICAgIDB4ZWFjNztcblxuICB2YXIgaXNWYWxpZEVsZW1lbnQgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcbiAgICAgIG9iamVjdCAhPT0gbnVsbCAmJlxuICAgICAgb2JqZWN0LiQkdHlwZW9mID09PSBSRUFDVF9FTEVNRU5UX1RZUEU7XG4gIH07XG5cbiAgLy8gQnkgZXhwbGljaXRseSB1c2luZyBgcHJvcC10eXBlc2AgeW91IGFyZSBvcHRpbmcgaW50byBuZXcgZGV2ZWxvcG1lbnQgYmVoYXZpb3IuXG4gIC8vIGh0dHA6Ly9mYi5tZS9wcm9wLXR5cGVzLWluLXByb2RcbiAgdmFyIHRocm93T25EaXJlY3RBY2Nlc3MgPSB0cnVlO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZmFjdG9yeVdpdGhUeXBlQ2hlY2tlcnMnKShpc1ZhbGlkRWxlbWVudCwgdGhyb3dPbkRpcmVjdEFjY2Vzcyk7XG59IGVsc2Uge1xuICAvLyBCeSBleHBsaWNpdGx5IHVzaW5nIGBwcm9wLXR5cGVzYCB5b3UgYXJlIG9wdGluZyBpbnRvIG5ldyBwcm9kdWN0aW9uIGJlaGF2aW9yLlxuICAvLyBodHRwOi8vZmIubWUvcHJvcC10eXBlcy1pbi1wcm9kXG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9mYWN0b3J5V2l0aFRocm93aW5nU2hpbXMnKSgpO1xufVxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb3AtdHlwZXMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wcm9jZXNzL2Jyb3dzZXIuanNcbi8vIG1vZHVsZSBpZCA9IDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBhc3NpZ24gPSByZXF1aXJlKCdvYmplY3QtYXNzaWduJyk7XG5cbnZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9IHJlcXVpcmUoJy4vbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0Jyk7XG52YXIgY2hlY2tQcm9wVHlwZXMgPSByZXF1aXJlKCcuL2NoZWNrUHJvcFR5cGVzJyk7XG5cbnZhciBwcmludFdhcm5pbmcgPSBmdW5jdGlvbigpIHt9O1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBwcmludFdhcm5pbmcgPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIG1lc3NhZ2UgPSAnV2FybmluZzogJyArIHRleHQ7XG4gICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIC8vIC0tLSBXZWxjb21lIHRvIGRlYnVnZ2luZyBSZWFjdCAtLS1cbiAgICAgIC8vIFRoaXMgZXJyb3Igd2FzIHRocm93biBhcyBhIGNvbnZlbmllbmNlIHNvIHRoYXQgeW91IGNhbiB1c2UgdGhpcyBzdGFja1xuICAgICAgLy8gdG8gZmluZCB0aGUgY2FsbHNpdGUgdGhhdCBjYXVzZWQgdGhpcyB3YXJuaW5nIHRvIGZpcmUuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoeCkge31cbiAgfTtcbn1cblxuZnVuY3Rpb24gZW1wdHlGdW5jdGlvblRoYXRSZXR1cm5zTnVsbCgpIHtcbiAgcmV0dXJuIG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXNWYWxpZEVsZW1lbnQsIHRocm93T25EaXJlY3RBY2Nlc3MpIHtcbiAgLyogZ2xvYmFsIFN5bWJvbCAqL1xuICB2YXIgSVRFUkFUT1JfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuaXRlcmF0b3I7XG4gIHZhciBGQVVYX0lURVJBVE9SX1NZTUJPTCA9ICdAQGl0ZXJhdG9yJzsgLy8gQmVmb3JlIFN5bWJvbCBzcGVjLlxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBpdGVyYXRvciBtZXRob2QgZnVuY3Rpb24gY29udGFpbmVkIG9uIHRoZSBpdGVyYWJsZSBvYmplY3QuXG4gICAqXG4gICAqIEJlIHN1cmUgdG8gaW52b2tlIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSBpdGVyYWJsZSBhcyBjb250ZXh0OlxuICAgKlxuICAgKiAgICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKG15SXRlcmFibGUpO1xuICAgKiAgICAgaWYgKGl0ZXJhdG9yRm4pIHtcbiAgICogICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKG15SXRlcmFibGUpO1xuICAgKiAgICAgICAuLi5cbiAgICogICAgIH1cbiAgICpcbiAgICogQHBhcmFtIHs/b2JqZWN0fSBtYXliZUl0ZXJhYmxlXG4gICAqIEByZXR1cm4gez9mdW5jdGlvbn1cbiAgICovXG4gIGZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4obWF5YmVJdGVyYWJsZSkge1xuICAgIHZhciBpdGVyYXRvckZuID0gbWF5YmVJdGVyYWJsZSAmJiAoSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXSk7XG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gaXRlcmF0b3JGbjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29sbGVjdGlvbiBvZiBtZXRob2RzIHRoYXQgYWxsb3cgZGVjbGFyYXRpb24gYW5kIHZhbGlkYXRpb24gb2YgcHJvcHMgdGhhdCBhcmVcbiAgICogc3VwcGxpZWQgdG8gUmVhY3QgY29tcG9uZW50cy4gRXhhbXBsZSB1c2FnZTpcbiAgICpcbiAgICogICB2YXIgUHJvcHMgPSByZXF1aXJlKCdSZWFjdFByb3BUeXBlcycpO1xuICAgKiAgIHZhciBNeUFydGljbGUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAqICAgICBwcm9wVHlwZXM6IHtcbiAgICogICAgICAgLy8gQW4gb3B0aW9uYWwgc3RyaW5nIHByb3AgbmFtZWQgXCJkZXNjcmlwdGlvblwiLlxuICAgKiAgICAgICBkZXNjcmlwdGlvbjogUHJvcHMuc3RyaW5nLFxuICAgKlxuICAgKiAgICAgICAvLyBBIHJlcXVpcmVkIGVudW0gcHJvcCBuYW1lZCBcImNhdGVnb3J5XCIuXG4gICAqICAgICAgIGNhdGVnb3J5OiBQcm9wcy5vbmVPZihbJ05ld3MnLCdQaG90b3MnXSkuaXNSZXF1aXJlZCxcbiAgICpcbiAgICogICAgICAgLy8gQSBwcm9wIG5hbWVkIFwiZGlhbG9nXCIgdGhhdCByZXF1aXJlcyBhbiBpbnN0YW5jZSBvZiBEaWFsb2cuXG4gICAqICAgICAgIGRpYWxvZzogUHJvcHMuaW5zdGFuY2VPZihEaWFsb2cpLmlzUmVxdWlyZWRcbiAgICogICAgIH0sXG4gICAqICAgICByZW5kZXI6IGZ1bmN0aW9uKCkgeyAuLi4gfVxuICAgKiAgIH0pO1xuICAgKlxuICAgKiBBIG1vcmUgZm9ybWFsIHNwZWNpZmljYXRpb24gb2YgaG93IHRoZXNlIG1ldGhvZHMgYXJlIHVzZWQ6XG4gICAqXG4gICAqICAgdHlwZSA6PSBhcnJheXxib29sfGZ1bmN8b2JqZWN0fG51bWJlcnxzdHJpbmd8b25lT2YoWy4uLl0pfGluc3RhbmNlT2YoLi4uKVxuICAgKiAgIGRlY2wgOj0gUmVhY3RQcm9wVHlwZXMue3R5cGV9KC5pc1JlcXVpcmVkKT9cbiAgICpcbiAgICogRWFjaCBhbmQgZXZlcnkgZGVjbGFyYXRpb24gcHJvZHVjZXMgYSBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lIHNpZ25hdHVyZS4gVGhpc1xuICAgKiBhbGxvd3MgdGhlIGNyZWF0aW9uIG9mIGN1c3RvbSB2YWxpZGF0aW9uIGZ1bmN0aW9ucy4gRm9yIGV4YW1wbGU6XG4gICAqXG4gICAqICB2YXIgTXlMaW5rID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgKiAgICBwcm9wVHlwZXM6IHtcbiAgICogICAgICAvLyBBbiBvcHRpb25hbCBzdHJpbmcgb3IgVVJJIHByb3AgbmFtZWQgXCJocmVmXCIuXG4gICAqICAgICAgaHJlZjogZnVuY3Rpb24ocHJvcHMsIHByb3BOYW1lLCBjb21wb25lbnROYW1lKSB7XG4gICAqICAgICAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgKiAgICAgICAgaWYgKHByb3BWYWx1ZSAhPSBudWxsICYmIHR5cGVvZiBwcm9wVmFsdWUgIT09ICdzdHJpbmcnICYmXG4gICAqICAgICAgICAgICAgIShwcm9wVmFsdWUgaW5zdGFuY2VvZiBVUkkpKSB7XG4gICAqICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoXG4gICAqICAgICAgICAgICAgJ0V4cGVjdGVkIGEgc3RyaW5nIG9yIGFuIFVSSSBmb3IgJyArIHByb3BOYW1lICsgJyBpbiAnICtcbiAgICogICAgICAgICAgICBjb21wb25lbnROYW1lXG4gICAqICAgICAgICAgICk7XG4gICAqICAgICAgICB9XG4gICAqICAgICAgfVxuICAgKiAgICB9LFxuICAgKiAgICByZW5kZXI6IGZ1bmN0aW9uKCkgey4uLn1cbiAgICogIH0pO1xuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG5cbiAgdmFyIEFOT05ZTU9VUyA9ICc8PGFub255bW91cz4+JztcblxuICAvLyBJbXBvcnRhbnQhXG4gIC8vIEtlZXAgdGhpcyBsaXN0IGluIHN5bmMgd2l0aCBwcm9kdWN0aW9uIHZlcnNpb24gaW4gYC4vZmFjdG9yeVdpdGhUaHJvd2luZ1NoaW1zLmpzYC5cbiAgdmFyIFJlYWN0UHJvcFR5cGVzID0ge1xuICAgIGFycmF5OiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignYXJyYXknKSxcbiAgICBib29sOiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcignYm9vbGVhbicpLFxuICAgIGZ1bmM6IGNyZWF0ZVByaW1pdGl2ZVR5cGVDaGVja2VyKCdmdW5jdGlvbicpLFxuICAgIG51bWJlcjogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ251bWJlcicpLFxuICAgIG9iamVjdDogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ29iamVjdCcpLFxuICAgIHN0cmluZzogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ3N0cmluZycpLFxuICAgIHN5bWJvbDogY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXIoJ3N5bWJvbCcpLFxuXG4gICAgYW55OiBjcmVhdGVBbnlUeXBlQ2hlY2tlcigpLFxuICAgIGFycmF5T2Y6IGNyZWF0ZUFycmF5T2ZUeXBlQ2hlY2tlcixcbiAgICBlbGVtZW50OiBjcmVhdGVFbGVtZW50VHlwZUNoZWNrZXIoKSxcbiAgICBpbnN0YW5jZU9mOiBjcmVhdGVJbnN0YW5jZVR5cGVDaGVja2VyLFxuICAgIG5vZGU6IGNyZWF0ZU5vZGVDaGVja2VyKCksXG4gICAgb2JqZWN0T2Y6IGNyZWF0ZU9iamVjdE9mVHlwZUNoZWNrZXIsXG4gICAgb25lT2Y6IGNyZWF0ZUVudW1UeXBlQ2hlY2tlcixcbiAgICBvbmVPZlR5cGU6IGNyZWF0ZVVuaW9uVHlwZUNoZWNrZXIsXG4gICAgc2hhcGU6IGNyZWF0ZVNoYXBlVHlwZUNoZWNrZXIsXG4gICAgZXhhY3Q6IGNyZWF0ZVN0cmljdFNoYXBlVHlwZUNoZWNrZXIsXG4gIH07XG5cbiAgLyoqXG4gICAqIGlubGluZWQgT2JqZWN0LmlzIHBvbHlmaWxsIHRvIGF2b2lkIHJlcXVpcmluZyBjb25zdW1lcnMgc2hpcCB0aGVpciBvd25cbiAgICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzXG4gICAqL1xuICAvKmVzbGludC1kaXNhYmxlIG5vLXNlbGYtY29tcGFyZSovXG4gIGZ1bmN0aW9uIGlzKHgsIHkpIHtcbiAgICAvLyBTYW1lVmFsdWUgYWxnb3JpdGhtXG4gICAgaWYgKHggPT09IHkpIHtcbiAgICAgIC8vIFN0ZXBzIDEtNSwgNy0xMFxuICAgICAgLy8gU3RlcHMgNi5iLTYuZTogKzAgIT0gLTBcbiAgICAgIHJldHVybiB4ICE9PSAwIHx8IDEgLyB4ID09PSAxIC8geTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU3RlcCA2LmE6IE5hTiA9PSBOYU5cbiAgICAgIHJldHVybiB4ICE9PSB4ICYmIHkgIT09IHk7XG4gICAgfVxuICB9XG4gIC8qZXNsaW50LWVuYWJsZSBuby1zZWxmLWNvbXBhcmUqL1xuXG4gIC8qKlxuICAgKiBXZSB1c2UgYW4gRXJyb3ItbGlrZSBvYmplY3QgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgYXMgcGVvcGxlIG1heSBjYWxsXG4gICAqIFByb3BUeXBlcyBkaXJlY3RseSBhbmQgaW5zcGVjdCB0aGVpciBvdXRwdXQuIEhvd2V2ZXIsIHdlIGRvbid0IHVzZSByZWFsXG4gICAqIEVycm9ycyBhbnltb3JlLiBXZSBkb24ndCBpbnNwZWN0IHRoZWlyIHN0YWNrIGFueXdheSwgYW5kIGNyZWF0aW5nIHRoZW1cbiAgICogaXMgcHJvaGliaXRpdmVseSBleHBlbnNpdmUgaWYgdGhleSBhcmUgY3JlYXRlZCB0b28gb2Z0ZW4sIHN1Y2ggYXMgd2hhdFxuICAgKiBoYXBwZW5zIGluIG9uZU9mVHlwZSgpIGZvciBhbnkgdHlwZSBiZWZvcmUgdGhlIG9uZSB0aGF0IG1hdGNoZWQuXG4gICAqL1xuICBmdW5jdGlvbiBQcm9wVHlwZUVycm9yKG1lc3NhZ2UpIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIHRoaXMuc3RhY2sgPSAnJztcbiAgfVxuICAvLyBNYWtlIGBpbnN0YW5jZW9mIEVycm9yYCBzdGlsbCB3b3JrIGZvciByZXR1cm5lZCBlcnJvcnMuXG4gIFByb3BUeXBlRXJyb3IucHJvdG90eXBlID0gRXJyb3IucHJvdG90eXBlO1xuXG4gIGZ1bmN0aW9uIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIHZhciBtYW51YWxQcm9wVHlwZUNhbGxDYWNoZSA9IHt9O1xuICAgICAgdmFyIG1hbnVhbFByb3BUeXBlV2FybmluZ0NvdW50ID0gMDtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2hlY2tUeXBlKGlzUmVxdWlyZWQsIHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSwgc2VjcmV0KSB7XG4gICAgICBjb21wb25lbnROYW1lID0gY29tcG9uZW50TmFtZSB8fCBBTk9OWU1PVVM7XG4gICAgICBwcm9wRnVsbE5hbWUgPSBwcm9wRnVsbE5hbWUgfHwgcHJvcE5hbWU7XG5cbiAgICAgIGlmIChzZWNyZXQgIT09IFJlYWN0UHJvcFR5cGVzU2VjcmV0KSB7XG4gICAgICAgIGlmICh0aHJvd09uRGlyZWN0QWNjZXNzKSB7XG4gICAgICAgICAgLy8gTmV3IGJlaGF2aW9yIG9ubHkgZm9yIHVzZXJzIG9mIGBwcm9wLXR5cGVzYCBwYWNrYWdlXG4gICAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdDYWxsaW5nIFByb3BUeXBlcyB2YWxpZGF0b3JzIGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLiAnICtcbiAgICAgICAgICAgICdVc2UgYFByb3BUeXBlcy5jaGVja1Byb3BUeXBlcygpYCB0byBjYWxsIHRoZW0uICcgK1xuICAgICAgICAgICAgJ1JlYWQgbW9yZSBhdCBodHRwOi8vZmIubWUvdXNlLWNoZWNrLXByb3AtdHlwZXMnXG4gICAgICAgICAgKTtcbiAgICAgICAgICBlcnIubmFtZSA9ICdJbnZhcmlhbnQgVmlvbGF0aW9uJztcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAvLyBPbGQgYmVoYXZpb3IgZm9yIHBlb3BsZSB1c2luZyBSZWFjdC5Qcm9wVHlwZXNcbiAgICAgICAgICB2YXIgY2FjaGVLZXkgPSBjb21wb25lbnROYW1lICsgJzonICsgcHJvcE5hbWU7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIW1hbnVhbFByb3BUeXBlQ2FsbENhY2hlW2NhY2hlS2V5XSAmJlxuICAgICAgICAgICAgLy8gQXZvaWQgc3BhbW1pbmcgdGhlIGNvbnNvbGUgYmVjYXVzZSB0aGV5IGFyZSBvZnRlbiBub3QgYWN0aW9uYWJsZSBleGNlcHQgZm9yIGxpYiBhdXRob3JzXG4gICAgICAgICAgICBtYW51YWxQcm9wVHlwZVdhcm5pbmdDb3VudCA8IDNcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHByaW50V2FybmluZyhcbiAgICAgICAgICAgICAgJ1lvdSBhcmUgbWFudWFsbHkgY2FsbGluZyBhIFJlYWN0LlByb3BUeXBlcyB2YWxpZGF0aW9uICcgK1xuICAgICAgICAgICAgICAnZnVuY3Rpb24gZm9yIHRoZSBgJyArIHByb3BGdWxsTmFtZSArICdgIHByb3Agb24gYCcgKyBjb21wb25lbnROYW1lICArICdgLiBUaGlzIGlzIGRlcHJlY2F0ZWQgJyArXG4gICAgICAgICAgICAgICdhbmQgd2lsbCB0aHJvdyBpbiB0aGUgc3RhbmRhbG9uZSBgcHJvcC10eXBlc2AgcGFja2FnZS4gJyArXG4gICAgICAgICAgICAgICdZb3UgbWF5IGJlIHNlZWluZyB0aGlzIHdhcm5pbmcgZHVlIHRvIGEgdGhpcmQtcGFydHkgUHJvcFR5cGVzICcgK1xuICAgICAgICAgICAgICAnbGlicmFyeS4gU2VlIGh0dHBzOi8vZmIubWUvcmVhY3Qtd2FybmluZy1kb250LWNhbGwtcHJvcHR5cGVzICcgKyAnZm9yIGRldGFpbHMuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG1hbnVhbFByb3BUeXBlQ2FsbENhY2hlW2NhY2hlS2V5XSA9IHRydWU7XG4gICAgICAgICAgICBtYW51YWxQcm9wVHlwZVdhcm5pbmdDb3VudCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSA9PSBudWxsKSB7XG4gICAgICAgIGlmIChpc1JlcXVpcmVkKSB7XG4gICAgICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdUaGUgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIGlzIG1hcmtlZCBhcyByZXF1aXJlZCAnICsgKCdpbiBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgYnV0IGl0cyB2YWx1ZSBpcyBgbnVsbGAuJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ1RoZSAnICsgbG9jYXRpb24gKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2AgaXMgbWFya2VkIGFzIHJlcXVpcmVkIGluICcgKyAoJ2AnICsgY29tcG9uZW50TmFtZSArICdgLCBidXQgaXRzIHZhbHVlIGlzIGB1bmRlZmluZWRgLicpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjaGFpbmVkQ2hlY2tUeXBlID0gY2hlY2tUeXBlLmJpbmQobnVsbCwgZmFsc2UpO1xuICAgIGNoYWluZWRDaGVja1R5cGUuaXNSZXF1aXJlZCA9IGNoZWNrVHlwZS5iaW5kKG51bGwsIHRydWUpO1xuXG4gICAgcmV0dXJuIGNoYWluZWRDaGVja1R5cGU7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVQcmltaXRpdmVUeXBlQ2hlY2tlcihleHBlY3RlZFR5cGUpIHtcbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUsIHNlY3JldCkge1xuICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAgICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgICBpZiAocHJvcFR5cGUgIT09IGV4cGVjdGVkVHlwZSkge1xuICAgICAgICAvLyBgcHJvcFZhbHVlYCBiZWluZyBpbnN0YW5jZSBvZiwgc2F5LCBkYXRlL3JlZ2V4cCwgcGFzcyB0aGUgJ29iamVjdCdcbiAgICAgICAgLy8gY2hlY2ssIGJ1dCB3ZSBjYW4gb2ZmZXIgYSBtb3JlIHByZWNpc2UgZXJyb3IgbWVzc2FnZSBoZXJlIHJhdGhlciB0aGFuXG4gICAgICAgIC8vICdvZiB0eXBlIGBvYmplY3RgJy5cbiAgICAgICAgdmFyIHByZWNpc2VUeXBlID0gZ2V0UHJlY2lzZVR5cGUocHJvcFZhbHVlKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgJyArICgnYCcgKyBwcmVjaXNlVHlwZSArICdgIHN1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCAnKSArICgnYCcgKyBleHBlY3RlZFR5cGUgKyAnYC4nKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUFueVR5cGVDaGVja2VyKCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcihlbXB0eUZ1bmN0aW9uVGhhdFJldHVybnNOdWxsKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUFycmF5T2ZUeXBlQ2hlY2tlcih0eXBlQ2hlY2tlcikge1xuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgaWYgKHR5cGVvZiB0eXBlQ2hlY2tlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ1Byb3BlcnR5IGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgY29tcG9uZW50IGAnICsgY29tcG9uZW50TmFtZSArICdgIGhhcyBpbnZhbGlkIFByb3BUeXBlIG5vdGF0aW9uIGluc2lkZSBhcnJheU9mLicpO1xuICAgICAgfVxuICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShwcm9wVmFsdWUpKSB7XG4gICAgICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgICAgIHJldHVybiBuZXcgUHJvcFR5cGVFcnJvcignSW52YWxpZCAnICsgbG9jYXRpb24gKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgdHlwZSAnICsgKCdgJyArIHByb3BUeXBlICsgJ2Agc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGV4cGVjdGVkIGFuIGFycmF5LicpKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcFZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBlcnJvciA9IHR5cGVDaGVja2VyKHByb3BWYWx1ZSwgaSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSArICdbJyArIGkgKyAnXScsIFJlYWN0UHJvcFR5cGVzU2VjcmV0KTtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlQ2hhaW5hYmxlVHlwZUNoZWNrZXIodmFsaWRhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlRWxlbWVudFR5cGVDaGVja2VyKCkge1xuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAgICAgIGlmICghaXNWYWxpZEVsZW1lbnQocHJvcFZhbHVlKSkge1xuICAgICAgICB2YXIgcHJvcFR5cGUgPSBnZXRQcm9wVHlwZShwcm9wVmFsdWUpO1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgJyArICgnYCcgKyBwcm9wVHlwZSArICdgIHN1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBhIHNpbmdsZSBSZWFjdEVsZW1lbnQuJykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVJbnN0YW5jZVR5cGVDaGVja2VyKGV4cGVjdGVkQ2xhc3MpIHtcbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICAgIGlmICghKHByb3BzW3Byb3BOYW1lXSBpbnN0YW5jZW9mIGV4cGVjdGVkQ2xhc3MpKSB7XG4gICAgICAgIHZhciBleHBlY3RlZENsYXNzTmFtZSA9IGV4cGVjdGVkQ2xhc3MubmFtZSB8fCBBTk9OWU1PVVM7XG4gICAgICAgIHZhciBhY3R1YWxDbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocHJvcHNbcHJvcE5hbWVdKTtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlICcgKyAoJ2AnICsgYWN0dWFsQ2xhc3NOYW1lICsgJ2Agc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGV4cGVjdGVkICcpICsgKCdpbnN0YW5jZSBvZiBgJyArIGV4cGVjdGVkQ2xhc3NOYW1lICsgJ2AuJykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVFbnVtVHlwZUNoZWNrZXIoZXhwZWN0ZWRWYWx1ZXMpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZXhwZWN0ZWRWYWx1ZXMpKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gcHJpbnRXYXJuaW5nKCdJbnZhbGlkIGFyZ3VtZW50IHN1cHBsaWVkIHRvIG9uZU9mLCBleHBlY3RlZCBhbiBpbnN0YW5jZSBvZiBhcnJheS4nKSA6IHZvaWQgMDtcbiAgICAgIHJldHVybiBlbXB0eUZ1bmN0aW9uVGhhdFJldHVybnNOdWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZXhwZWN0ZWRWYWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGlzKHByb3BWYWx1ZSwgZXhwZWN0ZWRWYWx1ZXNbaV0pKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHZhbHVlc1N0cmluZyA9IEpTT04uc3RyaW5naWZ5KGV4cGVjdGVkVmFsdWVzKTtcbiAgICAgIHJldHVybiBuZXcgUHJvcFR5cGVFcnJvcignSW52YWxpZCAnICsgbG9jYXRpb24gKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgdmFsdWUgYCcgKyBwcm9wVmFsdWUgKyAnYCAnICsgKCdzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgb25lIG9mICcgKyB2YWx1ZXNTdHJpbmcgKyAnLicpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZU9iamVjdE9mVHlwZUNoZWNrZXIodHlwZUNoZWNrZXIpIHtcbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICAgIGlmICh0eXBlb2YgdHlwZUNoZWNrZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdQcm9wZXJ0eSBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIGNvbXBvbmVudCBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCBoYXMgaW52YWxpZCBQcm9wVHlwZSBub3RhdGlvbiBpbnNpZGUgb2JqZWN0T2YuJyk7XG4gICAgICB9XG4gICAgICB2YXIgcHJvcFZhbHVlID0gcHJvcHNbcHJvcE5hbWVdO1xuICAgICAgdmFyIHByb3BUeXBlID0gZ2V0UHJvcFR5cGUocHJvcFZhbHVlKTtcbiAgICAgIGlmIChwcm9wVHlwZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9wVHlwZUVycm9yKCdJbnZhbGlkICcgKyBsb2NhdGlvbiArICcgYCcgKyBwcm9wRnVsbE5hbWUgKyAnYCBvZiB0eXBlICcgKyAoJ2AnICsgcHJvcFR5cGUgKyAnYCBzdXBwbGllZCB0byBgJyArIGNvbXBvbmVudE5hbWUgKyAnYCwgZXhwZWN0ZWQgYW4gb2JqZWN0LicpKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wVmFsdWUpIHtcbiAgICAgICAgaWYgKHByb3BWYWx1ZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgdmFyIGVycm9yID0gdHlwZUNoZWNrZXIocHJvcFZhbHVlLCBrZXksIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUgKyAnLicgKyBrZXksIFJlYWN0UHJvcFR5cGVzU2VjcmV0KTtcbiAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVVbmlvblR5cGVDaGVja2VyKGFycmF5T2ZUeXBlQ2hlY2tlcnMpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXlPZlR5cGVDaGVja2VycykpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBwcmludFdhcm5pbmcoJ0ludmFsaWQgYXJndW1lbnQgc3VwcGxpZWQgdG8gb25lT2ZUeXBlLCBleHBlY3RlZCBhbiBpbnN0YW5jZSBvZiBhcnJheS4nKSA6IHZvaWQgMDtcbiAgICAgIHJldHVybiBlbXB0eUZ1bmN0aW9uVGhhdFJldHVybnNOdWxsO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXlPZlR5cGVDaGVja2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGNoZWNrZXIgPSBhcnJheU9mVHlwZUNoZWNrZXJzW2ldO1xuICAgICAgaWYgKHR5cGVvZiBjaGVja2VyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHByaW50V2FybmluZyhcbiAgICAgICAgICAnSW52YWxpZCBhcmd1bWVudCBzdXBwbGllZCB0byBvbmVPZlR5cGUuIEV4cGVjdGVkIGFuIGFycmF5IG9mIGNoZWNrIGZ1bmN0aW9ucywgYnV0ICcgK1xuICAgICAgICAgICdyZWNlaXZlZCAnICsgZ2V0UG9zdGZpeEZvclR5cGVXYXJuaW5nKGNoZWNrZXIpICsgJyBhdCBpbmRleCAnICsgaSArICcuJ1xuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZW1wdHlGdW5jdGlvblRoYXRSZXR1cm5zTnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXlPZlR5cGVDaGVja2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hlY2tlciA9IGFycmF5T2ZUeXBlQ2hlY2tlcnNbaV07XG4gICAgICAgIGlmIChjaGVja2VyKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSwgUmVhY3RQcm9wVHlwZXNTZWNyZXQpID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIHN1cHBsaWVkIHRvICcgKyAoJ2AnICsgY29tcG9uZW50TmFtZSArICdgLicpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZU5vZGVDaGVja2VyKCkge1xuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgaWYgKCFpc05vZGUocHJvcHNbcHJvcE5hbWVdKSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIHN1cHBsaWVkIHRvICcgKyAoJ2AnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBhIFJlYWN0Tm9kZS4nKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVNoYXBlVHlwZUNoZWNrZXIoc2hhcGVUeXBlcykge1xuICAgIGZ1bmN0aW9uIHZhbGlkYXRlKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSkge1xuICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXTtcbiAgICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgICBpZiAocHJvcFR5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvcFR5cGVFcnJvcignSW52YWxpZCAnICsgbG9jYXRpb24gKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Agb2YgdHlwZSBgJyArIHByb3BUeXBlICsgJ2AgJyArICgnc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AsIGV4cGVjdGVkIGBvYmplY3RgLicpKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiBzaGFwZVR5cGVzKSB7XG4gICAgICAgIHZhciBjaGVja2VyID0gc2hhcGVUeXBlc1trZXldO1xuICAgICAgICBpZiAoIWNoZWNrZXIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZXJyb3IgPSBjaGVja2VyKHByb3BWYWx1ZSwga2V5LCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lICsgJy4nICsga2V5LCBSZWFjdFByb3BUeXBlc1NlY3JldCk7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjcmVhdGVDaGFpbmFibGVUeXBlQ2hlY2tlcih2YWxpZGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVTdHJpY3RTaGFwZVR5cGVDaGVja2VyKHNoYXBlVHlwZXMpIHtcbiAgICBmdW5jdGlvbiB2YWxpZGF0ZShwcm9wcywgcHJvcE5hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBwcm9wRnVsbE5hbWUpIHtcbiAgICAgIHZhciBwcm9wVmFsdWUgPSBwcm9wc1twcm9wTmFtZV07XG4gICAgICB2YXIgcHJvcFR5cGUgPSBnZXRQcm9wVHlwZShwcm9wVmFsdWUpO1xuICAgICAgaWYgKHByb3BUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoJ0ludmFsaWQgJyArIGxvY2F0aW9uICsgJyBgJyArIHByb3BGdWxsTmFtZSArICdgIG9mIHR5cGUgYCcgKyBwcm9wVHlwZSArICdgICcgKyAoJ3N1cHBsaWVkIHRvIGAnICsgY29tcG9uZW50TmFtZSArICdgLCBleHBlY3RlZCBgb2JqZWN0YC4nKSk7XG4gICAgICB9XG4gICAgICAvLyBXZSBuZWVkIHRvIGNoZWNrIGFsbCBrZXlzIGluIGNhc2Ugc29tZSBhcmUgcmVxdWlyZWQgYnV0IG1pc3NpbmcgZnJvbVxuICAgICAgLy8gcHJvcHMuXG4gICAgICB2YXIgYWxsS2V5cyA9IGFzc2lnbih7fSwgcHJvcHNbcHJvcE5hbWVdLCBzaGFwZVR5cGVzKTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBhbGxLZXlzKSB7XG4gICAgICAgIHZhciBjaGVja2VyID0gc2hhcGVUeXBlc1trZXldO1xuICAgICAgICBpZiAoIWNoZWNrZXIpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFByb3BUeXBlRXJyb3IoXG4gICAgICAgICAgICAnSW52YWxpZCAnICsgbG9jYXRpb24gKyAnIGAnICsgcHJvcEZ1bGxOYW1lICsgJ2Aga2V5IGAnICsga2V5ICsgJ2Agc3VwcGxpZWQgdG8gYCcgKyBjb21wb25lbnROYW1lICsgJ2AuJyArXG4gICAgICAgICAgICAnXFxuQmFkIG9iamVjdDogJyArIEpTT04uc3RyaW5naWZ5KHByb3BzW3Byb3BOYW1lXSwgbnVsbCwgJyAgJykgK1xuICAgICAgICAgICAgJ1xcblZhbGlkIGtleXM6ICcgKyAgSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXMoc2hhcGVUeXBlcyksIG51bGwsICcgICcpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZXJyb3IgPSBjaGVja2VyKHByb3BWYWx1ZSwga2V5LCBjb21wb25lbnROYW1lLCBsb2NhdGlvbiwgcHJvcEZ1bGxOYW1lICsgJy4nICsga2V5LCBSZWFjdFByb3BUeXBlc1NlY3JldCk7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUNoYWluYWJsZVR5cGVDaGVja2VyKHZhbGlkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzTm9kZShwcm9wVmFsdWUpIHtcbiAgICBzd2l0Y2ggKHR5cGVvZiBwcm9wVmFsdWUpIHtcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgcmV0dXJuICFwcm9wVmFsdWU7XG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwcm9wVmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHByb3BWYWx1ZS5ldmVyeShpc05vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wVmFsdWUgPT09IG51bGwgfHwgaXNWYWxpZEVsZW1lbnQocHJvcFZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGl0ZXJhdG9yRm4gPSBnZXRJdGVyYXRvckZuKHByb3BWYWx1ZSk7XG4gICAgICAgIGlmIChpdGVyYXRvckZuKSB7XG4gICAgICAgICAgdmFyIGl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKHByb3BWYWx1ZSk7XG4gICAgICAgICAgdmFyIHN0ZXA7XG4gICAgICAgICAgaWYgKGl0ZXJhdG9yRm4gIT09IHByb3BWYWx1ZS5lbnRyaWVzKSB7XG4gICAgICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgICAgIGlmICghaXNOb2RlKHN0ZXAudmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEl0ZXJhdG9yIHdpbGwgcHJvdmlkZSBlbnRyeSBbayx2XSB0dXBsZXMgcmF0aGVyIHRoYW4gdmFsdWVzLlxuICAgICAgICAgICAgd2hpbGUgKCEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgICAgICAgICB2YXIgZW50cnkgPSBzdGVwLnZhbHVlO1xuICAgICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzTm9kZShlbnRyeVsxXSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNTeW1ib2wocHJvcFR5cGUsIHByb3BWYWx1ZSkge1xuICAgIC8vIE5hdGl2ZSBTeW1ib2wuXG4gICAgaWYgKHByb3BUeXBlID09PSAnc3ltYm9sJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gMTkuNC4zLjUgU3ltYm9sLnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXSA9PT0gJ1N5bWJvbCdcbiAgICBpZiAocHJvcFZhbHVlWydAQHRvU3RyaW5nVGFnJ10gPT09ICdTeW1ib2wnKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBGYWxsYmFjayBmb3Igbm9uLXNwZWMgY29tcGxpYW50IFN5bWJvbHMgd2hpY2ggYXJlIHBvbHlmaWxsZWQuXG4gICAgaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgcHJvcFZhbHVlIGluc3RhbmNlb2YgU3ltYm9sKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBFcXVpdmFsZW50IG9mIGB0eXBlb2ZgIGJ1dCB3aXRoIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGFycmF5IGFuZCByZWdleHAuXG4gIGZ1bmN0aW9uIGdldFByb3BUeXBlKHByb3BWYWx1ZSkge1xuICAgIHZhciBwcm9wVHlwZSA9IHR5cGVvZiBwcm9wVmFsdWU7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocHJvcFZhbHVlKSkge1xuICAgICAgcmV0dXJuICdhcnJheSc7XG4gICAgfVxuICAgIGlmIChwcm9wVmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIC8vIE9sZCB3ZWJraXRzIChhdCBsZWFzdCB1bnRpbCBBbmRyb2lkIDQuMCkgcmV0dXJuICdmdW5jdGlvbicgcmF0aGVyIHRoYW5cbiAgICAgIC8vICdvYmplY3QnIGZvciB0eXBlb2YgYSBSZWdFeHAuIFdlJ2xsIG5vcm1hbGl6ZSB0aGlzIGhlcmUgc28gdGhhdCAvYmxhL1xuICAgICAgLy8gcGFzc2VzIFByb3BUeXBlcy5vYmplY3QuXG4gICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgfVxuICAgIGlmIChpc1N5bWJvbChwcm9wVHlwZSwgcHJvcFZhbHVlKSkge1xuICAgICAgcmV0dXJuICdzeW1ib2wnO1xuICAgIH1cbiAgICByZXR1cm4gcHJvcFR5cGU7XG4gIH1cblxuICAvLyBUaGlzIGhhbmRsZXMgbW9yZSB0eXBlcyB0aGFuIGBnZXRQcm9wVHlwZWAuIE9ubHkgdXNlZCBmb3IgZXJyb3IgbWVzc2FnZXMuXG4gIC8vIFNlZSBgY3JlYXRlUHJpbWl0aXZlVHlwZUNoZWNrZXJgLlxuICBmdW5jdGlvbiBnZXRQcmVjaXNlVHlwZShwcm9wVmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHByb3BWYWx1ZSA9PT0gJ3VuZGVmaW5lZCcgfHwgcHJvcFZhbHVlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gJycgKyBwcm9wVmFsdWU7XG4gICAgfVxuICAgIHZhciBwcm9wVHlwZSA9IGdldFByb3BUeXBlKHByb3BWYWx1ZSk7XG4gICAgaWYgKHByb3BUeXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHByb3BWYWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuICdkYXRlJztcbiAgICAgIH0gZWxzZSBpZiAocHJvcFZhbHVlIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHJldHVybiAncmVnZXhwJztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHByb3BUeXBlO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHN0cmluZyB0aGF0IGlzIHBvc3RmaXhlZCB0byBhIHdhcm5pbmcgYWJvdXQgYW4gaW52YWxpZCB0eXBlLlxuICAvLyBGb3IgZXhhbXBsZSwgXCJ1bmRlZmluZWRcIiBvciBcIm9mIHR5cGUgYXJyYXlcIlxuICBmdW5jdGlvbiBnZXRQb3N0Zml4Rm9yVHlwZVdhcm5pbmcodmFsdWUpIHtcbiAgICB2YXIgdHlwZSA9IGdldFByZWNpc2VUeXBlKHZhbHVlKTtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICAgIHJldHVybiAnYW4gJyArIHR5cGU7XG4gICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgY2FzZSAncmVnZXhwJzpcbiAgICAgICAgcmV0dXJuICdhICcgKyB0eXBlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgfVxuICB9XG5cbiAgLy8gUmV0dXJucyBjbGFzcyBuYW1lIG9mIHRoZSBvYmplY3QsIGlmIGFueS5cbiAgZnVuY3Rpb24gZ2V0Q2xhc3NOYW1lKHByb3BWYWx1ZSkge1xuICAgIGlmICghcHJvcFZhbHVlLmNvbnN0cnVjdG9yIHx8ICFwcm9wVmFsdWUuY29uc3RydWN0b3IubmFtZSkge1xuICAgICAgcmV0dXJuIEFOT05ZTU9VUztcbiAgICB9XG4gICAgcmV0dXJuIHByb3BWYWx1ZS5jb25zdHJ1Y3Rvci5uYW1lO1xuICB9XG5cbiAgUmVhY3RQcm9wVHlwZXMuY2hlY2tQcm9wVHlwZXMgPSBjaGVja1Byb3BUeXBlcztcbiAgUmVhY3RQcm9wVHlwZXMuUHJvcFR5cGVzID0gUmVhY3RQcm9wVHlwZXM7XG5cbiAgcmV0dXJuIFJlYWN0UHJvcFR5cGVzO1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wcm9wLXR5cGVzL2ZhY3RvcnlXaXRoVHlwZUNoZWNrZXJzLmpzXG4vLyBtb2R1bGUgaWQgPSA1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qXG5vYmplY3QtYXNzaWduXG4oYykgU2luZHJlIFNvcmh1c1xuQGxpY2Vuc2UgTUlUXG4qL1xuXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGdldE93blByb3BlcnR5U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHByb3BJc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5mdW5jdGlvbiB0b09iamVjdCh2YWwpIHtcblx0aWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG5cdH1cblxuXHRyZXR1cm4gT2JqZWN0KHZhbCk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFVzZU5hdGl2ZSgpIHtcblx0dHJ5IHtcblx0XHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBEZXRlY3QgYnVnZ3kgcHJvcGVydHkgZW51bWVyYXRpb24gb3JkZXIgaW4gb2xkZXIgVjggdmVyc2lvbnMuXG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD00MTE4XG5cdFx0dmFyIHRlc3QxID0gbmV3IFN0cmluZygnYWJjJyk7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy13cmFwcGVyc1xuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHQvLyBXZSBkb24ndCBleHBlY3QgYW55IG9mIHRoZSBhYm92ZSB0byB0aHJvdywgYnV0IGJldHRlciB0byBiZSBzYWZlLlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNob3VsZFVzZU5hdGl2ZSgpID8gT2JqZWN0LmFzc2lnbiA6IGZ1bmN0aW9uICh0YXJnZXQsIHNvdXJjZSkge1xuXHR2YXIgZnJvbTtcblx0dmFyIHRvID0gdG9PYmplY3QodGFyZ2V0KTtcblx0dmFyIHN5bWJvbHM7XG5cblx0Zm9yICh2YXIgcyA9IDE7IHMgPCBhcmd1bWVudHMubGVuZ3RoOyBzKyspIHtcblx0XHRmcm9tID0gT2JqZWN0KGFyZ3VtZW50c1tzXSk7XG5cblx0XHRmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuXHRcdFx0aWYgKGhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkge1xuXHRcdFx0XHR0b1trZXldID0gZnJvbVtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChnZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcblx0XHRcdHN5bWJvbHMgPSBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vb2JqZWN0LWFzc2lnbi9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxMy1wcmVzZW50LCBGYWNlYm9vaywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWN0UHJvcFR5cGVzU2VjcmV0ID0gJ1NFQ1JFVF9ET19OT1RfUEFTU19USElTX09SX1lPVV9XSUxMX0JFX0ZJUkVEJztcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFjdFByb3BUeXBlc1NlY3JldDtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wcm9wLXR5cGVzL2xpYi9SZWFjdFByb3BUeXBlc1NlY3JldC5qc1xuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxMy1wcmVzZW50LCBGYWNlYm9vaywgSW5jLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxudmFyIHByaW50V2FybmluZyA9IGZ1bmN0aW9uKCkge307XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIHZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9IHJlcXVpcmUoJy4vbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0Jyk7XG4gIHZhciBsb2dnZWRUeXBlRmFpbHVyZXMgPSB7fTtcblxuICBwcmludFdhcm5pbmcgPSBmdW5jdGlvbih0ZXh0KSB7XG4gICAgdmFyIG1lc3NhZ2UgPSAnV2FybmluZzogJyArIHRleHQ7XG4gICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIC8vIC0tLSBXZWxjb21lIHRvIGRlYnVnZ2luZyBSZWFjdCAtLS1cbiAgICAgIC8vIFRoaXMgZXJyb3Igd2FzIHRocm93biBhcyBhIGNvbnZlbmllbmNlIHNvIHRoYXQgeW91IGNhbiB1c2UgdGhpcyBzdGFja1xuICAgICAgLy8gdG8gZmluZCB0aGUgY2FsbHNpdGUgdGhhdCBjYXVzZWQgdGhpcyB3YXJuaW5nIHRvIGZpcmUuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoeCkge31cbiAgfTtcbn1cblxuLyoqXG4gKiBBc3NlcnQgdGhhdCB0aGUgdmFsdWVzIG1hdGNoIHdpdGggdGhlIHR5cGUgc3BlY3MuXG4gKiBFcnJvciBtZXNzYWdlcyBhcmUgbWVtb3JpemVkIGFuZCB3aWxsIG9ubHkgYmUgc2hvd24gb25jZS5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gdHlwZVNwZWNzIE1hcCBvZiBuYW1lIHRvIGEgUmVhY3RQcm9wVHlwZVxuICogQHBhcmFtIHtvYmplY3R9IHZhbHVlcyBSdW50aW1lIHZhbHVlcyB0aGF0IG5lZWQgdG8gYmUgdHlwZS1jaGVja2VkXG4gKiBAcGFyYW0ge3N0cmluZ30gbG9jYXRpb24gZS5nLiBcInByb3BcIiwgXCJjb250ZXh0XCIsIFwiY2hpbGQgY29udGV4dFwiXG4gKiBAcGFyYW0ge3N0cmluZ30gY29tcG9uZW50TmFtZSBOYW1lIG9mIHRoZSBjb21wb25lbnQgZm9yIGVycm9yIG1lc3NhZ2VzLlxuICogQHBhcmFtIHs/RnVuY3Rpb259IGdldFN0YWNrIFJldHVybnMgdGhlIGNvbXBvbmVudCBzdGFjay5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGNoZWNrUHJvcFR5cGVzKHR5cGVTcGVjcywgdmFsdWVzLCBsb2NhdGlvbiwgY29tcG9uZW50TmFtZSwgZ2V0U3RhY2spIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBmb3IgKHZhciB0eXBlU3BlY05hbWUgaW4gdHlwZVNwZWNzKSB7XG4gICAgICBpZiAodHlwZVNwZWNzLmhhc093blByb3BlcnR5KHR5cGVTcGVjTmFtZSkpIHtcbiAgICAgICAgdmFyIGVycm9yO1xuICAgICAgICAvLyBQcm9wIHR5cGUgdmFsaWRhdGlvbiBtYXkgdGhyb3cuIEluIGNhc2UgdGhleSBkbywgd2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgICAvLyBmYWlsIHRoZSByZW5kZXIgcGhhc2Ugd2hlcmUgaXQgZGlkbid0IGZhaWwgYmVmb3JlLiBTbyB3ZSBsb2cgaXQuXG4gICAgICAgIC8vIEFmdGVyIHRoZXNlIGhhdmUgYmVlbiBjbGVhbmVkIHVwLCB3ZSdsbCBsZXQgdGhlbSB0aHJvdy5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBUaGlzIGlzIGludGVudGlvbmFsbHkgYW4gaW52YXJpYW50IHRoYXQgZ2V0cyBjYXVnaHQuIEl0J3MgdGhlIHNhbWVcbiAgICAgICAgICAvLyBiZWhhdmlvciBhcyB3aXRob3V0IHRoaXMgc3RhdGVtZW50IGV4Y2VwdCB3aXRoIGEgYmV0dGVyIG1lc3NhZ2UuXG4gICAgICAgICAgaWYgKHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKFxuICAgICAgICAgICAgICAoY29tcG9uZW50TmFtZSB8fCAnUmVhY3QgY2xhc3MnKSArICc6ICcgKyBsb2NhdGlvbiArICcgdHlwZSBgJyArIHR5cGVTcGVjTmFtZSArICdgIGlzIGludmFsaWQ7ICcgK1xuICAgICAgICAgICAgICAnaXQgbXVzdCBiZSBhIGZ1bmN0aW9uLCB1c3VhbGx5IGZyb20gdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLCBidXQgcmVjZWl2ZWQgYCcgKyB0eXBlb2YgdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0gKyAnYC4nXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZXJyLm5hbWUgPSAnSW52YXJpYW50IFZpb2xhdGlvbic7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVycm9yID0gdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0odmFsdWVzLCB0eXBlU3BlY05hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBudWxsLCBSZWFjdFByb3BUeXBlc1NlY3JldCk7XG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgZXJyb3IgPSBleDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXJyb3IgJiYgIShlcnJvciBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgIHByaW50V2FybmluZyhcbiAgICAgICAgICAgIChjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycpICsgJzogdHlwZSBzcGVjaWZpY2F0aW9uIG9mICcgK1xuICAgICAgICAgICAgbG9jYXRpb24gKyAnIGAnICsgdHlwZVNwZWNOYW1lICsgJ2AgaXMgaW52YWxpZDsgdGhlIHR5cGUgY2hlY2tlciAnICtcbiAgICAgICAgICAgICdmdW5jdGlvbiBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gYEVycm9yYCBidXQgcmV0dXJuZWQgYSAnICsgdHlwZW9mIGVycm9yICsgJy4gJyArXG4gICAgICAgICAgICAnWW91IG1heSBoYXZlIGZvcmdvdHRlbiB0byBwYXNzIGFuIGFyZ3VtZW50IHRvIHRoZSB0eXBlIGNoZWNrZXIgJyArXG4gICAgICAgICAgICAnY3JlYXRvciAoYXJyYXlPZiwgaW5zdGFuY2VPZiwgb2JqZWN0T2YsIG9uZU9mLCBvbmVPZlR5cGUsIGFuZCAnICtcbiAgICAgICAgICAgICdzaGFwZSBhbGwgcmVxdWlyZSBhbiBhcmd1bWVudCkuJ1xuICAgICAgICAgIClcblxuICAgICAgICB9XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IubWVzc2FnZSBpbiBsb2dnZWRUeXBlRmFpbHVyZXMpKSB7XG4gICAgICAgICAgLy8gT25seSBtb25pdG9yIHRoaXMgZmFpbHVyZSBvbmNlIGJlY2F1c2UgdGhlcmUgdGVuZHMgdG8gYmUgYSBsb3Qgb2YgdGhlXG4gICAgICAgICAgLy8gc2FtZSBlcnJvci5cbiAgICAgICAgICBsb2dnZWRUeXBlRmFpbHVyZXNbZXJyb3IubWVzc2FnZV0gPSB0cnVlO1xuXG4gICAgICAgICAgdmFyIHN0YWNrID0gZ2V0U3RhY2sgPyBnZXRTdGFjaygpIDogJyc7XG5cbiAgICAgICAgICBwcmludFdhcm5pbmcoXG4gICAgICAgICAgICAnRmFpbGVkICcgKyBsb2NhdGlvbiArICcgdHlwZTogJyArIGVycm9yLm1lc3NhZ2UgKyAoc3RhY2sgIT0gbnVsbCA/IHN0YWNrIDogJycpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNoZWNrUHJvcFR5cGVzO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3Byb3AtdHlwZXMvY2hlY2tQcm9wVHlwZXMuanNcbi8vIG1vZHVsZSBpZCA9IDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSZWFjdFByb3BUeXBlc1NlY3JldCA9IHJlcXVpcmUoJy4vbGliL1JlYWN0UHJvcFR5cGVzU2VjcmV0Jyk7XG5cbmZ1bmN0aW9uIGVtcHR5RnVuY3Rpb24oKSB7fVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBzaGltKHByb3BzLCBwcm9wTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIHByb3BGdWxsTmFtZSwgc2VjcmV0KSB7XG4gICAgaWYgKHNlY3JldCA9PT0gUmVhY3RQcm9wVHlwZXNTZWNyZXQpIHtcbiAgICAgIC8vIEl0IGlzIHN0aWxsIHNhZmUgd2hlbiBjYWxsZWQgZnJvbSBSZWFjdC5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcihcbiAgICAgICdDYWxsaW5nIFByb3BUeXBlcyB2YWxpZGF0b3JzIGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLiAnICtcbiAgICAgICdVc2UgUHJvcFR5cGVzLmNoZWNrUHJvcFR5cGVzKCkgdG8gY2FsbCB0aGVtLiAnICtcbiAgICAgICdSZWFkIG1vcmUgYXQgaHR0cDovL2ZiLm1lL3VzZS1jaGVjay1wcm9wLXR5cGVzJ1xuICAgICk7XG4gICAgZXJyLm5hbWUgPSAnSW52YXJpYW50IFZpb2xhdGlvbic7XG4gICAgdGhyb3cgZXJyO1xuICB9O1xuICBzaGltLmlzUmVxdWlyZWQgPSBzaGltO1xuICBmdW5jdGlvbiBnZXRTaGltKCkge1xuICAgIHJldHVybiBzaGltO1xuICB9O1xuICAvLyBJbXBvcnRhbnQhXG4gIC8vIEtlZXAgdGhpcyBsaXN0IGluIHN5bmMgd2l0aCBwcm9kdWN0aW9uIHZlcnNpb24gaW4gYC4vZmFjdG9yeVdpdGhUeXBlQ2hlY2tlcnMuanNgLlxuICB2YXIgUmVhY3RQcm9wVHlwZXMgPSB7XG4gICAgYXJyYXk6IHNoaW0sXG4gICAgYm9vbDogc2hpbSxcbiAgICBmdW5jOiBzaGltLFxuICAgIG51bWJlcjogc2hpbSxcbiAgICBvYmplY3Q6IHNoaW0sXG4gICAgc3RyaW5nOiBzaGltLFxuICAgIHN5bWJvbDogc2hpbSxcblxuICAgIGFueTogc2hpbSxcbiAgICBhcnJheU9mOiBnZXRTaGltLFxuICAgIGVsZW1lbnQ6IHNoaW0sXG4gICAgaW5zdGFuY2VPZjogZ2V0U2hpbSxcbiAgICBub2RlOiBzaGltLFxuICAgIG9iamVjdE9mOiBnZXRTaGltLFxuICAgIG9uZU9mOiBnZXRTaGltLFxuICAgIG9uZU9mVHlwZTogZ2V0U2hpbSxcbiAgICBzaGFwZTogZ2V0U2hpbSxcbiAgICBleGFjdDogZ2V0U2hpbVxuICB9O1xuXG4gIFJlYWN0UHJvcFR5cGVzLmNoZWNrUHJvcFR5cGVzID0gZW1wdHlGdW5jdGlvbjtcbiAgUmVhY3RQcm9wVHlwZXMuUHJvcFR5cGVzID0gUmVhY3RQcm9wVHlwZXM7XG5cbiAgcmV0dXJuIFJlYWN0UHJvcFR5cGVzO1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wcm9wLXR5cGVzL2ZhY3RvcnlXaXRoVGhyb3dpbmdTaGltcy5qc1xuLy8gbW9kdWxlIGlkID0gOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvLyBMb2FkIGluIGRlcGVuZGVuY2llc1xudmFyIGNvbXB1dGVkU3R5bGUgPSByZXF1aXJlKCdjb21wdXRlZC1zdHlsZScpO1xuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgYGxpbmUtaGVpZ2h0YCBvZiBhIGdpdmVuIG5vZGVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IG5vZGUgRWxlbWVudCB0byBjYWxjdWxhdGUgbGluZSBoZWlnaHQgb2YuIE11c3QgYmUgaW4gdGhlIERPTS5cbiAqIEByZXR1cm5zIHtOdW1iZXJ9IGBsaW5lLWhlaWdodGAgb2YgdGhlIGVsZW1lbnQgaW4gcGl4ZWxzXG4gKi9cbmZ1bmN0aW9uIGxpbmVIZWlnaHQobm9kZSkge1xuICAvLyBHcmFiIHRoZSBsaW5lLWhlaWdodCB2aWEgc3R5bGVcbiAgdmFyIGxuSGVpZ2h0U3RyID0gY29tcHV0ZWRTdHlsZShub2RlLCAnbGluZS1oZWlnaHQnKSxcbiAgICAgIGxuSGVpZ2h0ID0gcGFyc2VGbG9hdChsbkhlaWdodFN0ciwgMTApO1xuXG4gIC8vIElmIHRoZSBsaW5lSGVpZ2h0IGRpZCBub3QgY29udGFpbiBhIHVuaXQgKGkuZS4gaXQgd2FzIG51bWVyaWMpLCBjb252ZXJ0IGl0IHRvIGVtcyAoZS5nLiAnMi4zJyA9PT0gJzIuM2VtJylcbiAgaWYgKGxuSGVpZ2h0U3RyID09PSBsbkhlaWdodCArICcnKSB7XG4gICAgLy8gU2F2ZSB0aGUgb2xkIGxpbmVIZWlnaHQgc3R5bGUgYW5kIHVwZGF0ZSB0aGUgZW0gdW5pdCB0byB0aGUgZWxlbWVudFxuICAgIHZhciBfbG5IZWlnaHRTdHlsZSA9IG5vZGUuc3R5bGUubGluZUhlaWdodDtcbiAgICBub2RlLnN0eWxlLmxpbmVIZWlnaHQgPSBsbkhlaWdodFN0ciArICdlbSc7XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIGVtIGJhc2VkIGhlaWdodFxuICAgIGxuSGVpZ2h0U3RyID0gY29tcHV0ZWRTdHlsZShub2RlLCAnbGluZS1oZWlnaHQnKTtcbiAgICBsbkhlaWdodCA9IHBhcnNlRmxvYXQobG5IZWlnaHRTdHIsIDEwKTtcblxuICAgIC8vIFJldmVydCB0aGUgbGluZUhlaWdodCBzdHlsZVxuICAgIGlmIChfbG5IZWlnaHRTdHlsZSkge1xuICAgICAgbm9kZS5zdHlsZS5saW5lSGVpZ2h0ID0gX2xuSGVpZ2h0U3R5bGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSBub2RlLnN0eWxlLmxpbmVIZWlnaHQ7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgdGhlIGxpbmVIZWlnaHQgaXMgaW4gYHB0YCwgY29udmVydCBpdCB0byBwaXhlbHMgKDRweCBmb3IgM3B0KVxuICAvLyBERVY6IGBlbWAgdW5pdHMgYXJlIGNvbnZlcnRlZCB0byBgcHRgIGluIElFNlxuICAvLyBDb252ZXJzaW9uIHJhdGlvIGZyb20gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL2xlbmd0aFxuICBpZiAobG5IZWlnaHRTdHIuaW5kZXhPZigncHQnKSAhPT0gLTEpIHtcbiAgICBsbkhlaWdodCAqPSA0O1xuICAgIGxuSGVpZ2h0IC89IDM7XG4gIH0gZWxzZSBpZiAobG5IZWlnaHRTdHIuaW5kZXhPZignbW0nKSAhPT0gLTEpIHtcbiAgLy8gT3RoZXJ3aXNlLCBpZiB0aGUgbGluZUhlaWdodCBpcyBpbiBgbW1gLCBjb252ZXJ0IGl0IHRvIHBpeGVscyAoOTZweCBmb3IgMjUuNG1tKVxuICAgIGxuSGVpZ2h0ICo9IDk2O1xuICAgIGxuSGVpZ2h0IC89IDI1LjQ7XG4gIH0gZWxzZSBpZiAobG5IZWlnaHRTdHIuaW5kZXhPZignY20nKSAhPT0gLTEpIHtcbiAgLy8gT3RoZXJ3aXNlLCBpZiB0aGUgbGluZUhlaWdodCBpcyBpbiBgY21gLCBjb252ZXJ0IGl0IHRvIHBpeGVscyAoOTZweCBmb3IgMi41NGNtKVxuICAgIGxuSGVpZ2h0ICo9IDk2O1xuICAgIGxuSGVpZ2h0IC89IDIuNTQ7XG4gIH0gZWxzZSBpZiAobG5IZWlnaHRTdHIuaW5kZXhPZignaW4nKSAhPT0gLTEpIHtcbiAgLy8gT3RoZXJ3aXNlLCBpZiB0aGUgbGluZUhlaWdodCBpcyBpbiBgaW5gLCBjb252ZXJ0IGl0IHRvIHBpeGVscyAoOTZweCBmb3IgMWluKVxuICAgIGxuSGVpZ2h0ICo9IDk2O1xuICB9IGVsc2UgaWYgKGxuSGVpZ2h0U3RyLmluZGV4T2YoJ3BjJykgIT09IC0xKSB7XG4gIC8vIE90aGVyd2lzZSwgaWYgdGhlIGxpbmVIZWlnaHQgaXMgaW4gYHBjYCwgY29udmVydCBpdCB0byBwaXhlbHMgKDEycHQgZm9yIDFwYylcbiAgICBsbkhlaWdodCAqPSAxNjtcbiAgfVxuXG4gIC8vIENvbnRpbnVlIG91ciBjb21wdXRhdGlvblxuICBsbkhlaWdodCA9IE1hdGgucm91bmQobG5IZWlnaHQpO1xuXG4gIC8vIElmIHRoZSBsaW5lLWhlaWdodCBpcyBcIm5vcm1hbFwiLCBjYWxjdWxhdGUgYnkgZm9udC1zaXplXG4gIGlmIChsbkhlaWdodFN0ciA9PT0gJ25vcm1hbCcpIHtcbiAgICAvLyBDcmVhdGUgYSB0ZW1wb3Jhcnkgbm9kZVxuICAgIHZhciBub2RlTmFtZSA9IG5vZGUubm9kZU5hbWUsXG4gICAgICAgIF9ub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChub2RlTmFtZSk7XG4gICAgX25vZGUuaW5uZXJIVE1MID0gJyZuYnNwOyc7XG5cbiAgICAvLyBTZXQgdGhlIGZvbnQtc2l6ZSBvZiB0aGUgZWxlbWVudFxuICAgIHZhciBmb250U2l6ZVN0ciA9IGNvbXB1dGVkU3R5bGUobm9kZSwgJ2ZvbnQtc2l6ZScpO1xuICAgIF9ub2RlLnN0eWxlLmZvbnRTaXplID0gZm9udFNpemVTdHI7XG5cbiAgICAvLyBBcHBlbmQgaXQgdG8gdGhlIGJvZHlcbiAgICB2YXIgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gICAgYm9keS5hcHBlbmRDaGlsZChfbm9kZSk7XG5cbiAgICAvLyBBc3N1bWUgdGhlIGxpbmUgaGVpZ2h0IG9mIHRoZSBlbGVtZW50IGlzIHRoZSBoZWlnaHRcbiAgICB2YXIgaGVpZ2h0ID0gX25vZGUub2Zmc2V0SGVpZ2h0O1xuICAgIGxuSGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgLy8gUmVtb3ZlIG91ciBjaGlsZCBmcm9tIHRoZSBET01cbiAgICBib2R5LnJlbW92ZUNoaWxkKF9ub2RlKTtcbiAgfVxuXG4gIC8vIFJldHVybiB0aGUgY2FsY3VsYXRlZCBoZWlnaHRcbiAgcmV0dXJuIGxuSGVpZ2h0O1xufVxuXG4vLyBFeHBvcnQgbGluZUhlaWdodFxubW9kdWxlLmV4cG9ydHMgPSBsaW5lSGVpZ2h0O1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9saW5lLWhlaWdodC9saWIvbGluZS1oZWlnaHQuanNcbi8vIG1vZHVsZSBpZCA9IDEwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIFRoaXMgY29kZSBoYXMgYmVlbiByZWZhY3RvcmVkIGZvciAxNDAgYnl0ZXNcbi8vIFlvdSBjYW4gc2VlIHRoZSBvcmlnaW5hbCBoZXJlOiBodHRwczovL2dpdGh1Yi5jb20vdHdvbGZzb24vY29tcHV0ZWRTdHlsZS9ibG9iLzA0Y2QxZGEyZTMwZmE0NTg0NGY5NWY1Y2IxYWM4OThlOWI5ZWYwNTAvbGliL2NvbXB1dGVkU3R5bGUuanNcbnZhciBjb21wdXRlZFN0eWxlID0gZnVuY3Rpb24gKGVsLCBwcm9wLCBnZXRDb21wdXRlZFN0eWxlKSB7XG4gIGdldENvbXB1dGVkU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZTtcblxuICAvLyBJbiBvbmUgZmVsbCBzd29vcFxuICByZXR1cm4gKFxuICAgIC8vIElmIHdlIGhhdmUgZ2V0Q29tcHV0ZWRTdHlsZVxuICAgIGdldENvbXB1dGVkU3R5bGUgP1xuICAgICAgLy8gUXVlcnkgaXRcbiAgICAgIC8vIFRPRE86IEZyb20gQ1NTLVF1ZXJ5IG5vdGVzLCB3ZSBtaWdodCBuZWVkIChub2RlLCBudWxsKSBmb3IgRkZcbiAgICAgIGdldENvbXB1dGVkU3R5bGUoZWwpIDpcblxuICAgIC8vIE90aGVyd2lzZSwgd2UgYXJlIGluIElFIGFuZCB1c2UgY3VycmVudFN0eWxlXG4gICAgICBlbC5jdXJyZW50U3R5bGVcbiAgKVtcbiAgICAvLyBTd2l0Y2ggdG8gY2FtZWxDYXNlIGZvciBDU1NPTVxuICAgIC8vIERFVjogR3JhYmJlZCBmcm9tIGpRdWVyeVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L2Jsb2IvMS45LXN0YWJsZS9zcmMvY3NzLmpzI0wxOTEtTDE5NFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L2Jsb2IvMS45LXN0YWJsZS9zcmMvY29yZS5qcyNMNTkzLUw1OTdcbiAgICBwcm9wLnJlcGxhY2UoLy0oXFx3KS9naSwgZnVuY3Rpb24gKHdvcmQsIGxldHRlcikge1xuICAgICAgcmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xuICAgIH0pXG4gIF07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXB1dGVkU3R5bGU7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vbGluZS1oZWlnaHQvfi9jb21wdXRlZC1zdHlsZS9kaXN0L2NvbXB1dGVkU3R5bGUuY29tbW9uanMuanNcbi8vIG1vZHVsZSBpZCA9IDExXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlKG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqWydkZWZhdWx0J10gOiBvYmo7IH1cblxudmFyIF9Nb3Rpb24gPSByZXF1aXJlKCcuL01vdGlvbicpO1xuXG5leHBvcnRzLk1vdGlvbiA9IF9pbnRlcm9wUmVxdWlyZShfTW90aW9uKTtcblxudmFyIF9TdGFnZ2VyZWRNb3Rpb24gPSByZXF1aXJlKCcuL1N0YWdnZXJlZE1vdGlvbicpO1xuXG5leHBvcnRzLlN0YWdnZXJlZE1vdGlvbiA9IF9pbnRlcm9wUmVxdWlyZShfU3RhZ2dlcmVkTW90aW9uKTtcblxudmFyIF9UcmFuc2l0aW9uTW90aW9uID0gcmVxdWlyZSgnLi9UcmFuc2l0aW9uTW90aW9uJyk7XG5cbmV4cG9ydHMuVHJhbnNpdGlvbk1vdGlvbiA9IF9pbnRlcm9wUmVxdWlyZShfVHJhbnNpdGlvbk1vdGlvbik7XG5cbnZhciBfc3ByaW5nID0gcmVxdWlyZSgnLi9zcHJpbmcnKTtcblxuZXhwb3J0cy5zcHJpbmcgPSBfaW50ZXJvcFJlcXVpcmUoX3NwcmluZyk7XG5cbnZhciBfcHJlc2V0cyA9IHJlcXVpcmUoJy4vcHJlc2V0cycpO1xuXG5leHBvcnRzLnByZXNldHMgPSBfaW50ZXJvcFJlcXVpcmUoX3ByZXNldHMpO1xuXG52YXIgX3N0cmlwU3R5bGUgPSByZXF1aXJlKCcuL3N0cmlwU3R5bGUnKTtcblxuZXhwb3J0cy5zdHJpcFN0eWxlID0gX2ludGVyb3BSZXF1aXJlKF9zdHJpcFN0eWxlKTtcblxuLy8gZGVwcmVjYXRlZCwgZHVtbXkgd2FybmluZyBmdW5jdGlvblxuXG52YXIgX3Jlb3JkZXJLZXlzID0gcmVxdWlyZSgnLi9yZW9yZGVyS2V5cycpO1xuXG5leHBvcnRzLnJlb3JkZXJLZXlzID0gX2ludGVyb3BSZXF1aXJlKF9yZW9yZGVyS2V5cyk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvcmVhY3QtbW90aW9uLmpzXG4vLyBtb2R1bGUgaWQgPSAxMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfbWFwVG9aZXJvID0gcmVxdWlyZSgnLi9tYXBUb1plcm8nKTtcblxudmFyIF9tYXBUb1plcm8yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFwVG9aZXJvKTtcblxudmFyIF9zdHJpcFN0eWxlID0gcmVxdWlyZSgnLi9zdHJpcFN0eWxlJyk7XG5cbnZhciBfc3RyaXBTdHlsZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zdHJpcFN0eWxlKTtcblxudmFyIF9zdGVwcGVyMyA9IHJlcXVpcmUoJy4vc3RlcHBlcicpO1xuXG52YXIgX3N0ZXBwZXI0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc3RlcHBlcjMpO1xuXG52YXIgX3BlcmZvcm1hbmNlTm93ID0gcmVxdWlyZSgncGVyZm9ybWFuY2Utbm93Jyk7XG5cbnZhciBfcGVyZm9ybWFuY2VOb3cyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcGVyZm9ybWFuY2VOb3cpO1xuXG52YXIgX3JhZiA9IHJlcXVpcmUoJ3JhZicpO1xuXG52YXIgX3JhZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yYWYpO1xuXG52YXIgX3Nob3VsZFN0b3BBbmltYXRpb24gPSByZXF1aXJlKCcuL3Nob3VsZFN0b3BBbmltYXRpb24nKTtcblxudmFyIF9zaG91bGRTdG9wQW5pbWF0aW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3Nob3VsZFN0b3BBbmltYXRpb24pO1xuXG52YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7XG5cbnZhciBfcHJvcFR5cGVzID0gcmVxdWlyZSgncHJvcC10eXBlcycpO1xuXG52YXIgX3Byb3BUeXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wcm9wVHlwZXMpO1xuXG52YXIgbXNQZXJGcmFtZSA9IDEwMDAgLyA2MDtcblxudmFyIE1vdGlvbiA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoTW90aW9uLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICBfY3JlYXRlQ2xhc3MoTW90aW9uLCBudWxsLCBbe1xuICAgIGtleTogJ3Byb3BUeXBlcycsXG4gICAgdmFsdWU6IHtcbiAgICAgIC8vIFRPT0Q6IHdhcm4gYWdhaW5zdCBwdXR0aW5nIGEgY29uZmlnIGluIGhlcmVcbiAgICAgIGRlZmF1bHRTdHlsZTogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5vYmplY3RPZihfcHJvcFR5cGVzMlsnZGVmYXVsdCddLm51bWJlciksXG4gICAgICBzdHlsZTogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5vYmplY3RPZihfcHJvcFR5cGVzMlsnZGVmYXVsdCddLm9uZU9mVHlwZShbX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5udW1iZXIsIF9wcm9wVHlwZXMyWydkZWZhdWx0J10ub2JqZWN0XSkpLmlzUmVxdWlyZWQsXG4gICAgICBjaGlsZHJlbjogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICBvblJlc3Q6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10uZnVuY1xuICAgIH0sXG4gICAgZW51bWVyYWJsZTogdHJ1ZVxuICB9XSk7XG5cbiAgZnVuY3Rpb24gTW90aW9uKHByb3BzKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBNb3Rpb24pO1xuXG4gICAgX1JlYWN0JENvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLndhc0FuaW1hdGluZyA9IGZhbHNlO1xuICAgIHRoaXMuYW5pbWF0aW9uSUQgPSBudWxsO1xuICAgIHRoaXMucHJldlRpbWUgPSAwO1xuICAgIHRoaXMuYWNjdW11bGF0ZWRUaW1lID0gMDtcbiAgICB0aGlzLnVucmVhZFByb3BTdHlsZSA9IG51bGw7XG5cbiAgICB0aGlzLmNsZWFyVW5yZWFkUHJvcFN0eWxlID0gZnVuY3Rpb24gKGRlc3RTdHlsZSkge1xuICAgICAgdmFyIGRpcnR5ID0gZmFsc2U7XG4gICAgICB2YXIgX3N0YXRlID0gX3RoaXMuc3RhdGU7XG4gICAgICB2YXIgY3VycmVudFN0eWxlID0gX3N0YXRlLmN1cnJlbnRTdHlsZTtcbiAgICAgIHZhciBjdXJyZW50VmVsb2NpdHkgPSBfc3RhdGUuY3VycmVudFZlbG9jaXR5O1xuICAgICAgdmFyIGxhc3RJZGVhbFN0eWxlID0gX3N0YXRlLmxhc3RJZGVhbFN0eWxlO1xuICAgICAgdmFyIGxhc3RJZGVhbFZlbG9jaXR5ID0gX3N0YXRlLmxhc3RJZGVhbFZlbG9jaXR5O1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGVzdFN0eWxlKSB7XG4gICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGRlc3RTdHlsZSwga2V5KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0eWxlVmFsdWUgPSBkZXN0U3R5bGVba2V5XTtcbiAgICAgICAgaWYgKHR5cGVvZiBzdHlsZVZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIGlmICghZGlydHkpIHtcbiAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgIGN1cnJlbnRTdHlsZSA9IF9leHRlbmRzKHt9LCBjdXJyZW50U3R5bGUpO1xuICAgICAgICAgICAgY3VycmVudFZlbG9jaXR5ID0gX2V4dGVuZHMoe30sIGN1cnJlbnRWZWxvY2l0eSk7XG4gICAgICAgICAgICBsYXN0SWRlYWxTdHlsZSA9IF9leHRlbmRzKHt9LCBsYXN0SWRlYWxTdHlsZSk7XG4gICAgICAgICAgICBsYXN0SWRlYWxWZWxvY2l0eSA9IF9leHRlbmRzKHt9LCBsYXN0SWRlYWxWZWxvY2l0eSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3VycmVudFN0eWxlW2tleV0gPSBzdHlsZVZhbHVlO1xuICAgICAgICAgIGN1cnJlbnRWZWxvY2l0eVtrZXldID0gMDtcbiAgICAgICAgICBsYXN0SWRlYWxTdHlsZVtrZXldID0gc3R5bGVWYWx1ZTtcbiAgICAgICAgICBsYXN0SWRlYWxWZWxvY2l0eVtrZXldID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZGlydHkpIHtcbiAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBjdXJyZW50U3R5bGU6IGN1cnJlbnRTdHlsZSwgY3VycmVudFZlbG9jaXR5OiBjdXJyZW50VmVsb2NpdHksIGxhc3RJZGVhbFN0eWxlOiBsYXN0SWRlYWxTdHlsZSwgbGFzdElkZWFsVmVsb2NpdHk6IGxhc3RJZGVhbFZlbG9jaXR5IH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUT0RPOiB3aGVuIGNvbmZpZyBpcyB7YTogMTB9IGFuZCBkZXN0IGlzIHthOiAxMH0gZG8gd2UgcmFmIG9uY2UgYW5kXG4gICAgICAvLyBjYWxsIGNiPyBObywgb3RoZXJ3aXNlIGFjY2lkZW50YWwgcGFyZW50IHJlcmVuZGVyIGNhdXNlcyBjYiB0cmlnZ2VyXG4gICAgICBfdGhpcy5hbmltYXRpb25JRCA9IF9yYWYyWydkZWZhdWx0J10oZnVuY3Rpb24gKHRpbWVzdGFtcCkge1xuICAgICAgICAvLyBjaGVjayBpZiB3ZSBuZWVkIHRvIGFuaW1hdGUgaW4gdGhlIGZpcnN0IHBsYWNlXG4gICAgICAgIHZhciBwcm9wc1N0eWxlID0gX3RoaXMucHJvcHMuc3R5bGU7XG4gICAgICAgIGlmIChfc2hvdWxkU3RvcEFuaW1hdGlvbjJbJ2RlZmF1bHQnXShfdGhpcy5zdGF0ZS5jdXJyZW50U3R5bGUsIHByb3BzU3R5bGUsIF90aGlzLnN0YXRlLmN1cnJlbnRWZWxvY2l0eSkpIHtcbiAgICAgICAgICBpZiAoX3RoaXMud2FzQW5pbWF0aW5nICYmIF90aGlzLnByb3BzLm9uUmVzdCkge1xuICAgICAgICAgICAgX3RoaXMucHJvcHMub25SZXN0KCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gbm8gbmVlZCB0byBjYW5jZWwgYW5pbWF0aW9uSUQgaGVyZTsgc2hvdWxkbid0IGhhdmUgYW55IGluIGZsaWdodFxuICAgICAgICAgIF90aGlzLmFuaW1hdGlvbklEID0gbnVsbDtcbiAgICAgICAgICBfdGhpcy53YXNBbmltYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPSAwO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzLndhc0FuaW1hdGluZyA9IHRydWU7XG5cbiAgICAgICAgdmFyIGN1cnJlbnRUaW1lID0gdGltZXN0YW1wIHx8IF9wZXJmb3JtYW5jZU5vdzJbJ2RlZmF1bHQnXSgpO1xuICAgICAgICB2YXIgdGltZURlbHRhID0gY3VycmVudFRpbWUgLSBfdGhpcy5wcmV2VGltZTtcbiAgICAgICAgX3RoaXMucHJldlRpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgX3RoaXMuYWNjdW11bGF0ZWRUaW1lID0gX3RoaXMuYWNjdW11bGF0ZWRUaW1lICsgdGltZURlbHRhO1xuICAgICAgICAvLyBtb3JlIHRoYW4gMTAgZnJhbWVzPyBwcm9sbHkgc3dpdGNoZWQgYnJvd3NlciB0YWIuIFJlc3RhcnRcbiAgICAgICAgaWYgKF90aGlzLmFjY3VtdWxhdGVkVGltZSA+IG1zUGVyRnJhbWUgKiAxMCkge1xuICAgICAgICAgIF90aGlzLmFjY3VtdWxhdGVkVGltZSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoX3RoaXMuYWNjdW11bGF0ZWRUaW1lID09PSAwKSB7XG4gICAgICAgICAgLy8gbm8gbmVlZCB0byBjYW5jZWwgYW5pbWF0aW9uSUQgaGVyZTsgc2hvdWxkbid0IGhhdmUgYW55IGluIGZsaWdodFxuICAgICAgICAgIF90aGlzLmFuaW1hdGlvbklEID0gbnVsbDtcbiAgICAgICAgICBfdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGN1cnJlbnRGcmFtZUNvbXBsZXRpb24gPSAoX3RoaXMuYWNjdW11bGF0ZWRUaW1lIC0gTWF0aC5mbG9vcihfdGhpcy5hY2N1bXVsYXRlZFRpbWUgLyBtc1BlckZyYW1lKSAqIG1zUGVyRnJhbWUpIC8gbXNQZXJGcmFtZTtcbiAgICAgICAgdmFyIGZyYW1lc1RvQ2F0Y2hVcCA9IE1hdGguZmxvb3IoX3RoaXMuYWNjdW11bGF0ZWRUaW1lIC8gbXNQZXJGcmFtZSk7XG5cbiAgICAgICAgdmFyIG5ld0xhc3RJZGVhbFN0eWxlID0ge307XG4gICAgICAgIHZhciBuZXdMYXN0SWRlYWxWZWxvY2l0eSA9IHt9O1xuICAgICAgICB2YXIgbmV3Q3VycmVudFN0eWxlID0ge307XG4gICAgICAgIHZhciBuZXdDdXJyZW50VmVsb2NpdHkgPSB7fTtcblxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gcHJvcHNTdHlsZSkge1xuICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3BzU3R5bGUsIGtleSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBzdHlsZVZhbHVlID0gcHJvcHNTdHlsZVtrZXldO1xuICAgICAgICAgIGlmICh0eXBlb2Ygc3R5bGVWYWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIG5ld0N1cnJlbnRTdHlsZVtrZXldID0gc3R5bGVWYWx1ZTtcbiAgICAgICAgICAgIG5ld0N1cnJlbnRWZWxvY2l0eVtrZXldID0gMDtcbiAgICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlW2tleV0gPSBzdHlsZVZhbHVlO1xuICAgICAgICAgICAgbmV3TGFzdElkZWFsVmVsb2NpdHlba2V5XSA9IDA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlID0gX3RoaXMuc3RhdGUubGFzdElkZWFsU3R5bGVba2V5XTtcbiAgICAgICAgICAgIHZhciBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlID0gX3RoaXMuc3RhdGUubGFzdElkZWFsVmVsb2NpdHlba2V5XTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnJhbWVzVG9DYXRjaFVwOyBpKyspIHtcbiAgICAgICAgICAgICAgdmFyIF9zdGVwcGVyID0gX3N0ZXBwZXI0WydkZWZhdWx0J10obXNQZXJGcmFtZSAvIDEwMDAsIG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUsIG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUsIHN0eWxlVmFsdWUudmFsLCBzdHlsZVZhbHVlLnN0aWZmbmVzcywgc3R5bGVWYWx1ZS5kYW1waW5nLCBzdHlsZVZhbHVlLnByZWNpc2lvbik7XG5cbiAgICAgICAgICAgICAgbmV3TGFzdElkZWFsU3R5bGVWYWx1ZSA9IF9zdGVwcGVyWzBdO1xuICAgICAgICAgICAgICBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlID0gX3N0ZXBwZXJbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBfc3RlcHBlcjIgPSBfc3RlcHBlcjRbJ2RlZmF1bHQnXShtc1BlckZyYW1lIC8gMTAwMCwgbmV3TGFzdElkZWFsU3R5bGVWYWx1ZSwgbmV3TGFzdElkZWFsVmVsb2NpdHlWYWx1ZSwgc3R5bGVWYWx1ZS52YWwsIHN0eWxlVmFsdWUuc3RpZmZuZXNzLCBzdHlsZVZhbHVlLmRhbXBpbmcsIHN0eWxlVmFsdWUucHJlY2lzaW9uKTtcblxuICAgICAgICAgICAgdmFyIG5leHRJZGVhbFggPSBfc3RlcHBlcjJbMF07XG4gICAgICAgICAgICB2YXIgbmV4dElkZWFsViA9IF9zdGVwcGVyMlsxXTtcblxuICAgICAgICAgICAgbmV3Q3VycmVudFN0eWxlW2tleV0gPSBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlICsgKG5leHRJZGVhbFggLSBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlKSAqIGN1cnJlbnRGcmFtZUNvbXBsZXRpb247XG4gICAgICAgICAgICBuZXdDdXJyZW50VmVsb2NpdHlba2V5XSA9IG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUgKyAobmV4dElkZWFsViAtIG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUpICogY3VycmVudEZyYW1lQ29tcGxldGlvbjtcbiAgICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlW2tleV0gPSBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlO1xuICAgICAgICAgICAgbmV3TGFzdElkZWFsVmVsb2NpdHlba2V5XSA9IG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXMuYW5pbWF0aW9uSUQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgYW1vdW50IHdlJ3JlIGxvb3BlZCBvdmVyIGFib3ZlXG4gICAgICAgIF90aGlzLmFjY3VtdWxhdGVkVGltZSAtPSBmcmFtZXNUb0NhdGNoVXAgKiBtc1BlckZyYW1lO1xuXG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBjdXJyZW50U3R5bGU6IG5ld0N1cnJlbnRTdHlsZSxcbiAgICAgICAgICBjdXJyZW50VmVsb2NpdHk6IG5ld0N1cnJlbnRWZWxvY2l0eSxcbiAgICAgICAgICBsYXN0SWRlYWxTdHlsZTogbmV3TGFzdElkZWFsU3R5bGUsXG4gICAgICAgICAgbGFzdElkZWFsVmVsb2NpdHk6IG5ld0xhc3RJZGVhbFZlbG9jaXR5XG4gICAgICAgIH0pO1xuXG4gICAgICAgIF90aGlzLnVucmVhZFByb3BTdHlsZSA9IG51bGw7XG5cbiAgICAgICAgX3RoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHRoaXMuc3RhdGUgPSB0aGlzLmRlZmF1bHRTdGF0ZSgpO1xuICB9XG5cbiAgTW90aW9uLnByb3RvdHlwZS5kZWZhdWx0U3RhdGUgPSBmdW5jdGlvbiBkZWZhdWx0U3RhdGUoKSB7XG4gICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgdmFyIGRlZmF1bHRTdHlsZSA9IF9wcm9wcy5kZWZhdWx0U3R5bGU7XG4gICAgdmFyIHN0eWxlID0gX3Byb3BzLnN0eWxlO1xuXG4gICAgdmFyIGN1cnJlbnRTdHlsZSA9IGRlZmF1bHRTdHlsZSB8fCBfc3RyaXBTdHlsZTJbJ2RlZmF1bHQnXShzdHlsZSk7XG4gICAgdmFyIGN1cnJlbnRWZWxvY2l0eSA9IF9tYXBUb1plcm8yWydkZWZhdWx0J10oY3VycmVudFN0eWxlKTtcbiAgICByZXR1cm4ge1xuICAgICAgY3VycmVudFN0eWxlOiBjdXJyZW50U3R5bGUsXG4gICAgICBjdXJyZW50VmVsb2NpdHk6IGN1cnJlbnRWZWxvY2l0eSxcbiAgICAgIGxhc3RJZGVhbFN0eWxlOiBjdXJyZW50U3R5bGUsXG4gICAgICBsYXN0SWRlYWxWZWxvY2l0eTogY3VycmVudFZlbG9jaXR5XG4gICAgfTtcbiAgfTtcblxuICAvLyBpdCdzIHBvc3NpYmxlIHRoYXQgY3VycmVudFN0eWxlJ3MgdmFsdWUgaXMgc3RhbGU6IGlmIHByb3BzIGlzIGltbWVkaWF0ZWx5XG4gIC8vIGNoYW5nZWQgZnJvbSAwIHRvIDQwMCB0byBzcHJpbmcoMCkgYWdhaW4sIHRoZSBhc3luYyBjdXJyZW50U3R5bGUgaXMgc3RpbGxcbiAgLy8gYXQgMCAoZGlkbid0IGhhdmUgdGltZSB0byB0aWNrIGFuZCBpbnRlcnBvbGF0ZSBldmVuIG9uY2UpLiBJZiB3ZSBuYWl2ZWx5XG4gIC8vIGNvbXBhcmUgY3VycmVudFN0eWxlIHdpdGggZGVzdFZhbCBpdCdsbCBiZSAwID09PSAwIChubyBhbmltYXRpb24sIHN0b3ApLlxuICAvLyBJbiByZWFsaXR5IGN1cnJlbnRTdHlsZSBzaG91bGQgYmUgNDAwXG5cbiAgTW90aW9uLnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgIHRoaXMucHJldlRpbWUgPSBfcGVyZm9ybWFuY2VOb3cyWydkZWZhdWx0J10oKTtcbiAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtcbiAgfTtcblxuICBNb3Rpb24ucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHByb3BzKSB7XG4gICAgaWYgKHRoaXMudW5yZWFkUHJvcFN0eWxlICE9IG51bGwpIHtcbiAgICAgIC8vIHByZXZpb3VzIHByb3BzIGhhdmVuJ3QgaGFkIHRoZSBjaGFuY2UgdG8gYmUgc2V0IHlldDsgc2V0IHRoZW0gaGVyZVxuICAgICAgdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZSh0aGlzLnVucmVhZFByb3BTdHlsZSk7XG4gICAgfVxuXG4gICAgdGhpcy51bnJlYWRQcm9wU3R5bGUgPSBwcm9wcy5zdHlsZTtcbiAgICBpZiAodGhpcy5hbmltYXRpb25JRCA9PSBudWxsKSB7XG4gICAgICB0aGlzLnByZXZUaW1lID0gX3BlcmZvcm1hbmNlTm93MlsnZGVmYXVsdCddKCk7XG4gICAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtcbiAgICB9XG4gIH07XG5cbiAgTW90aW9uLnByb3RvdHlwZS5jb21wb25lbnRXaWxsVW5tb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgIGlmICh0aGlzLmFuaW1hdGlvbklEICE9IG51bGwpIHtcbiAgICAgIF9yYWYyWydkZWZhdWx0J10uY2FuY2VsKHRoaXMuYW5pbWF0aW9uSUQpO1xuICAgICAgdGhpcy5hbmltYXRpb25JRCA9IG51bGw7XG4gICAgfVxuICB9O1xuXG4gIE1vdGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgIHZhciByZW5kZXJlZENoaWxkcmVuID0gdGhpcy5wcm9wcy5jaGlsZHJlbih0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZSk7XG4gICAgcmV0dXJuIHJlbmRlcmVkQ2hpbGRyZW4gJiYgX3JlYWN0MlsnZGVmYXVsdCddLkNoaWxkcmVuLm9ubHkocmVuZGVyZWRDaGlsZHJlbik7XG4gIH07XG5cbiAgcmV0dXJuIE1vdGlvbjtcbn0pKF9yZWFjdDJbJ2RlZmF1bHQnXS5Db21wb25lbnQpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBNb3Rpb247XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcblxuLy8gYWZ0ZXIgY2hlY2tpbmcgZm9yIHVucmVhZFByb3BTdHlsZSAhPSBudWxsLCB3ZSBtYW51YWxseSBnbyBzZXQgdGhlXG4vLyBub24taW50ZXJwb2xhdGluZyB2YWx1ZXMgKHRob3NlIHRoYXQgYXJlIGEgbnVtYmVyLCB3aXRob3V0IGEgc3ByaW5nXG4vLyBjb25maWcpXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvTW90aW9uLmpzXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcblxuLy8gY3VycmVudGx5IHVzZWQgdG8gaW5pdGlhdGUgdGhlIHZlbG9jaXR5IHN0eWxlIG9iamVjdCB0byAwXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBtYXBUb1plcm87XG5cbmZ1bmN0aW9uIG1hcFRvWmVybyhvYmopIHtcbiAgdmFyIHJldCA9IHt9O1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIHJldFtrZXldID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvbWFwVG9aZXJvLmpzXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcbi8vIHR1cm4ge3g6IHt2YWw6IDEsIHN0aWZmbmVzczogMSwgZGFtcGluZzogMn0sIHk6IDJ9IGdlbmVyYXRlZCBieVxuLy8gYHt4OiBzcHJpbmcoMSwge3N0aWZmbmVzczogMSwgZGFtcGluZzogMn0pLCB5OiAyfWAgaW50byB7eDogMSwgeTogMn1cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0c1snZGVmYXVsdCddID0gc3RyaXBTdHlsZTtcblxuZnVuY3Rpb24gc3RyaXBTdHlsZShzdHlsZSkge1xuICB2YXIgcmV0ID0ge307XG4gIGZvciAodmFyIGtleSBpbiBzdHlsZSkge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0eWxlLCBrZXkpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmV0W2tleV0gPSB0eXBlb2Ygc3R5bGVba2V5XSA9PT0gJ251bWJlcicgPyBzdHlsZVtrZXldIDogc3R5bGVba2V5XS52YWw7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvc3RyaXBTdHlsZS5qc1xuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG5cbi8vIHN0ZXBwZXIgaXMgdXNlZCBhIGxvdC4gU2F2ZXMgYWxsb2NhdGlvbiB0byByZXR1cm4gdGhlIHNhbWUgYXJyYXkgd3JhcHBlci5cbi8vIFRoaXMgaXMgZmluZSBhbmQgZGFuZ2VyLWZyZWUgYWdhaW5zdCBtdXRhdGlvbnMgYmVjYXVzZSB0aGUgY2FsbHNpdGVcbi8vIGltbWVkaWF0ZWx5IGRlc3RydWN0dXJlcyBpdCBhbmQgZ2V0cyB0aGUgbnVtYmVycyBpbnNpZGUgd2l0aG91dCBwYXNzaW5nIHRoZVxuXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IHN0ZXBwZXI7XG5cbnZhciByZXVzZWRUdXBsZSA9IFswLCAwXTtcblxuZnVuY3Rpb24gc3RlcHBlcihzZWNvbmRQZXJGcmFtZSwgeCwgdiwgZGVzdFgsIGssIGIsIHByZWNpc2lvbikge1xuICAvLyBTcHJpbmcgc3RpZmZuZXNzLCBpbiBrZyAvIHNeMlxuXG4gIC8vIGZvciBhbmltYXRpb25zLCBkZXN0WCBpcyByZWFsbHkgc3ByaW5nIGxlbmd0aCAoc3ByaW5nIGF0IHJlc3QpLiBpbml0aWFsXG4gIC8vIHBvc2l0aW9uIGlzIGNvbnNpZGVyZWQgYXMgdGhlIHN0cmV0Y2hlZC9jb21wcmVzc2VkIHBvc2l0aW9uIG9mIGEgc3ByaW5nXG4gIHZhciBGc3ByaW5nID0gLWsgKiAoeCAtIGRlc3RYKTtcblxuICAvLyBEYW1waW5nLCBpbiBrZyAvIHNcbiAgdmFyIEZkYW1wZXIgPSAtYiAqIHY7XG5cbiAgLy8gdXN1YWxseSB3ZSBwdXQgbWFzcyBoZXJlLCBidXQgZm9yIGFuaW1hdGlvbiBwdXJwb3Nlcywgc3BlY2lmeWluZyBtYXNzIGlzIGFcbiAgLy8gYml0IHJlZHVuZGFudC4geW91IGNvdWxkIHNpbXBseSBhZGp1c3QgayBhbmQgYiBhY2NvcmRpbmdseVxuICAvLyBsZXQgYSA9IChGc3ByaW5nICsgRmRhbXBlcikgLyBtYXNzO1xuICB2YXIgYSA9IEZzcHJpbmcgKyBGZGFtcGVyO1xuXG4gIHZhciBuZXdWID0gdiArIGEgKiBzZWNvbmRQZXJGcmFtZTtcbiAgdmFyIG5ld1ggPSB4ICsgbmV3ViAqIHNlY29uZFBlckZyYW1lO1xuXG4gIGlmIChNYXRoLmFicyhuZXdWKSA8IHByZWNpc2lvbiAmJiBNYXRoLmFicyhuZXdYIC0gZGVzdFgpIDwgcHJlY2lzaW9uKSB7XG4gICAgcmV1c2VkVHVwbGVbMF0gPSBkZXN0WDtcbiAgICByZXVzZWRUdXBsZVsxXSA9IDA7XG4gICAgcmV0dXJuIHJldXNlZFR1cGxlO1xuICB9XG5cbiAgcmV1c2VkVHVwbGVbMF0gPSBuZXdYO1xuICByZXVzZWRUdXBsZVsxXSA9IG5ld1Y7XG4gIHJldHVybiByZXVzZWRUdXBsZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTtcbi8vIGFycmF5IHJlZmVyZW5jZSBhcm91bmQuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvc3RlcHBlci5qc1xuLy8gbW9kdWxlIGlkID0gMTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgZ2V0TmFub1NlY29uZHMsIGhydGltZSwgbG9hZFRpbWU7XG5cbiAgaWYgKCh0eXBlb2YgcGVyZm9ybWFuY2UgIT09IFwidW5kZWZpbmVkXCIgJiYgcGVyZm9ybWFuY2UgIT09IG51bGwpICYmIHBlcmZvcm1hbmNlLm5vdykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgfTtcbiAgfSBlbHNlIGlmICgodHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIgJiYgcHJvY2VzcyAhPT0gbnVsbCkgJiYgcHJvY2Vzcy5ocnRpbWUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIChnZXROYW5vU2Vjb25kcygpIC0gbG9hZFRpbWUpIC8gMWU2O1xuICAgIH07XG4gICAgaHJ0aW1lID0gcHJvY2Vzcy5ocnRpbWU7XG4gICAgZ2V0TmFub1NlY29uZHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBocjtcbiAgICAgIGhyID0gaHJ0aW1lKCk7XG4gICAgICByZXR1cm4gaHJbMF0gKiAxZTkgKyBoclsxXTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gZ2V0TmFub1NlY29uZHMoKTtcbiAgfSBlbHNlIGlmIChEYXRlLm5vdykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gRGF0ZS5ub3coKSAtIGxvYWRUaW1lO1xuICAgIH07XG4gICAgbG9hZFRpbWUgPSBEYXRlLm5vdygpO1xuICB9IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCkgLSBsb2FkVGltZTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIH1cblxufSkuY2FsbCh0aGlzKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wZXJmb3JtYW5jZS1ub3cvbGliL3BlcmZvcm1hbmNlLW5vdy5qc1xuLy8gbW9kdWxlIGlkID0gMTdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIG5vdyA9IHJlcXVpcmUoJ3BlcmZvcm1hbmNlLW5vdycpXG4gICwgcm9vdCA9IHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogd2luZG93XG4gICwgdmVuZG9ycyA9IFsnbW96JywgJ3dlYmtpdCddXG4gICwgc3VmZml4ID0gJ0FuaW1hdGlvbkZyYW1lJ1xuICAsIHJhZiA9IHJvb3RbJ3JlcXVlc3QnICsgc3VmZml4XVxuICAsIGNhZiA9IHJvb3RbJ2NhbmNlbCcgKyBzdWZmaXhdIHx8IHJvb3RbJ2NhbmNlbFJlcXVlc3QnICsgc3VmZml4XVxuXG5mb3IodmFyIGkgPSAwOyAhcmFmICYmIGkgPCB2ZW5kb3JzLmxlbmd0aDsgaSsrKSB7XG4gIHJhZiA9IHJvb3RbdmVuZG9yc1tpXSArICdSZXF1ZXN0JyArIHN1ZmZpeF1cbiAgY2FmID0gcm9vdFt2ZW5kb3JzW2ldICsgJ0NhbmNlbCcgKyBzdWZmaXhdXG4gICAgICB8fCByb290W3ZlbmRvcnNbaV0gKyAnQ2FuY2VsUmVxdWVzdCcgKyBzdWZmaXhdXG59XG5cbi8vIFNvbWUgdmVyc2lvbnMgb2YgRkYgaGF2ZSByQUYgYnV0IG5vdCBjQUZcbmlmKCFyYWYgfHwgIWNhZikge1xuICB2YXIgbGFzdCA9IDBcbiAgICAsIGlkID0gMFxuICAgICwgcXVldWUgPSBbXVxuICAgICwgZnJhbWVEdXJhdGlvbiA9IDEwMDAgLyA2MFxuXG4gIHJhZiA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYocXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YXIgX25vdyA9IG5vdygpXG4gICAgICAgICwgbmV4dCA9IE1hdGgubWF4KDAsIGZyYW1lRHVyYXRpb24gLSAoX25vdyAtIGxhc3QpKVxuICAgICAgbGFzdCA9IG5leHQgKyBfbm93XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgY3AgPSBxdWV1ZS5zbGljZSgwKVxuICAgICAgICAvLyBDbGVhciBxdWV1ZSBoZXJlIHRvIHByZXZlbnRcbiAgICAgICAgLy8gY2FsbGJhY2tzIGZyb20gYXBwZW5kaW5nIGxpc3RlbmVyc1xuICAgICAgICAvLyB0byB0aGUgY3VycmVudCBmcmFtZSdzIHF1ZXVlXG4gICAgICAgIHF1ZXVlLmxlbmd0aCA9IDBcbiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGNwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYoIWNwW2ldLmNhbmNlbGxlZCkge1xuICAgICAgICAgICAgdHJ5e1xuICAgICAgICAgICAgICBjcFtpXS5jYWxsYmFjayhsYXN0KVxuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IHRocm93IGUgfSwgMClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIE1hdGgucm91bmQobmV4dCkpXG4gICAgfVxuICAgIHF1ZXVlLnB1c2goe1xuICAgICAgaGFuZGxlOiArK2lkLFxuICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgY2FuY2VsbGVkOiBmYWxzZVxuICAgIH0pXG4gICAgcmV0dXJuIGlkXG4gIH1cblxuICBjYWYgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmKHF1ZXVlW2ldLmhhbmRsZSA9PT0gaGFuZGxlKSB7XG4gICAgICAgIHF1ZXVlW2ldLmNhbmNlbGxlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbikge1xuICAvLyBXcmFwIGluIGEgbmV3IGZ1bmN0aW9uIHRvIHByZXZlbnRcbiAgLy8gYGNhbmNlbGAgcG90ZW50aWFsbHkgYmVpbmcgYXNzaWduZWRcbiAgLy8gdG8gdGhlIG5hdGl2ZSByQUYgZnVuY3Rpb25cbiAgcmV0dXJuIHJhZi5jYWxsKHJvb3QsIGZuKVxufVxubW9kdWxlLmV4cG9ydHMuY2FuY2VsID0gZnVuY3Rpb24oKSB7XG4gIGNhZi5hcHBseShyb290LCBhcmd1bWVudHMpXG59XG5tb2R1bGUuZXhwb3J0cy5wb2x5ZmlsbCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBpZiAoIW9iamVjdCkge1xuICAgIG9iamVjdCA9IHJvb3Q7XG4gIH1cbiAgb2JqZWN0LnJlcXVlc3RBbmltYXRpb25GcmFtZSA9IHJhZlxuICBvYmplY3QuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBjYWZcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yYWYvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDE4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi4yXG4oZnVuY3Rpb24oKSB7XG4gIHZhciBnZXROYW5vU2Vjb25kcywgaHJ0aW1lLCBsb2FkVGltZSwgbW9kdWxlTG9hZFRpbWUsIG5vZGVMb2FkVGltZSwgdXBUaW1lO1xuXG4gIGlmICgodHlwZW9mIHBlcmZvcm1hbmNlICE9PSBcInVuZGVmaW5lZFwiICYmIHBlcmZvcm1hbmNlICE9PSBudWxsKSAmJiBwZXJmb3JtYW5jZS5ub3cpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAoKHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MgIT09IG51bGwpICYmIHByb2Nlc3MuaHJ0aW1lKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAoZ2V0TmFub1NlY29uZHMoKSAtIG5vZGVMb2FkVGltZSkgLyAxZTY7XG4gICAgfTtcbiAgICBocnRpbWUgPSBwcm9jZXNzLmhydGltZTtcbiAgICBnZXROYW5vU2Vjb25kcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGhyO1xuICAgICAgaHIgPSBocnRpbWUoKTtcbiAgICAgIHJldHVybiBoclswXSAqIDFlOSArIGhyWzFdO1xuICAgIH07XG4gICAgbW9kdWxlTG9hZFRpbWUgPSBnZXROYW5vU2Vjb25kcygpO1xuICAgIHVwVGltZSA9IHByb2Nlc3MudXB0aW1lKCkgKiAxZTk7XG4gICAgbm9kZUxvYWRUaW1lID0gbW9kdWxlTG9hZFRpbWUgLSB1cFRpbWU7XG4gIH0gZWxzZSBpZiAoRGF0ZS5ub3cpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIERhdGUubm93KCkgLSBsb2FkVGltZTtcbiAgICB9O1xuICAgIGxvYWRUaW1lID0gRGF0ZS5ub3coKTtcbiAgfSBlbHNlIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gbG9hZFRpbWU7XG4gICAgfTtcbiAgICBsb2FkVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICB9XG5cbn0pLmNhbGwodGhpcyk7XG5cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBlcmZvcm1hbmNlLW5vdy5qcy5tYXBcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9yYWYvfi9wZXJmb3JtYW5jZS1ub3cvbGliL3BlcmZvcm1hbmNlLW5vdy5qc1xuLy8gbW9kdWxlIGlkID0gMTlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG5cbi8vIHVzYWdlIGFzc3VtcHRpb246IGN1cnJlbnRTdHlsZSB2YWx1ZXMgaGF2ZSBhbHJlYWR5IGJlZW4gcmVuZGVyZWQgYnV0IGl0IHNheXNcbi8vIG5vdGhpbmcgb2Ygd2hldGhlciBjdXJyZW50U3R5bGUgaXMgc3RhbGUgKHNlZSB1bnJlYWRQcm9wU3R5bGUpXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBzaG91bGRTdG9wQW5pbWF0aW9uO1xuXG5mdW5jdGlvbiBzaG91bGRTdG9wQW5pbWF0aW9uKGN1cnJlbnRTdHlsZSwgc3R5bGUsIGN1cnJlbnRWZWxvY2l0eSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3R5bGUpIHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdHlsZSwga2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRWZWxvY2l0eVtrZXldICE9PSAwKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHN0eWxlVmFsdWUgPSB0eXBlb2Ygc3R5bGVba2V5XSA9PT0gJ251bWJlcicgPyBzdHlsZVtrZXldIDogc3R5bGVba2V5XS52YWw7XG4gICAgLy8gc3RlcHBlciB3aWxsIGhhdmUgYWxyZWFkeSB0YWtlbiBjYXJlIG9mIHJvdW5kaW5nIHByZWNpc2lvbiBlcnJvcnMsIHNvXG4gICAgLy8gd29uJ3QgaGF2ZSBzdWNoIHRoaW5nIGFzIDAuOTk5OSAhPT09IDFcbiAgICBpZiAoY3VycmVudFN0eWxlW2tleV0gIT09IHN0eWxlVmFsdWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvc2hvdWxkU3RvcEFuaW1hdGlvbi5qc1xuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgndmFsdWUnIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX21hcFRvWmVybyA9IHJlcXVpcmUoJy4vbWFwVG9aZXJvJyk7XG5cbnZhciBfbWFwVG9aZXJvMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21hcFRvWmVybyk7XG5cbnZhciBfc3RyaXBTdHlsZSA9IHJlcXVpcmUoJy4vc3RyaXBTdHlsZScpO1xuXG52YXIgX3N0cmlwU3R5bGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc3RyaXBTdHlsZSk7XG5cbnZhciBfc3RlcHBlcjMgPSByZXF1aXJlKCcuL3N0ZXBwZXInKTtcblxudmFyIF9zdGVwcGVyNCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3N0ZXBwZXIzKTtcblxudmFyIF9wZXJmb3JtYW5jZU5vdyA9IHJlcXVpcmUoJ3BlcmZvcm1hbmNlLW5vdycpO1xuXG52YXIgX3BlcmZvcm1hbmNlTm93MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3BlcmZvcm1hbmNlTm93KTtcblxudmFyIF9yYWYgPSByZXF1aXJlKCdyYWYnKTtcblxudmFyIF9yYWYyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmFmKTtcblxudmFyIF9zaG91bGRTdG9wQW5pbWF0aW9uID0gcmVxdWlyZSgnLi9zaG91bGRTdG9wQW5pbWF0aW9uJyk7XG5cbnZhciBfc2hvdWxkU3RvcEFuaW1hdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zaG91bGRTdG9wQW5pbWF0aW9uKTtcblxudmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVhY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3QpO1xuXG52YXIgX3Byb3BUeXBlcyA9IHJlcXVpcmUoJ3Byb3AtdHlwZXMnKTtcblxudmFyIF9wcm9wVHlwZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcHJvcFR5cGVzKTtcblxudmFyIG1zUGVyRnJhbWUgPSAxMDAwIC8gNjA7XG5cbmZ1bmN0aW9uIHNob3VsZFN0b3BBbmltYXRpb25BbGwoY3VycmVudFN0eWxlcywgc3R5bGVzLCBjdXJyZW50VmVsb2NpdGllcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGN1cnJlbnRTdHlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIV9zaG91bGRTdG9wQW5pbWF0aW9uMlsnZGVmYXVsdCddKGN1cnJlbnRTdHlsZXNbaV0sIHN0eWxlc1tpXSwgY3VycmVudFZlbG9jaXRpZXNbaV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG52YXIgU3RhZ2dlcmVkTW90aW9uID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhTdGFnZ2VyZWRNb3Rpb24sIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gIF9jcmVhdGVDbGFzcyhTdGFnZ2VyZWRNb3Rpb24sIG51bGwsIFt7XG4gICAga2V5OiAncHJvcFR5cGVzJyxcbiAgICB2YWx1ZToge1xuICAgICAgLy8gVE9PRDogd2FybiBhZ2FpbnN0IHB1dHRpbmcgYSBjb25maWcgaW4gaGVyZVxuICAgICAgZGVmYXVsdFN0eWxlczogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5hcnJheU9mKF9wcm9wVHlwZXMyWydkZWZhdWx0J10ub2JqZWN0T2YoX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5udW1iZXIpKSxcbiAgICAgIHN0eWxlczogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICBjaGlsZHJlbjogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5mdW5jLmlzUmVxdWlyZWRcbiAgICB9LFxuICAgIGVudW1lcmFibGU6IHRydWVcbiAgfV0pO1xuXG4gIGZ1bmN0aW9uIFN0YWdnZXJlZE1vdGlvbihwcm9wcykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU3RhZ2dlcmVkTW90aW9uKTtcblxuICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcyk7XG4gICAgdGhpcy5hbmltYXRpb25JRCA9IG51bGw7XG4gICAgdGhpcy5wcmV2VGltZSA9IDA7XG4gICAgdGhpcy5hY2N1bXVsYXRlZFRpbWUgPSAwO1xuICAgIHRoaXMudW5yZWFkUHJvcFN0eWxlcyA9IG51bGw7XG5cbiAgICB0aGlzLmNsZWFyVW5yZWFkUHJvcFN0eWxlID0gZnVuY3Rpb24gKHVucmVhZFByb3BTdHlsZXMpIHtcbiAgICAgIHZhciBfc3RhdGUgPSBfdGhpcy5zdGF0ZTtcbiAgICAgIHZhciBjdXJyZW50U3R5bGVzID0gX3N0YXRlLmN1cnJlbnRTdHlsZXM7XG4gICAgICB2YXIgY3VycmVudFZlbG9jaXRpZXMgPSBfc3RhdGUuY3VycmVudFZlbG9jaXRpZXM7XG4gICAgICB2YXIgbGFzdElkZWFsU3R5bGVzID0gX3N0YXRlLmxhc3RJZGVhbFN0eWxlcztcbiAgICAgIHZhciBsYXN0SWRlYWxWZWxvY2l0aWVzID0gX3N0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXM7XG5cbiAgICAgIHZhciBzb21lRGlydHkgPSBmYWxzZTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdW5yZWFkUHJvcFN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdW5yZWFkUHJvcFN0eWxlID0gdW5yZWFkUHJvcFN0eWxlc1tpXTtcbiAgICAgICAgdmFyIGRpcnR5ID0gZmFsc2U7XG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIHVucmVhZFByb3BTdHlsZSkge1xuICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHVucmVhZFByb3BTdHlsZSwga2V5KSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIHN0eWxlVmFsdWUgPSB1bnJlYWRQcm9wU3R5bGVba2V5XTtcbiAgICAgICAgICBpZiAodHlwZW9mIHN0eWxlVmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBpZiAoIWRpcnR5KSB7XG4gICAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgc29tZURpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgY3VycmVudFN0eWxlc1tpXSA9IF9leHRlbmRzKHt9LCBjdXJyZW50U3R5bGVzW2ldKTtcbiAgICAgICAgICAgICAgY3VycmVudFZlbG9jaXRpZXNbaV0gPSBfZXh0ZW5kcyh7fSwgY3VycmVudFZlbG9jaXRpZXNbaV0pO1xuICAgICAgICAgICAgICBsYXN0SWRlYWxTdHlsZXNbaV0gPSBfZXh0ZW5kcyh7fSwgbGFzdElkZWFsU3R5bGVzW2ldKTtcbiAgICAgICAgICAgICAgbGFzdElkZWFsVmVsb2NpdGllc1tpXSA9IF9leHRlbmRzKHt9LCBsYXN0SWRlYWxWZWxvY2l0aWVzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnJlbnRTdHlsZXNbaV1ba2V5XSA9IHN0eWxlVmFsdWU7XG4gICAgICAgICAgICBjdXJyZW50VmVsb2NpdGllc1tpXVtrZXldID0gMDtcbiAgICAgICAgICAgIGxhc3RJZGVhbFN0eWxlc1tpXVtrZXldID0gc3R5bGVWYWx1ZTtcbiAgICAgICAgICAgIGxhc3RJZGVhbFZlbG9jaXRpZXNbaV1ba2V5XSA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzb21lRGlydHkpIHtcbiAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBjdXJyZW50U3R5bGVzOiBjdXJyZW50U3R5bGVzLCBjdXJyZW50VmVsb2NpdGllczogY3VycmVudFZlbG9jaXRpZXMsIGxhc3RJZGVhbFN0eWxlczogbGFzdElkZWFsU3R5bGVzLCBsYXN0SWRlYWxWZWxvY2l0aWVzOiBsYXN0SWRlYWxWZWxvY2l0aWVzIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUT0RPOiB3aGVuIGNvbmZpZyBpcyB7YTogMTB9IGFuZCBkZXN0IGlzIHthOiAxMH0gZG8gd2UgcmFmIG9uY2UgYW5kXG4gICAgICAvLyBjYWxsIGNiPyBObywgb3RoZXJ3aXNlIGFjY2lkZW50YWwgcGFyZW50IHJlcmVuZGVyIGNhdXNlcyBjYiB0cmlnZ2VyXG4gICAgICBfdGhpcy5hbmltYXRpb25JRCA9IF9yYWYyWydkZWZhdWx0J10oZnVuY3Rpb24gKHRpbWVzdGFtcCkge1xuICAgICAgICB2YXIgZGVzdFN0eWxlcyA9IF90aGlzLnByb3BzLnN0eWxlcyhfdGhpcy5zdGF0ZS5sYXN0SWRlYWxTdHlsZXMpO1xuXG4gICAgICAgIC8vIGNoZWNrIGlmIHdlIG5lZWQgdG8gYW5pbWF0ZSBpbiB0aGUgZmlyc3QgcGxhY2VcbiAgICAgICAgaWYgKHNob3VsZFN0b3BBbmltYXRpb25BbGwoX3RoaXMuc3RhdGUuY3VycmVudFN0eWxlcywgZGVzdFN0eWxlcywgX3RoaXMuc3RhdGUuY3VycmVudFZlbG9jaXRpZXMpKSB7XG4gICAgICAgICAgLy8gbm8gbmVlZCB0byBjYW5jZWwgYW5pbWF0aW9uSUQgaGVyZTsgc2hvdWxkbid0IGhhdmUgYW55IGluIGZsaWdodFxuICAgICAgICAgIF90aGlzLmFuaW1hdGlvbklEID0gbnVsbDtcbiAgICAgICAgICBfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPSAwO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjdXJyZW50VGltZSA9IHRpbWVzdGFtcCB8fCBfcGVyZm9ybWFuY2VOb3cyWydkZWZhdWx0J10oKTtcbiAgICAgICAgdmFyIHRpbWVEZWx0YSA9IGN1cnJlbnRUaW1lIC0gX3RoaXMucHJldlRpbWU7XG4gICAgICAgIF90aGlzLnByZXZUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgIF90aGlzLmFjY3VtdWxhdGVkVGltZSA9IF90aGlzLmFjY3VtdWxhdGVkVGltZSArIHRpbWVEZWx0YTtcbiAgICAgICAgLy8gbW9yZSB0aGFuIDEwIGZyYW1lcz8gcHJvbGx5IHN3aXRjaGVkIGJyb3dzZXIgdGFiLiBSZXN0YXJ0XG4gICAgICAgIGlmIChfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPiBtc1BlckZyYW1lICogMTApIHtcbiAgICAgICAgICBfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF90aGlzLmFjY3VtdWxhdGVkVGltZSA9PT0gMCkge1xuICAgICAgICAgIC8vIG5vIG5lZWQgdG8gY2FuY2VsIGFuaW1hdGlvbklEIGhlcmU7IHNob3VsZG4ndCBoYXZlIGFueSBpbiBmbGlnaHRcbiAgICAgICAgICBfdGhpcy5hbmltYXRpb25JRCA9IG51bGw7XG4gICAgICAgICAgX3RoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjdXJyZW50RnJhbWVDb21wbGV0aW9uID0gKF90aGlzLmFjY3VtdWxhdGVkVGltZSAtIE1hdGguZmxvb3IoX3RoaXMuYWNjdW11bGF0ZWRUaW1lIC8gbXNQZXJGcmFtZSkgKiBtc1BlckZyYW1lKSAvIG1zUGVyRnJhbWU7XG4gICAgICAgIHZhciBmcmFtZXNUb0NhdGNoVXAgPSBNYXRoLmZsb29yKF90aGlzLmFjY3VtdWxhdGVkVGltZSAvIG1zUGVyRnJhbWUpO1xuXG4gICAgICAgIHZhciBuZXdMYXN0SWRlYWxTdHlsZXMgPSBbXTtcbiAgICAgICAgdmFyIG5ld0xhc3RJZGVhbFZlbG9jaXRpZXMgPSBbXTtcbiAgICAgICAgdmFyIG5ld0N1cnJlbnRTdHlsZXMgPSBbXTtcbiAgICAgICAgdmFyIG5ld0N1cnJlbnRWZWxvY2l0aWVzID0gW107XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXN0U3R5bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGRlc3RTdHlsZSA9IGRlc3RTdHlsZXNbaV07XG4gICAgICAgICAgdmFyIG5ld0N1cnJlbnRTdHlsZSA9IHt9O1xuICAgICAgICAgIHZhciBuZXdDdXJyZW50VmVsb2NpdHkgPSB7fTtcbiAgICAgICAgICB2YXIgbmV3TGFzdElkZWFsU3R5bGUgPSB7fTtcbiAgICAgICAgICB2YXIgbmV3TGFzdElkZWFsVmVsb2NpdHkgPSB7fTtcblxuICAgICAgICAgIGZvciAodmFyIGtleSBpbiBkZXN0U3R5bGUpIHtcbiAgICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGRlc3RTdHlsZSwga2V5KSkge1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHN0eWxlVmFsdWUgPSBkZXN0U3R5bGVba2V5XTtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3R5bGVWYWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgbmV3Q3VycmVudFN0eWxlW2tleV0gPSBzdHlsZVZhbHVlO1xuICAgICAgICAgICAgICBuZXdDdXJyZW50VmVsb2NpdHlba2V5XSA9IDA7XG4gICAgICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlW2tleV0gPSBzdHlsZVZhbHVlO1xuICAgICAgICAgICAgICBuZXdMYXN0SWRlYWxWZWxvY2l0eVtrZXldID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhciBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlID0gX3RoaXMuc3RhdGUubGFzdElkZWFsU3R5bGVzW2ldW2tleV07XG4gICAgICAgICAgICAgIHZhciBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlID0gX3RoaXMuc3RhdGUubGFzdElkZWFsVmVsb2NpdGllc1tpXVtrZXldO1xuICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGZyYW1lc1RvQ2F0Y2hVcDsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9zdGVwcGVyID0gX3N0ZXBwZXI0WydkZWZhdWx0J10obXNQZXJGcmFtZSAvIDEwMDAsIG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUsIG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUsIHN0eWxlVmFsdWUudmFsLCBzdHlsZVZhbHVlLnN0aWZmbmVzcywgc3R5bGVWYWx1ZS5kYW1waW5nLCBzdHlsZVZhbHVlLnByZWNpc2lvbik7XG5cbiAgICAgICAgICAgICAgICBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlID0gX3N0ZXBwZXJbMF07XG4gICAgICAgICAgICAgICAgbmV3TGFzdElkZWFsVmVsb2NpdHlWYWx1ZSA9IF9zdGVwcGVyWzFdO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdmFyIF9zdGVwcGVyMiA9IF9zdGVwcGVyNFsnZGVmYXVsdCddKG1zUGVyRnJhbWUgLyAxMDAwLCBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlLCBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlLCBzdHlsZVZhbHVlLnZhbCwgc3R5bGVWYWx1ZS5zdGlmZm5lc3MsIHN0eWxlVmFsdWUuZGFtcGluZywgc3R5bGVWYWx1ZS5wcmVjaXNpb24pO1xuXG4gICAgICAgICAgICAgIHZhciBuZXh0SWRlYWxYID0gX3N0ZXBwZXIyWzBdO1xuICAgICAgICAgICAgICB2YXIgbmV4dElkZWFsViA9IF9zdGVwcGVyMlsxXTtcblxuICAgICAgICAgICAgICBuZXdDdXJyZW50U3R5bGVba2V5XSA9IG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUgKyAobmV4dElkZWFsWCAtIG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUpICogY3VycmVudEZyYW1lQ29tcGxldGlvbjtcbiAgICAgICAgICAgICAgbmV3Q3VycmVudFZlbG9jaXR5W2tleV0gPSBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlICsgKG5leHRJZGVhbFYgLSBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlKSAqIGN1cnJlbnRGcmFtZUNvbXBsZXRpb247XG4gICAgICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlW2tleV0gPSBuZXdMYXN0SWRlYWxTdHlsZVZhbHVlO1xuICAgICAgICAgICAgICBuZXdMYXN0SWRlYWxWZWxvY2l0eVtrZXldID0gbmV3TGFzdElkZWFsVmVsb2NpdHlWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBuZXdDdXJyZW50U3R5bGVzW2ldID0gbmV3Q3VycmVudFN0eWxlO1xuICAgICAgICAgIG5ld0N1cnJlbnRWZWxvY2l0aWVzW2ldID0gbmV3Q3VycmVudFZlbG9jaXR5O1xuICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlc1tpXSA9IG5ld0xhc3RJZGVhbFN0eWxlO1xuICAgICAgICAgIG5ld0xhc3RJZGVhbFZlbG9jaXRpZXNbaV0gPSBuZXdMYXN0SWRlYWxWZWxvY2l0eTtcbiAgICAgICAgfVxuXG4gICAgICAgIF90aGlzLmFuaW1hdGlvbklEID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIGFtb3VudCB3ZSdyZSBsb29wZWQgb3ZlciBhYm92ZVxuICAgICAgICBfdGhpcy5hY2N1bXVsYXRlZFRpbWUgLT0gZnJhbWVzVG9DYXRjaFVwICogbXNQZXJGcmFtZTtcblxuICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgY3VycmVudFN0eWxlczogbmV3Q3VycmVudFN0eWxlcyxcbiAgICAgICAgICBjdXJyZW50VmVsb2NpdGllczogbmV3Q3VycmVudFZlbG9jaXRpZXMsXG4gICAgICAgICAgbGFzdElkZWFsU3R5bGVzOiBuZXdMYXN0SWRlYWxTdHlsZXMsXG4gICAgICAgICAgbGFzdElkZWFsVmVsb2NpdGllczogbmV3TGFzdElkZWFsVmVsb2NpdGllc1xuICAgICAgICB9KTtcblxuICAgICAgICBfdGhpcy51bnJlYWRQcm9wU3R5bGVzID0gbnVsbDtcblxuICAgICAgICBfdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuZGVmYXVsdFN0YXRlKCk7XG4gIH1cblxuICBTdGFnZ2VyZWRNb3Rpb24ucHJvdG90eXBlLmRlZmF1bHRTdGF0ZSA9IGZ1bmN0aW9uIGRlZmF1bHRTdGF0ZSgpIHtcbiAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICB2YXIgZGVmYXVsdFN0eWxlcyA9IF9wcm9wcy5kZWZhdWx0U3R5bGVzO1xuICAgIHZhciBzdHlsZXMgPSBfcHJvcHMuc3R5bGVzO1xuXG4gICAgdmFyIGN1cnJlbnRTdHlsZXMgPSBkZWZhdWx0U3R5bGVzIHx8IHN0eWxlcygpLm1hcChfc3RyaXBTdHlsZTJbJ2RlZmF1bHQnXSk7XG4gICAgdmFyIGN1cnJlbnRWZWxvY2l0aWVzID0gY3VycmVudFN0eWxlcy5tYXAoZnVuY3Rpb24gKGN1cnJlbnRTdHlsZSkge1xuICAgICAgcmV0dXJuIF9tYXBUb1plcm8yWydkZWZhdWx0J10oY3VycmVudFN0eWxlKTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgY3VycmVudFN0eWxlczogY3VycmVudFN0eWxlcyxcbiAgICAgIGN1cnJlbnRWZWxvY2l0aWVzOiBjdXJyZW50VmVsb2NpdGllcyxcbiAgICAgIGxhc3RJZGVhbFN0eWxlczogY3VycmVudFN0eWxlcyxcbiAgICAgIGxhc3RJZGVhbFZlbG9jaXRpZXM6IGN1cnJlbnRWZWxvY2l0aWVzXG4gICAgfTtcbiAgfTtcblxuICBTdGFnZ2VyZWRNb3Rpb24ucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5wcmV2VGltZSA9IF9wZXJmb3JtYW5jZU5vdzJbJ2RlZmF1bHQnXSgpO1xuICAgIHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO1xuICB9O1xuXG4gIFN0YWdnZXJlZE1vdGlvbi5wcm90b3R5cGUuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMocHJvcHMpIHtcbiAgICBpZiAodGhpcy51bnJlYWRQcm9wU3R5bGVzICE9IG51bGwpIHtcbiAgICAgIC8vIHByZXZpb3VzIHByb3BzIGhhdmVuJ3QgaGFkIHRoZSBjaGFuY2UgdG8gYmUgc2V0IHlldDsgc2V0IHRoZW0gaGVyZVxuICAgICAgdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZSh0aGlzLnVucmVhZFByb3BTdHlsZXMpO1xuICAgIH1cblxuICAgIHRoaXMudW5yZWFkUHJvcFN0eWxlcyA9IHByb3BzLnN0eWxlcyh0aGlzLnN0YXRlLmxhc3RJZGVhbFN0eWxlcyk7XG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uSUQgPT0gbnVsbCkge1xuICAgICAgdGhpcy5wcmV2VGltZSA9IF9wZXJmb3JtYW5jZU5vdzJbJ2RlZmF1bHQnXSgpO1xuICAgICAgdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCk7XG4gICAgfVxuICB9O1xuXG4gIFN0YWdnZXJlZE1vdGlvbi5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICBpZiAodGhpcy5hbmltYXRpb25JRCAhPSBudWxsKSB7XG4gICAgICBfcmFmMlsnZGVmYXVsdCddLmNhbmNlbCh0aGlzLmFuaW1hdGlvbklEKTtcbiAgICAgIHRoaXMuYW5pbWF0aW9uSUQgPSBudWxsO1xuICAgIH1cbiAgfTtcblxuICBTdGFnZ2VyZWRNb3Rpb24ucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICB2YXIgcmVuZGVyZWRDaGlsZHJlbiA9IHRoaXMucHJvcHMuY2hpbGRyZW4odGhpcy5zdGF0ZS5jdXJyZW50U3R5bGVzKTtcbiAgICByZXR1cm4gcmVuZGVyZWRDaGlsZHJlbiAmJiBfcmVhY3QyWydkZWZhdWx0J10uQ2hpbGRyZW4ub25seShyZW5kZXJlZENoaWxkcmVuKTtcbiAgfTtcblxuICByZXR1cm4gU3RhZ2dlcmVkTW90aW9uO1xufSkoX3JlYWN0MlsnZGVmYXVsdCddLkNvbXBvbmVudCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFN0YWdnZXJlZE1vdGlvbjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuXG4vLyBpdCdzIHBvc3NpYmxlIHRoYXQgY3VycmVudFN0eWxlJ3MgdmFsdWUgaXMgc3RhbGU6IGlmIHByb3BzIGlzIGltbWVkaWF0ZWx5XG4vLyBjaGFuZ2VkIGZyb20gMCB0byA0MDAgdG8gc3ByaW5nKDApIGFnYWluLCB0aGUgYXN5bmMgY3VycmVudFN0eWxlIGlzIHN0aWxsXG4vLyBhdCAwIChkaWRuJ3QgaGF2ZSB0aW1lIHRvIHRpY2sgYW5kIGludGVycG9sYXRlIGV2ZW4gb25jZSkuIElmIHdlIG5haXZlbHlcbi8vIGNvbXBhcmUgY3VycmVudFN0eWxlIHdpdGggZGVzdFZhbCBpdCdsbCBiZSAwID09PSAwIChubyBhbmltYXRpb24sIHN0b3ApLlxuLy8gSW4gcmVhbGl0eSBjdXJyZW50U3R5bGUgc2hvdWxkIGJlIDQwMFxuXG4vLyBhZnRlciBjaGVja2luZyBmb3IgdW5yZWFkUHJvcFN0eWxlcyAhPSBudWxsLCB3ZSBtYW51YWxseSBnbyBzZXQgdGhlXG4vLyBub24taW50ZXJwb2xhdGluZyB2YWx1ZXMgKHRob3NlIHRoYXQgYXJlIGEgbnVtYmVyLCB3aXRob3V0IGEgc3ByaW5nXG4vLyBjb25maWcpXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvU3RhZ2dlcmVkTW90aW9uLmpzXG4vLyBtb2R1bGUgaWQgPSAyMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfbWFwVG9aZXJvID0gcmVxdWlyZSgnLi9tYXBUb1plcm8nKTtcblxudmFyIF9tYXBUb1plcm8yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFwVG9aZXJvKTtcblxudmFyIF9zdHJpcFN0eWxlID0gcmVxdWlyZSgnLi9zdHJpcFN0eWxlJyk7XG5cbnZhciBfc3RyaXBTdHlsZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zdHJpcFN0eWxlKTtcblxudmFyIF9zdGVwcGVyMyA9IHJlcXVpcmUoJy4vc3RlcHBlcicpO1xuXG52YXIgX3N0ZXBwZXI0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc3RlcHBlcjMpO1xuXG52YXIgX21lcmdlRGlmZiA9IHJlcXVpcmUoJy4vbWVyZ2VEaWZmJyk7XG5cbnZhciBfbWVyZ2VEaWZmMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lcmdlRGlmZik7XG5cbnZhciBfcGVyZm9ybWFuY2VOb3cgPSByZXF1aXJlKCdwZXJmb3JtYW5jZS1ub3cnKTtcblxudmFyIF9wZXJmb3JtYW5jZU5vdzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wZXJmb3JtYW5jZU5vdyk7XG5cbnZhciBfcmFmID0gcmVxdWlyZSgncmFmJyk7XG5cbnZhciBfcmFmMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JhZik7XG5cbnZhciBfc2hvdWxkU3RvcEFuaW1hdGlvbiA9IHJlcXVpcmUoJy4vc2hvdWxkU3RvcEFuaW1hdGlvbicpO1xuXG52YXIgX3Nob3VsZFN0b3BBbmltYXRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2hvdWxkU3RvcEFuaW1hdGlvbik7XG5cbnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTtcblxudmFyIF9wcm9wVHlwZXMgPSByZXF1aXJlKCdwcm9wLXR5cGVzJyk7XG5cbnZhciBfcHJvcFR5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3Byb3BUeXBlcyk7XG5cbnZhciBtc1BlckZyYW1lID0gMTAwMCAvIDYwO1xuXG4vLyB0aGUgY2hpbGRyZW4gZnVuY3Rpb24gJiAocG90ZW50aWFsKSBzdHlsZXMgZnVuY3Rpb24gYXNrcyBhcyBwYXJhbSBhblxuLy8gQXJyYXk8VHJhbnNpdGlvblBsYWluU3R5bGU+LCB3aGVyZSBlYWNoIFRyYW5zaXRpb25QbGFpblN0eWxlIGlzIG9mIHRoZSBmb3JtYXRcbi8vIHtrZXk6IHN0cmluZywgZGF0YT86IGFueSwgc3R5bGU6IFBsYWluU3R5bGV9LiBIb3dldmVyLCB0aGUgd2F5IHdlIGtlZXBcbi8vIGludGVybmFsIHN0YXRlcyBkb2Vzbid0IGNvbnRhaW4gc3VjaCBhIGRhdGEgc3RydWN0dXJlIChjaGVjayB0aGUgc3RhdGUgYW5kXG4vLyBUcmFuc2l0aW9uTW90aW9uU3RhdGUpLiBTbyB3aGVuIGNoaWxkcmVuIGZ1bmN0aW9uIGFuZCBvdGhlcnMgYXNrIGZvciBzdWNoXG4vLyBkYXRhIHdlIG5lZWQgdG8gZ2VuZXJhdGUgdGhlbSBvbiB0aGUgZmx5IGJ5IGNvbWJpbmluZyBtZXJnZWRQcm9wc1N0eWxlcyBhbmRcbi8vIGN1cnJlbnRTdHlsZXMvbGFzdElkZWFsU3R5bGVzXG5mdW5jdGlvbiByZWh5ZHJhdGVTdHlsZXMobWVyZ2VkUHJvcHNTdHlsZXMsIHVucmVhZFByb3BTdHlsZXMsIHBsYWluU3R5bGVzKSB7XG4gIC8vIENvcHkgdGhlIHZhbHVlIHRvIGEgYGNvbnN0YCBzbyB0aGF0IEZsb3cgdW5kZXJzdGFuZHMgdGhhdCB0aGUgY29uc3Qgd29uJ3RcbiAgLy8gY2hhbmdlIGFuZCB3aWxsIGJlIG5vbi1udWxsYWJsZSBpbiB0aGUgY2FsbGJhY2sgYmVsb3cuXG4gIHZhciBjVW5yZWFkUHJvcFN0eWxlcyA9IHVucmVhZFByb3BTdHlsZXM7XG4gIGlmIChjVW5yZWFkUHJvcFN0eWxlcyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG1lcmdlZFByb3BzU3R5bGVzLm1hcChmdW5jdGlvbiAobWVyZ2VkUHJvcHNTdHlsZSwgaSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAga2V5OiBtZXJnZWRQcm9wc1N0eWxlLmtleSxcbiAgICAgICAgZGF0YTogbWVyZ2VkUHJvcHNTdHlsZS5kYXRhLFxuICAgICAgICBzdHlsZTogcGxhaW5TdHlsZXNbaV1cbiAgICAgIH07XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG1lcmdlZFByb3BzU3R5bGVzLm1hcChmdW5jdGlvbiAobWVyZ2VkUHJvcHNTdHlsZSwgaSkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgY1VucmVhZFByb3BTdHlsZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChjVW5yZWFkUHJvcFN0eWxlc1tqXS5rZXkgPT09IG1lcmdlZFByb3BzU3R5bGUua2V5KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiBjVW5yZWFkUHJvcFN0eWxlc1tqXS5rZXksXG4gICAgICAgICAgZGF0YTogY1VucmVhZFByb3BTdHlsZXNbal0uZGF0YSxcbiAgICAgICAgICBzdHlsZTogcGxhaW5TdHlsZXNbaV1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsga2V5OiBtZXJnZWRQcm9wc1N0eWxlLmtleSwgZGF0YTogbWVyZ2VkUHJvcHNTdHlsZS5kYXRhLCBzdHlsZTogcGxhaW5TdHlsZXNbaV0gfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFN0b3BBbmltYXRpb25BbGwoY3VycmVudFN0eWxlcywgZGVzdFN0eWxlcywgY3VycmVudFZlbG9jaXRpZXMsIG1lcmdlZFByb3BzU3R5bGVzKSB7XG4gIGlmIChtZXJnZWRQcm9wc1N0eWxlcy5sZW5ndGggIT09IGRlc3RTdHlsZXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXJnZWRQcm9wc1N0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChtZXJnZWRQcm9wc1N0eWxlc1tpXS5rZXkgIT09IGRlc3RTdHlsZXNbaV0ua2V5KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLy8gd2UgaGF2ZSB0aGUgaW52YXJpYW50IHRoYXQgbWVyZ2VkUHJvcHNTdHlsZXMgYW5kXG4gIC8vIGN1cnJlbnRTdHlsZXMvY3VycmVudFZlbG9jaXRpZXMvbGFzdCogYXJlIHN5bmNlZCBpbiB0ZXJtcyBvZiBjZWxscywgc2VlXG4gIC8vIG1lcmdlQW5kU3luYyBjb21tZW50IGZvciBtb3JlIGluZm9cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXJnZWRQcm9wc1N0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmICghX3Nob3VsZFN0b3BBbmltYXRpb24yWydkZWZhdWx0J10oY3VycmVudFN0eWxlc1tpXSwgZGVzdFN0eWxlc1tpXS5zdHlsZSwgY3VycmVudFZlbG9jaXRpZXNbaV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIGNvcmUga2V5IG1lcmdpbmcgbG9naWNcblxuLy8gdGhpbmdzIHRvIGRvOiBzYXkgcHJldmlvdXNseSBtZXJnZWQgc3R5bGUgaXMge2EsIGJ9LCBkZXN0IHN0eWxlIChwcm9wKSBpcyB7Yixcbi8vIGN9LCBwcmV2aW91cyBjdXJyZW50IChpbnRlcnBvbGF0aW5nKSBzdHlsZSBpcyB7YSwgYn1cbi8vICoqaW52YXJpYW50Kio6IGN1cnJlbnRbaV0gY29ycmVzcG9uZHMgdG8gbWVyZ2VkW2ldIGluIHRlcm1zIG9mIGtleVxuXG4vLyBzdGVwczpcbi8vIHR1cm4gbWVyZ2VkIHN0eWxlIGludG8ge2E/LCBiLCBjfVxuLy8gICAgYWRkIGMsIHZhbHVlIG9mIGMgaXMgZGVzdFN0eWxlcy5jXG4vLyAgICBtYXliZSByZW1vdmUgYSwgYWthIGNhbGwgd2lsbExlYXZlKGEpLCB0aGVuIG1lcmdlZCBpcyBlaXRoZXIge2IsIGN9IG9yIHthLCBiLCBjfVxuLy8gdHVybiBjdXJyZW50IChpbnRlcnBvbGF0aW5nKSBzdHlsZSBmcm9tIHthLCBifSBpbnRvIHthPywgYiwgY31cbi8vICAgIG1heWJlIHJlbW92ZSBhXG4vLyAgICBjZXJ0YWlubHkgYWRkIGMsIHZhbHVlIG9mIGMgaXMgd2lsbEVudGVyKGMpXG4vLyBsb29wIG92ZXIgbWVyZ2VkIGFuZCBjb25zdHJ1Y3QgbmV3IGN1cnJlbnRcbi8vIGRlc3QgZG9lc24ndCBjaGFuZ2UsIHRoYXQncyBvd25lcidzXG5mdW5jdGlvbiBtZXJnZUFuZFN5bmMod2lsbEVudGVyLCB3aWxsTGVhdmUsIGRpZExlYXZlLCBvbGRNZXJnZWRQcm9wc1N0eWxlcywgZGVzdFN0eWxlcywgb2xkQ3VycmVudFN0eWxlcywgb2xkQ3VycmVudFZlbG9jaXRpZXMsIG9sZExhc3RJZGVhbFN0eWxlcywgb2xkTGFzdElkZWFsVmVsb2NpdGllcykge1xuICB2YXIgbmV3TWVyZ2VkUHJvcHNTdHlsZXMgPSBfbWVyZ2VEaWZmMlsnZGVmYXVsdCddKG9sZE1lcmdlZFByb3BzU3R5bGVzLCBkZXN0U3R5bGVzLCBmdW5jdGlvbiAob2xkSW5kZXgsIG9sZE1lcmdlZFByb3BzU3R5bGUpIHtcbiAgICB2YXIgbGVhdmluZ1N0eWxlID0gd2lsbExlYXZlKG9sZE1lcmdlZFByb3BzU3R5bGUpO1xuICAgIGlmIChsZWF2aW5nU3R5bGUgPT0gbnVsbCkge1xuICAgICAgZGlkTGVhdmUoeyBrZXk6IG9sZE1lcmdlZFByb3BzU3R5bGUua2V5LCBkYXRhOiBvbGRNZXJnZWRQcm9wc1N0eWxlLmRhdGEgfSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKF9zaG91bGRTdG9wQW5pbWF0aW9uMlsnZGVmYXVsdCddKG9sZEN1cnJlbnRTdHlsZXNbb2xkSW5kZXhdLCBsZWF2aW5nU3R5bGUsIG9sZEN1cnJlbnRWZWxvY2l0aWVzW29sZEluZGV4XSkpIHtcbiAgICAgIGRpZExlYXZlKHsga2V5OiBvbGRNZXJnZWRQcm9wc1N0eWxlLmtleSwgZGF0YTogb2xkTWVyZ2VkUHJvcHNTdHlsZS5kYXRhIH0pO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB7IGtleTogb2xkTWVyZ2VkUHJvcHNTdHlsZS5rZXksIGRhdGE6IG9sZE1lcmdlZFByb3BzU3R5bGUuZGF0YSwgc3R5bGU6IGxlYXZpbmdTdHlsZSB9O1xuICB9KTtcblxuICB2YXIgbmV3Q3VycmVudFN0eWxlcyA9IFtdO1xuICB2YXIgbmV3Q3VycmVudFZlbG9jaXRpZXMgPSBbXTtcbiAgdmFyIG5ld0xhc3RJZGVhbFN0eWxlcyA9IFtdO1xuICB2YXIgbmV3TGFzdElkZWFsVmVsb2NpdGllcyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld01lcmdlZFByb3BzU3R5bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG5ld01lcmdlZFByb3BzU3R5bGVDZWxsID0gbmV3TWVyZ2VkUHJvcHNTdHlsZXNbaV07XG4gICAgdmFyIGZvdW5kT2xkSW5kZXggPSBudWxsO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgb2xkTWVyZ2VkUHJvcHNTdHlsZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChvbGRNZXJnZWRQcm9wc1N0eWxlc1tqXS5rZXkgPT09IG5ld01lcmdlZFByb3BzU3R5bGVDZWxsLmtleSkge1xuICAgICAgICBmb3VuZE9sZEluZGV4ID0gajtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFRPRE86IGtleSBzZWFyY2ggY29kZVxuICAgIGlmIChmb3VuZE9sZEluZGV4ID09IG51bGwpIHtcbiAgICAgIHZhciBwbGFpblN0eWxlID0gd2lsbEVudGVyKG5ld01lcmdlZFByb3BzU3R5bGVDZWxsKTtcbiAgICAgIG5ld0N1cnJlbnRTdHlsZXNbaV0gPSBwbGFpblN0eWxlO1xuICAgICAgbmV3TGFzdElkZWFsU3R5bGVzW2ldID0gcGxhaW5TdHlsZTtcblxuICAgICAgdmFyIHZlbG9jaXR5ID0gX21hcFRvWmVybzJbJ2RlZmF1bHQnXShuZXdNZXJnZWRQcm9wc1N0eWxlQ2VsbC5zdHlsZSk7XG4gICAgICBuZXdDdXJyZW50VmVsb2NpdGllc1tpXSA9IHZlbG9jaXR5O1xuICAgICAgbmV3TGFzdElkZWFsVmVsb2NpdGllc1tpXSA9IHZlbG9jaXR5O1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdDdXJyZW50U3R5bGVzW2ldID0gb2xkQ3VycmVudFN0eWxlc1tmb3VuZE9sZEluZGV4XTtcbiAgICAgIG5ld0xhc3RJZGVhbFN0eWxlc1tpXSA9IG9sZExhc3RJZGVhbFN0eWxlc1tmb3VuZE9sZEluZGV4XTtcbiAgICAgIG5ld0N1cnJlbnRWZWxvY2l0aWVzW2ldID0gb2xkQ3VycmVudFZlbG9jaXRpZXNbZm91bmRPbGRJbmRleF07XG4gICAgICBuZXdMYXN0SWRlYWxWZWxvY2l0aWVzW2ldID0gb2xkTGFzdElkZWFsVmVsb2NpdGllc1tmb3VuZE9sZEluZGV4XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gW25ld01lcmdlZFByb3BzU3R5bGVzLCBuZXdDdXJyZW50U3R5bGVzLCBuZXdDdXJyZW50VmVsb2NpdGllcywgbmV3TGFzdElkZWFsU3R5bGVzLCBuZXdMYXN0SWRlYWxWZWxvY2l0aWVzXTtcbn1cblxudmFyIFRyYW5zaXRpb25Nb3Rpb24gPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKFRyYW5zaXRpb25Nb3Rpb24sIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gIF9jcmVhdGVDbGFzcyhUcmFuc2l0aW9uTW90aW9uLCBudWxsLCBbe1xuICAgIGtleTogJ3Byb3BUeXBlcycsXG4gICAgdmFsdWU6IHtcbiAgICAgIGRlZmF1bHRTdHlsZXM6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10uYXJyYXlPZihfcHJvcFR5cGVzMlsnZGVmYXVsdCddLnNoYXBlKHtcbiAgICAgICAga2V5OiBfcHJvcFR5cGVzMlsnZGVmYXVsdCddLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgICBkYXRhOiBfcHJvcFR5cGVzMlsnZGVmYXVsdCddLmFueSxcbiAgICAgICAgc3R5bGU6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10ub2JqZWN0T2YoX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5udW1iZXIpLmlzUmVxdWlyZWRcbiAgICAgIH0pKSxcbiAgICAgIHN0eWxlczogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5vbmVPZlR5cGUoW19wcm9wVHlwZXMyWydkZWZhdWx0J10uZnVuYywgX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5hcnJheU9mKF9wcm9wVHlwZXMyWydkZWZhdWx0J10uc2hhcGUoe1xuICAgICAgICBrZXk6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10uc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIGRhdGE6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10uYW55LFxuICAgICAgICBzdHlsZTogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5vYmplY3RPZihfcHJvcFR5cGVzMlsnZGVmYXVsdCddLm9uZU9mVHlwZShbX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5udW1iZXIsIF9wcm9wVHlwZXMyWydkZWZhdWx0J10ub2JqZWN0XSkpLmlzUmVxdWlyZWRcbiAgICAgIH0pKV0pLmlzUmVxdWlyZWQsXG4gICAgICBjaGlsZHJlbjogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICB3aWxsRW50ZXI6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10uZnVuYyxcbiAgICAgIHdpbGxMZWF2ZTogX3Byb3BUeXBlczJbJ2RlZmF1bHQnXS5mdW5jLFxuICAgICAgZGlkTGVhdmU6IF9wcm9wVHlwZXMyWydkZWZhdWx0J10uZnVuY1xuICAgIH0sXG4gICAgZW51bWVyYWJsZTogdHJ1ZVxuICB9LCB7XG4gICAga2V5OiAnZGVmYXVsdFByb3BzJyxcbiAgICB2YWx1ZToge1xuICAgICAgd2lsbEVudGVyOiBmdW5jdGlvbiB3aWxsRW50ZXIoc3R5bGVUaGF0RW50ZXJlZCkge1xuICAgICAgICByZXR1cm4gX3N0cmlwU3R5bGUyWydkZWZhdWx0J10oc3R5bGVUaGF0RW50ZXJlZC5zdHlsZSk7XG4gICAgICB9LFxuICAgICAgLy8gcmVjYWxsOiByZXR1cm5pbmcgbnVsbCBtYWtlcyB0aGUgY3VycmVudCB1bm1vdW50aW5nIFRyYW5zaXRpb25TdHlsZVxuICAgICAgLy8gZGlzYXBwZWFyIGltbWVkaWF0ZWx5XG4gICAgICB3aWxsTGVhdmU6IGZ1bmN0aW9uIHdpbGxMZWF2ZSgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgZGlkTGVhdmU6IGZ1bmN0aW9uIGRpZExlYXZlKCkge31cbiAgICB9LFxuICAgIGVudW1lcmFibGU6IHRydWVcbiAgfV0pO1xuXG4gIGZ1bmN0aW9uIFRyYW5zaXRpb25Nb3Rpb24ocHJvcHMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRyYW5zaXRpb25Nb3Rpb24pO1xuXG4gICAgX1JlYWN0JENvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLnVubW91bnRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmFuaW1hdGlvbklEID0gbnVsbDtcbiAgICB0aGlzLnByZXZUaW1lID0gMDtcbiAgICB0aGlzLmFjY3VtdWxhdGVkVGltZSA9IDA7XG4gICAgdGhpcy51bnJlYWRQcm9wU3R5bGVzID0gbnVsbDtcblxuICAgIHRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGUgPSBmdW5jdGlvbiAodW5yZWFkUHJvcFN0eWxlcykge1xuICAgICAgdmFyIF9tZXJnZUFuZFN5bmMgPSBtZXJnZUFuZFN5bmMoX3RoaXMucHJvcHMud2lsbEVudGVyLCBfdGhpcy5wcm9wcy53aWxsTGVhdmUsIF90aGlzLnByb3BzLmRpZExlYXZlLCBfdGhpcy5zdGF0ZS5tZXJnZWRQcm9wc1N0eWxlcywgdW5yZWFkUHJvcFN0eWxlcywgX3RoaXMuc3RhdGUuY3VycmVudFN0eWxlcywgX3RoaXMuc3RhdGUuY3VycmVudFZlbG9jaXRpZXMsIF90aGlzLnN0YXRlLmxhc3RJZGVhbFN0eWxlcywgX3RoaXMuc3RhdGUubGFzdElkZWFsVmVsb2NpdGllcyk7XG5cbiAgICAgIHZhciBtZXJnZWRQcm9wc1N0eWxlcyA9IF9tZXJnZUFuZFN5bmNbMF07XG4gICAgICB2YXIgY3VycmVudFN0eWxlcyA9IF9tZXJnZUFuZFN5bmNbMV07XG4gICAgICB2YXIgY3VycmVudFZlbG9jaXRpZXMgPSBfbWVyZ2VBbmRTeW5jWzJdO1xuICAgICAgdmFyIGxhc3RJZGVhbFN0eWxlcyA9IF9tZXJnZUFuZFN5bmNbM107XG4gICAgICB2YXIgbGFzdElkZWFsVmVsb2NpdGllcyA9IF9tZXJnZUFuZFN5bmNbNF07XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdW5yZWFkUHJvcFN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdW5yZWFkUHJvcFN0eWxlID0gdW5yZWFkUHJvcFN0eWxlc1tpXS5zdHlsZTtcbiAgICAgICAgdmFyIGRpcnR5ID0gZmFsc2U7XG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIHVucmVhZFByb3BTdHlsZSkge1xuICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHVucmVhZFByb3BTdHlsZSwga2V5KSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIHN0eWxlVmFsdWUgPSB1bnJlYWRQcm9wU3R5bGVba2V5XTtcbiAgICAgICAgICBpZiAodHlwZW9mIHN0eWxlVmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBpZiAoIWRpcnR5KSB7XG4gICAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgY3VycmVudFN0eWxlc1tpXSA9IF9leHRlbmRzKHt9LCBjdXJyZW50U3R5bGVzW2ldKTtcbiAgICAgICAgICAgICAgY3VycmVudFZlbG9jaXRpZXNbaV0gPSBfZXh0ZW5kcyh7fSwgY3VycmVudFZlbG9jaXRpZXNbaV0pO1xuICAgICAgICAgICAgICBsYXN0SWRlYWxTdHlsZXNbaV0gPSBfZXh0ZW5kcyh7fSwgbGFzdElkZWFsU3R5bGVzW2ldKTtcbiAgICAgICAgICAgICAgbGFzdElkZWFsVmVsb2NpdGllc1tpXSA9IF9leHRlbmRzKHt9LCBsYXN0SWRlYWxWZWxvY2l0aWVzW2ldKTtcbiAgICAgICAgICAgICAgbWVyZ2VkUHJvcHNTdHlsZXNbaV0gPSB7XG4gICAgICAgICAgICAgICAga2V5OiBtZXJnZWRQcm9wc1N0eWxlc1tpXS5rZXksXG4gICAgICAgICAgICAgICAgZGF0YTogbWVyZ2VkUHJvcHNTdHlsZXNbaV0uZGF0YSxcbiAgICAgICAgICAgICAgICBzdHlsZTogX2V4dGVuZHMoe30sIG1lcmdlZFByb3BzU3R5bGVzW2ldLnN0eWxlKVxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VycmVudFN0eWxlc1tpXVtrZXldID0gc3R5bGVWYWx1ZTtcbiAgICAgICAgICAgIGN1cnJlbnRWZWxvY2l0aWVzW2ldW2tleV0gPSAwO1xuICAgICAgICAgICAgbGFzdElkZWFsU3R5bGVzW2ldW2tleV0gPSBzdHlsZVZhbHVlO1xuICAgICAgICAgICAgbGFzdElkZWFsVmVsb2NpdGllc1tpXVtrZXldID0gMDtcbiAgICAgICAgICAgIG1lcmdlZFByb3BzU3R5bGVzW2ldLnN0eWxlW2tleV0gPSBzdHlsZVZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyB1bmxpa2UgdGhlIG90aGVyIDIgY29tcG9uZW50cywgd2UgY2FuJ3QgZGV0ZWN0IHN0YWxlbmVzcyBhbmQgb3B0aW9uYWxseVxuICAgICAgLy8gb3B0IG91dCBvZiBzZXRTdGF0ZSBoZXJlLiBlYWNoIHN0eWxlIG9iamVjdCdzIGRhdGEgbWlnaHQgY29udGFpbiBuZXdcbiAgICAgIC8vIHN0dWZmIHdlJ3JlIG5vdC9jYW5ub3QgY29tcGFyZVxuICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICBjdXJyZW50U3R5bGVzOiBjdXJyZW50U3R5bGVzLFxuICAgICAgICBjdXJyZW50VmVsb2NpdGllczogY3VycmVudFZlbG9jaXRpZXMsXG4gICAgICAgIG1lcmdlZFByb3BzU3R5bGVzOiBtZXJnZWRQcm9wc1N0eWxlcyxcbiAgICAgICAgbGFzdElkZWFsU3R5bGVzOiBsYXN0SWRlYWxTdHlsZXMsXG4gICAgICAgIGxhc3RJZGVhbFZlbG9jaXRpZXM6IGxhc3RJZGVhbFZlbG9jaXRpZXNcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoX3RoaXMudW5tb3VudGluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFRPRE86IHdoZW4gY29uZmlnIGlzIHthOiAxMH0gYW5kIGRlc3QgaXMge2E6IDEwfSBkbyB3ZSByYWYgb25jZSBhbmRcbiAgICAgIC8vIGNhbGwgY2I/IE5vLCBvdGhlcndpc2UgYWNjaWRlbnRhbCBwYXJlbnQgcmVyZW5kZXIgY2F1c2VzIGNiIHRyaWdnZXJcbiAgICAgIF90aGlzLmFuaW1hdGlvbklEID0gX3JhZjJbJ2RlZmF1bHQnXShmdW5jdGlvbiAodGltZXN0YW1wKSB7XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGVuZ2xvdS9yZWFjdC1tb3Rpb24vcHVsbC80MjBcbiAgICAgICAgLy8gPiBpZiBleGVjdXRpb24gcGFzc2VzIHRoZSBjb25kaXRpb25hbCBpZiAodGhpcy51bm1vdW50aW5nKSwgdGhlblxuICAgICAgICAvLyBleGVjdXRlcyBhc3luYyBkZWZhdWx0UmFmIGFuZCBhZnRlciB0aGF0IGNvbXBvbmVudCB1bm1vdW50cyBhbmQgYWZ0ZXJcbiAgICAgICAgLy8gdGhhdCB0aGUgY2FsbGJhY2sgb2YgZGVmYXVsdFJhZiBpcyBjYWxsZWQsIHRoZW4gc2V0U3RhdGUgd2lsbCBiZSBjYWxsZWRcbiAgICAgICAgLy8gb24gdW5tb3VudGVkIGNvbXBvbmVudC5cbiAgICAgICAgaWYgKF90aGlzLnVubW91bnRpbmcpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcHJvcFN0eWxlcyA9IF90aGlzLnByb3BzLnN0eWxlcztcbiAgICAgICAgdmFyIGRlc3RTdHlsZXMgPSB0eXBlb2YgcHJvcFN0eWxlcyA9PT0gJ2Z1bmN0aW9uJyA/IHByb3BTdHlsZXMocmVoeWRyYXRlU3R5bGVzKF90aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLCBfdGhpcy51bnJlYWRQcm9wU3R5bGVzLCBfdGhpcy5zdGF0ZS5sYXN0SWRlYWxTdHlsZXMpKSA6IHByb3BTdHlsZXM7XG5cbiAgICAgICAgLy8gY2hlY2sgaWYgd2UgbmVlZCB0byBhbmltYXRlIGluIHRoZSBmaXJzdCBwbGFjZVxuICAgICAgICBpZiAoc2hvdWxkU3RvcEFuaW1hdGlvbkFsbChfdGhpcy5zdGF0ZS5jdXJyZW50U3R5bGVzLCBkZXN0U3R5bGVzLCBfdGhpcy5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcywgX3RoaXMuc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMpKSB7XG4gICAgICAgICAgLy8gbm8gbmVlZCB0byBjYW5jZWwgYW5pbWF0aW9uSUQgaGVyZTsgc2hvdWxkbid0IGhhdmUgYW55IGluIGZsaWdodFxuICAgICAgICAgIF90aGlzLmFuaW1hdGlvbklEID0gbnVsbDtcbiAgICAgICAgICBfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPSAwO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjdXJyZW50VGltZSA9IHRpbWVzdGFtcCB8fCBfcGVyZm9ybWFuY2VOb3cyWydkZWZhdWx0J10oKTtcbiAgICAgICAgdmFyIHRpbWVEZWx0YSA9IGN1cnJlbnRUaW1lIC0gX3RoaXMucHJldlRpbWU7XG4gICAgICAgIF90aGlzLnByZXZUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgIF90aGlzLmFjY3VtdWxhdGVkVGltZSA9IF90aGlzLmFjY3VtdWxhdGVkVGltZSArIHRpbWVEZWx0YTtcbiAgICAgICAgLy8gbW9yZSB0aGFuIDEwIGZyYW1lcz8gcHJvbGx5IHN3aXRjaGVkIGJyb3dzZXIgdGFiLiBSZXN0YXJ0XG4gICAgICAgIGlmIChfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPiBtc1BlckZyYW1lICogMTApIHtcbiAgICAgICAgICBfdGhpcy5hY2N1bXVsYXRlZFRpbWUgPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF90aGlzLmFjY3VtdWxhdGVkVGltZSA9PT0gMCkge1xuICAgICAgICAgIC8vIG5vIG5lZWQgdG8gY2FuY2VsIGFuaW1hdGlvbklEIGhlcmU7IHNob3VsZG4ndCBoYXZlIGFueSBpbiBmbGlnaHRcbiAgICAgICAgICBfdGhpcy5hbmltYXRpb25JRCA9IG51bGw7XG4gICAgICAgICAgX3RoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjdXJyZW50RnJhbWVDb21wbGV0aW9uID0gKF90aGlzLmFjY3VtdWxhdGVkVGltZSAtIE1hdGguZmxvb3IoX3RoaXMuYWNjdW11bGF0ZWRUaW1lIC8gbXNQZXJGcmFtZSkgKiBtc1BlckZyYW1lKSAvIG1zUGVyRnJhbWU7XG4gICAgICAgIHZhciBmcmFtZXNUb0NhdGNoVXAgPSBNYXRoLmZsb29yKF90aGlzLmFjY3VtdWxhdGVkVGltZSAvIG1zUGVyRnJhbWUpO1xuXG4gICAgICAgIHZhciBfbWVyZ2VBbmRTeW5jMiA9IG1lcmdlQW5kU3luYyhfdGhpcy5wcm9wcy53aWxsRW50ZXIsIF90aGlzLnByb3BzLndpbGxMZWF2ZSwgX3RoaXMucHJvcHMuZGlkTGVhdmUsIF90aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLCBkZXN0U3R5bGVzLCBfdGhpcy5zdGF0ZS5jdXJyZW50U3R5bGVzLCBfdGhpcy5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcywgX3RoaXMuc3RhdGUubGFzdElkZWFsU3R5bGVzLCBfdGhpcy5zdGF0ZS5sYXN0SWRlYWxWZWxvY2l0aWVzKTtcblxuICAgICAgICB2YXIgbmV3TWVyZ2VkUHJvcHNTdHlsZXMgPSBfbWVyZ2VBbmRTeW5jMlswXTtcbiAgICAgICAgdmFyIG5ld0N1cnJlbnRTdHlsZXMgPSBfbWVyZ2VBbmRTeW5jMlsxXTtcbiAgICAgICAgdmFyIG5ld0N1cnJlbnRWZWxvY2l0aWVzID0gX21lcmdlQW5kU3luYzJbMl07XG4gICAgICAgIHZhciBuZXdMYXN0SWRlYWxTdHlsZXMgPSBfbWVyZ2VBbmRTeW5jMlszXTtcbiAgICAgICAgdmFyIG5ld0xhc3RJZGVhbFZlbG9jaXRpZXMgPSBfbWVyZ2VBbmRTeW5jMls0XTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld01lcmdlZFByb3BzU3R5bGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIG5ld01lcmdlZFByb3BzU3R5bGUgPSBuZXdNZXJnZWRQcm9wc1N0eWxlc1tpXS5zdHlsZTtcbiAgICAgICAgICB2YXIgbmV3Q3VycmVudFN0eWxlID0ge307XG4gICAgICAgICAgdmFyIG5ld0N1cnJlbnRWZWxvY2l0eSA9IHt9O1xuICAgICAgICAgIHZhciBuZXdMYXN0SWRlYWxTdHlsZSA9IHt9O1xuICAgICAgICAgIHZhciBuZXdMYXN0SWRlYWxWZWxvY2l0eSA9IHt9O1xuXG4gICAgICAgICAgZm9yICh2YXIga2V5IGluIG5ld01lcmdlZFByb3BzU3R5bGUpIHtcbiAgICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5ld01lcmdlZFByb3BzU3R5bGUsIGtleSkpIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBzdHlsZVZhbHVlID0gbmV3TWVyZ2VkUHJvcHNTdHlsZVtrZXldO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHlsZVZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICBuZXdDdXJyZW50U3R5bGVba2V5XSA9IHN0eWxlVmFsdWU7XG4gICAgICAgICAgICAgIG5ld0N1cnJlbnRWZWxvY2l0eVtrZXldID0gMDtcbiAgICAgICAgICAgICAgbmV3TGFzdElkZWFsU3R5bGVba2V5XSA9IHN0eWxlVmFsdWU7XG4gICAgICAgICAgICAgIG5ld0xhc3RJZGVhbFZlbG9jaXR5W2tleV0gPSAwO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUgPSBuZXdMYXN0SWRlYWxTdHlsZXNbaV1ba2V5XTtcbiAgICAgICAgICAgICAgdmFyIG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUgPSBuZXdMYXN0SWRlYWxWZWxvY2l0aWVzW2ldW2tleV07XG4gICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZnJhbWVzVG9DYXRjaFVwOyBqKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgX3N0ZXBwZXIgPSBfc3RlcHBlcjRbJ2RlZmF1bHQnXShtc1BlckZyYW1lIC8gMTAwMCwgbmV3TGFzdElkZWFsU3R5bGVWYWx1ZSwgbmV3TGFzdElkZWFsVmVsb2NpdHlWYWx1ZSwgc3R5bGVWYWx1ZS52YWwsIHN0eWxlVmFsdWUuc3RpZmZuZXNzLCBzdHlsZVZhbHVlLmRhbXBpbmcsIHN0eWxlVmFsdWUucHJlY2lzaW9uKTtcblxuICAgICAgICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUgPSBfc3RlcHBlclswXTtcbiAgICAgICAgICAgICAgICBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlID0gX3N0ZXBwZXJbMV07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB2YXIgX3N0ZXBwZXIyID0gX3N0ZXBwZXI0WydkZWZhdWx0J10obXNQZXJGcmFtZSAvIDEwMDAsIG5ld0xhc3RJZGVhbFN0eWxlVmFsdWUsIG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUsIHN0eWxlVmFsdWUudmFsLCBzdHlsZVZhbHVlLnN0aWZmbmVzcywgc3R5bGVWYWx1ZS5kYW1waW5nLCBzdHlsZVZhbHVlLnByZWNpc2lvbik7XG5cbiAgICAgICAgICAgICAgdmFyIG5leHRJZGVhbFggPSBfc3RlcHBlcjJbMF07XG4gICAgICAgICAgICAgIHZhciBuZXh0SWRlYWxWID0gX3N0ZXBwZXIyWzFdO1xuXG4gICAgICAgICAgICAgIG5ld0N1cnJlbnRTdHlsZVtrZXldID0gbmV3TGFzdElkZWFsU3R5bGVWYWx1ZSArIChuZXh0SWRlYWxYIC0gbmV3TGFzdElkZWFsU3R5bGVWYWx1ZSkgKiBjdXJyZW50RnJhbWVDb21wbGV0aW9uO1xuICAgICAgICAgICAgICBuZXdDdXJyZW50VmVsb2NpdHlba2V5XSA9IG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUgKyAobmV4dElkZWFsViAtIG5ld0xhc3RJZGVhbFZlbG9jaXR5VmFsdWUpICogY3VycmVudEZyYW1lQ29tcGxldGlvbjtcbiAgICAgICAgICAgICAgbmV3TGFzdElkZWFsU3R5bGVba2V5XSA9IG5ld0xhc3RJZGVhbFN0eWxlVmFsdWU7XG4gICAgICAgICAgICAgIG5ld0xhc3RJZGVhbFZlbG9jaXR5W2tleV0gPSBuZXdMYXN0SWRlYWxWZWxvY2l0eVZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG5ld0xhc3RJZGVhbFN0eWxlc1tpXSA9IG5ld0xhc3RJZGVhbFN0eWxlO1xuICAgICAgICAgIG5ld0xhc3RJZGVhbFZlbG9jaXRpZXNbaV0gPSBuZXdMYXN0SWRlYWxWZWxvY2l0eTtcbiAgICAgICAgICBuZXdDdXJyZW50U3R5bGVzW2ldID0gbmV3Q3VycmVudFN0eWxlO1xuICAgICAgICAgIG5ld0N1cnJlbnRWZWxvY2l0aWVzW2ldID0gbmV3Q3VycmVudFZlbG9jaXR5O1xuICAgICAgICB9XG5cbiAgICAgICAgX3RoaXMuYW5pbWF0aW9uSUQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgYW1vdW50IHdlJ3JlIGxvb3BlZCBvdmVyIGFib3ZlXG4gICAgICAgIF90aGlzLmFjY3VtdWxhdGVkVGltZSAtPSBmcmFtZXNUb0NhdGNoVXAgKiBtc1BlckZyYW1lO1xuXG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBjdXJyZW50U3R5bGVzOiBuZXdDdXJyZW50U3R5bGVzLFxuICAgICAgICAgIGN1cnJlbnRWZWxvY2l0aWVzOiBuZXdDdXJyZW50VmVsb2NpdGllcyxcbiAgICAgICAgICBsYXN0SWRlYWxTdHlsZXM6IG5ld0xhc3RJZGVhbFN0eWxlcyxcbiAgICAgICAgICBsYXN0SWRlYWxWZWxvY2l0aWVzOiBuZXdMYXN0SWRlYWxWZWxvY2l0aWVzLFxuICAgICAgICAgIG1lcmdlZFByb3BzU3R5bGVzOiBuZXdNZXJnZWRQcm9wc1N0eWxlc1xuICAgICAgICB9KTtcblxuICAgICAgICBfdGhpcy51bnJlYWRQcm9wU3R5bGVzID0gbnVsbDtcblxuICAgICAgICBfdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5KCk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuZGVmYXVsdFN0YXRlKCk7XG4gIH1cblxuICBUcmFuc2l0aW9uTW90aW9uLnByb3RvdHlwZS5kZWZhdWx0U3RhdGUgPSBmdW5jdGlvbiBkZWZhdWx0U3RhdGUoKSB7XG4gICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgdmFyIGRlZmF1bHRTdHlsZXMgPSBfcHJvcHMuZGVmYXVsdFN0eWxlcztcbiAgICB2YXIgc3R5bGVzID0gX3Byb3BzLnN0eWxlcztcbiAgICB2YXIgd2lsbEVudGVyID0gX3Byb3BzLndpbGxFbnRlcjtcbiAgICB2YXIgd2lsbExlYXZlID0gX3Byb3BzLndpbGxMZWF2ZTtcbiAgICB2YXIgZGlkTGVhdmUgPSBfcHJvcHMuZGlkTGVhdmU7XG5cbiAgICB2YXIgZGVzdFN0eWxlcyA9IHR5cGVvZiBzdHlsZXMgPT09ICdmdW5jdGlvbicgPyBzdHlsZXMoZGVmYXVsdFN0eWxlcykgOiBzdHlsZXM7XG5cbiAgICAvLyB0aGlzIGlzIHNwZWNpYWwuIGZvciB0aGUgZmlyc3QgdGltZSBhcm91bmQsIHdlIGRvbid0IGhhdmUgYSBjb21wYXJpc29uXG4gICAgLy8gYmV0d2VlbiBsYXN0IChubyBsYXN0KSBhbmQgY3VycmVudCBtZXJnZWQgcHJvcHMuIHdlJ2xsIGNvbXB1dGUgbGFzdCBzbzpcbiAgICAvLyBzYXkgZGVmYXVsdCBpcyB7YSwgYn0gYW5kIHN0eWxlcyAoZGVzdCBzdHlsZSkgaXMge2IsIGN9LCB3ZSdsbFxuICAgIC8vIGZhYnJpY2F0ZSBsYXN0IGFzIHthLCBifVxuICAgIHZhciBvbGRNZXJnZWRQcm9wc1N0eWxlcyA9IHVuZGVmaW5lZDtcbiAgICBpZiAoZGVmYXVsdFN0eWxlcyA9PSBudWxsKSB7XG4gICAgICBvbGRNZXJnZWRQcm9wc1N0eWxlcyA9IGRlc3RTdHlsZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZE1lcmdlZFByb3BzU3R5bGVzID0gZGVmYXVsdFN0eWxlcy5tYXAoZnVuY3Rpb24gKGRlZmF1bHRTdHlsZUNlbGwpIHtcbiAgICAgICAgLy8gVE9ETzoga2V5IHNlYXJjaCBjb2RlXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVzdFN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChkZXN0U3R5bGVzW2ldLmtleSA9PT0gZGVmYXVsdFN0eWxlQ2VsbC5rZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBkZXN0U3R5bGVzW2ldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmYXVsdFN0eWxlQ2VsbDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB2YXIgb2xkQ3VycmVudFN0eWxlcyA9IGRlZmF1bHRTdHlsZXMgPT0gbnVsbCA/IGRlc3RTdHlsZXMubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgICByZXR1cm4gX3N0cmlwU3R5bGUyWydkZWZhdWx0J10ocy5zdHlsZSk7XG4gICAgfSkgOiBkZWZhdWx0U3R5bGVzLm1hcChmdW5jdGlvbiAocykge1xuICAgICAgcmV0dXJuIF9zdHJpcFN0eWxlMlsnZGVmYXVsdCddKHMuc3R5bGUpO1xuICAgIH0pO1xuICAgIHZhciBvbGRDdXJyZW50VmVsb2NpdGllcyA9IGRlZmF1bHRTdHlsZXMgPT0gbnVsbCA/IGRlc3RTdHlsZXMubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgICByZXR1cm4gX21hcFRvWmVybzJbJ2RlZmF1bHQnXShzLnN0eWxlKTtcbiAgICB9KSA6IGRlZmF1bHRTdHlsZXMubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgICByZXR1cm4gX21hcFRvWmVybzJbJ2RlZmF1bHQnXShzLnN0eWxlKTtcbiAgICB9KTtcblxuICAgIHZhciBfbWVyZ2VBbmRTeW5jMyA9IG1lcmdlQW5kU3luYyhcbiAgICAvLyBCZWNhdXNlIHRoaXMgaXMgYW4gb2xkLXN0eWxlIGNyZWF0ZVJlYWN0Q2xhc3MgY29tcG9uZW50LCBGbG93IGRvZXNuJ3RcbiAgICAvLyB1bmRlcnN0YW5kIHRoYXQgdGhlIHdpbGxFbnRlciBhbmQgd2lsbExlYXZlIHByb3BzIGhhdmUgZGVmYXVsdCB2YWx1ZXNcbiAgICAvLyBhbmQgd2lsbCBhbHdheXMgYmUgcHJlc2VudC5cbiAgICB3aWxsRW50ZXIsIHdpbGxMZWF2ZSwgZGlkTGVhdmUsIG9sZE1lcmdlZFByb3BzU3R5bGVzLCBkZXN0U3R5bGVzLCBvbGRDdXJyZW50U3R5bGVzLCBvbGRDdXJyZW50VmVsb2NpdGllcywgb2xkQ3VycmVudFN0eWxlcywgLy8gb2xkTGFzdElkZWFsU3R5bGVzIHJlYWxseVxuICAgIG9sZEN1cnJlbnRWZWxvY2l0aWVzKTtcblxuICAgIHZhciBtZXJnZWRQcm9wc1N0eWxlcyA9IF9tZXJnZUFuZFN5bmMzWzBdO1xuICAgIHZhciBjdXJyZW50U3R5bGVzID0gX21lcmdlQW5kU3luYzNbMV07XG4gICAgdmFyIGN1cnJlbnRWZWxvY2l0aWVzID0gX21lcmdlQW5kU3luYzNbMl07XG4gICAgdmFyIGxhc3RJZGVhbFN0eWxlcyA9IF9tZXJnZUFuZFN5bmMzWzNdO1xuICAgIHZhciBsYXN0SWRlYWxWZWxvY2l0aWVzID0gX21lcmdlQW5kU3luYzNbNF07XG4gICAgLy8gb2xkTGFzdElkZWFsVmVsb2NpdGllcyByZWFsbHlcblxuICAgIHJldHVybiB7XG4gICAgICBjdXJyZW50U3R5bGVzOiBjdXJyZW50U3R5bGVzLFxuICAgICAgY3VycmVudFZlbG9jaXRpZXM6IGN1cnJlbnRWZWxvY2l0aWVzLFxuICAgICAgbGFzdElkZWFsU3R5bGVzOiBsYXN0SWRlYWxTdHlsZXMsXG4gICAgICBsYXN0SWRlYWxWZWxvY2l0aWVzOiBsYXN0SWRlYWxWZWxvY2l0aWVzLFxuICAgICAgbWVyZ2VkUHJvcHNTdHlsZXM6IG1lcmdlZFByb3BzU3R5bGVzXG4gICAgfTtcbiAgfTtcblxuICAvLyBhZnRlciBjaGVja2luZyBmb3IgdW5yZWFkUHJvcFN0eWxlcyAhPSBudWxsLCB3ZSBtYW51YWxseSBnbyBzZXQgdGhlXG4gIC8vIG5vbi1pbnRlcnBvbGF0aW5nIHZhbHVlcyAodGhvc2UgdGhhdCBhcmUgYSBudW1iZXIsIHdpdGhvdXQgYSBzcHJpbmdcbiAgLy8gY29uZmlnKVxuXG4gIFRyYW5zaXRpb25Nb3Rpb24ucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5wcmV2VGltZSA9IF9wZXJmb3JtYW5jZU5vdzJbJ2RlZmF1bHQnXSgpO1xuICAgIHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO1xuICB9O1xuXG4gIFRyYW5zaXRpb25Nb3Rpb24ucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHByb3BzKSB7XG4gICAgaWYgKHRoaXMudW5yZWFkUHJvcFN0eWxlcykge1xuICAgICAgLy8gcHJldmlvdXMgcHJvcHMgaGF2ZW4ndCBoYWQgdGhlIGNoYW5jZSB0byBiZSBzZXQgeWV0OyBzZXQgdGhlbSBoZXJlXG4gICAgICB0aGlzLmNsZWFyVW5yZWFkUHJvcFN0eWxlKHRoaXMudW5yZWFkUHJvcFN0eWxlcyk7XG4gICAgfVxuXG4gICAgdmFyIHN0eWxlcyA9IHByb3BzLnN0eWxlcztcbiAgICBpZiAodHlwZW9mIHN0eWxlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy51bnJlYWRQcm9wU3R5bGVzID0gc3R5bGVzKHJlaHlkcmF0ZVN0eWxlcyh0aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLCB0aGlzLnVucmVhZFByb3BTdHlsZXMsIHRoaXMuc3RhdGUubGFzdElkZWFsU3R5bGVzKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudW5yZWFkUHJvcFN0eWxlcyA9IHN0eWxlcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hbmltYXRpb25JRCA9PSBudWxsKSB7XG4gICAgICB0aGlzLnByZXZUaW1lID0gX3BlcmZvcm1hbmNlTm93MlsnZGVmYXVsdCddKCk7XG4gICAgICB0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtcbiAgICB9XG4gIH07XG5cbiAgVHJhbnNpdGlvbk1vdGlvbi5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICB0aGlzLnVubW91bnRpbmcgPSB0cnVlO1xuICAgIGlmICh0aGlzLmFuaW1hdGlvbklEICE9IG51bGwpIHtcbiAgICAgIF9yYWYyWydkZWZhdWx0J10uY2FuY2VsKHRoaXMuYW5pbWF0aW9uSUQpO1xuICAgICAgdGhpcy5hbmltYXRpb25JRCA9IG51bGw7XG4gICAgfVxuICB9O1xuXG4gIFRyYW5zaXRpb25Nb3Rpb24ucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICB2YXIgaHlkcmF0ZWRTdHlsZXMgPSByZWh5ZHJhdGVTdHlsZXModGhpcy5zdGF0ZS5tZXJnZWRQcm9wc1N0eWxlcywgdGhpcy51bnJlYWRQcm9wU3R5bGVzLCB0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZXMpO1xuICAgIHZhciByZW5kZXJlZENoaWxkcmVuID0gdGhpcy5wcm9wcy5jaGlsZHJlbihoeWRyYXRlZFN0eWxlcyk7XG4gICAgcmV0dXJuIHJlbmRlcmVkQ2hpbGRyZW4gJiYgX3JlYWN0MlsnZGVmYXVsdCddLkNoaWxkcmVuLm9ubHkocmVuZGVyZWRDaGlsZHJlbik7XG4gIH07XG5cbiAgcmV0dXJuIFRyYW5zaXRpb25Nb3Rpb247XG59KShfcmVhY3QyWydkZWZhdWx0J10uQ29tcG9uZW50KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVHJhbnNpdGlvbk1vdGlvbjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuXG4vLyBsaXN0IG9mIHN0eWxlcywgZWFjaCBjb250YWluaW5nIGludGVycG9sYXRpbmcgdmFsdWVzLiBQYXJ0IG9mIHdoYXQncyBwYXNzZWRcbi8vIHRvIGNoaWxkcmVuIGZ1bmN0aW9uLiBOb3RpY2UgdGhhdCB0aGlzIGlzXG4vLyBBcnJheTxBY3R1YWxJbnRlcnBvbGF0aW5nU3R5bGVPYmplY3Q+LCB3aXRob3V0IHRoZSB3cmFwcGVyIHRoYXQgaXMge2tleTogLi4uLFxuLy8gZGF0YTogLi4uIHN0eWxlOiBBY3R1YWxJbnRlcnBvbGF0aW5nU3R5bGVPYmplY3R9LiBPbmx5IG1lcmdlZFByb3BzU3R5bGVzXG4vLyBjb250YWlucyB0aGUga2V5ICYgZGF0YSBpbmZvIChzbyB0aGF0IHdlIG9ubHkgaGF2ZSBhIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGhcbi8vIGZvciB0aGVzZSwgYW5kIHRvIHNhdmUgc3BhY2UpLiBDaGVjayB0aGUgY29tbWVudCBmb3IgYHJlaHlkcmF0ZVN0eWxlc2AgdG9cbi8vIHNlZSBob3cgd2UgcmVnZW5lcmF0ZSB0aGUgZW50aXJldHkgb2Ygd2hhdCdzIHBhc3NlZCB0byBjaGlsZHJlbiBmdW5jdGlvblxuXG4vLyB0aGUgYXJyYXkgdGhhdCBrZWVwcyB0cmFjayBvZiBjdXJyZW50bHkgcmVuZGVyZWQgc3R1ZmYhIEluY2x1ZGluZyBzdHVmZlxuLy8gdGhhdCB5b3UndmUgdW5tb3VudGVkIGJ1dCB0aGF0J3Mgc3RpbGwgYW5pbWF0aW5nLiBUaGlzIGlzIHdoZXJlIGl0IGxpdmVzXG5cbi8vIGl0J3MgcG9zc2libGUgdGhhdCBjdXJyZW50U3R5bGUncyB2YWx1ZSBpcyBzdGFsZTogaWYgcHJvcHMgaXMgaW1tZWRpYXRlbHlcbi8vIGNoYW5nZWQgZnJvbSAwIHRvIDQwMCB0byBzcHJpbmcoMCkgYWdhaW4sIHRoZSBhc3luYyBjdXJyZW50U3R5bGUgaXMgc3RpbGxcbi8vIGF0IDAgKGRpZG4ndCBoYXZlIHRpbWUgdG8gdGljayBhbmQgaW50ZXJwb2xhdGUgZXZlbiBvbmNlKS4gSWYgd2UgbmFpdmVseVxuLy8gY29tcGFyZSBjdXJyZW50U3R5bGUgd2l0aCBkZXN0VmFsIGl0J2xsIGJlIDAgPT09IDAgKG5vIGFuaW1hdGlvbiwgc3RvcCkuXG4vLyBJbiByZWFsaXR5IGN1cnJlbnRTdHlsZSBzaG91bGQgYmUgNDAwXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvVHJhbnNpdGlvbk1vdGlvbi5qc1xuLy8gbW9kdWxlIGlkID0gMjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXG5cbi8vIGNvcmUga2V5cyBtZXJnaW5nIGFsZ29yaXRobS4gSWYgcHJldmlvdXMgcmVuZGVyJ3Mga2V5cyBhcmUgW2EsIGJdLCBhbmQgdGhlXG4vLyBuZXh0IHJlbmRlcidzIFtjLCBiLCBkXSwgd2hhdCdzIHRoZSBmaW5hbCBtZXJnZWQga2V5cyBhbmQgb3JkZXJpbmc/XG5cbi8vIC0gYyBhbmQgYSBtdXN0IGJvdGggYmUgYmVmb3JlIGJcbi8vIC0gYiBiZWZvcmUgZFxuLy8gLSBvcmRlcmluZyBiZXR3ZWVuIGEgYW5kIGMgYW1iaWd1b3VzXG5cbi8vIHRoaXMgcmVkdWNlcyB0byBtZXJnaW5nIHR3byBwYXJ0aWFsbHkgb3JkZXJlZCBsaXN0cyAoZS5nLiBsaXN0cyB3aGVyZSBub3Rcbi8vIGV2ZXJ5IGl0ZW0gaGFzIGEgZGVmaW5pdGUgb3JkZXJpbmcsIGxpa2UgY29tcGFyaW5nIGEgYW5kIGMgYWJvdmUpLiBGb3IgdGhlXG4vLyBhbWJpZ3VvdXMgb3JkZXJpbmcgd2UgZGV0ZXJtaW5pc3RpY2FsbHkgY2hvb3NlIHRvIHBsYWNlIHRoZSBuZXh0IHJlbmRlcidzXG4vLyBpdGVtIGFmdGVyIHRoZSBwcmV2aW91cyc7IHNvIGMgYWZ0ZXIgYVxuXG4vLyB0aGlzIGlzIGNhbGxlZCBhIHRvcG9sb2dpY2FsIHNvcnRpbmcuIEV4Y2VwdCB0aGUgZXhpc3RpbmcgYWxnb3JpdGhtcyBkb24ndFxuLy8gd29yayB3ZWxsIHdpdGgganMgYmMgb2YgdGhlIGFtb3VudCBvZiBhbGxvY2F0aW9uLCBhbmQgaXNuJ3Qgb3B0aW1pemVkIGZvciBvdXJcbi8vIGN1cnJlbnQgdXNlLWNhc2UgYmMgdGhlIHJ1bnRpbWUgaXMgbGluZWFyIGluIHRlcm1zIG9mIGVkZ2VzIChzZWUgd2lraSBmb3Jcbi8vIG1lYW5pbmcpLCB3aGljaCBpcyBodWdlIHdoZW4gdHdvIGxpc3RzIGhhdmUgbWFueSBjb21tb24gZWxlbWVudHNcbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IG1lcmdlRGlmZjtcblxuZnVuY3Rpb24gbWVyZ2VEaWZmKHByZXYsIG5leHQsIG9uUmVtb3ZlKSB7XG4gIC8vIGJvb2trZWVwaW5nIGZvciBlYXNpZXIgYWNjZXNzIG9mIGEga2V5J3MgaW5kZXggYmVsb3cuIFRoaXMgaXMgMiBhbGxvY2F0aW9ucyArXG4gIC8vIHBvdGVudGlhbGx5IHRyaWdnZXJpbmcgY2hyb21lIGhhc2ggbWFwIG1vZGUgZm9yIG9ianMgKHNvIGl0IG1pZ2h0IGJlIGZhc3RlclxuXG4gIHZhciBwcmV2S2V5SW5kZXggPSB7fTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmV2Lmxlbmd0aDsgaSsrKSB7XG4gICAgcHJldktleUluZGV4W3ByZXZbaV0ua2V5XSA9IGk7XG4gIH1cbiAgdmFyIG5leHRLZXlJbmRleCA9IHt9O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG5leHQubGVuZ3RoOyBpKyspIHtcbiAgICBuZXh0S2V5SW5kZXhbbmV4dFtpXS5rZXldID0gaTtcbiAgfVxuXG4gIC8vIGZpcnN0LCBhbiBvdmVybHkgZWxhYm9yYXRlIHdheSBvZiBtZXJnaW5nIHByZXYgYW5kIG5leHQsIGVsaW1pbmF0aW5nXG4gIC8vIGR1cGxpY2F0ZXMgKGluIHRlcm1zIG9mIGtleXMpLiBJZiB0aGVyZSdzIGR1cGUsIGtlZXAgdGhlIGl0ZW0gaW4gbmV4dCkuXG4gIC8vIFRoaXMgd2F5IG9mIHdyaXRpbmcgaXQgc2F2ZXMgYWxsb2NhdGlvbnNcbiAgdmFyIHJldCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG5leHQubGVuZ3RoOyBpKyspIHtcbiAgICByZXRbaV0gPSBuZXh0W2ldO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJldi5sZW5ndGg7IGkrKykge1xuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5leHRLZXlJbmRleCwgcHJldltpXS5rZXkpKSB7XG4gICAgICAvLyB0aGlzIGlzIGNhbGxlZCBteSBUTSdzIGBtZXJnZUFuZFN5bmNgLCB3aGljaCBjYWxscyB3aWxsTGVhdmUuIFdlIGRvbid0XG4gICAgICAvLyBtZXJnZSBpbiBrZXlzIHRoYXQgdGhlIHVzZXIgZGVzaXJlcyB0byBraWxsXG4gICAgICB2YXIgZmlsbCA9IG9uUmVtb3ZlKGksIHByZXZbaV0pO1xuICAgICAgaWYgKGZpbGwgIT0gbnVsbCkge1xuICAgICAgICByZXQucHVzaChmaWxsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBub3cgYWxsIHRoZSBpdGVtcyBhbGwgcHJlc2VudC4gQ29yZSBzb3J0aW5nIGxvZ2ljIHRvIGhhdmUgdGhlIHJpZ2h0IG9yZGVyXG4gIHJldHVybiByZXQuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHZhciBuZXh0T3JkZXJBID0gbmV4dEtleUluZGV4W2Eua2V5XTtcbiAgICB2YXIgbmV4dE9yZGVyQiA9IG5leHRLZXlJbmRleFtiLmtleV07XG4gICAgdmFyIHByZXZPcmRlckEgPSBwcmV2S2V5SW5kZXhbYS5rZXldO1xuICAgIHZhciBwcmV2T3JkZXJCID0gcHJldktleUluZGV4W2Iua2V5XTtcblxuICAgIGlmIChuZXh0T3JkZXJBICE9IG51bGwgJiYgbmV4dE9yZGVyQiAhPSBudWxsKSB7XG4gICAgICAvLyBib3RoIGtleXMgaW4gbmV4dFxuICAgICAgcmV0dXJuIG5leHRLZXlJbmRleFthLmtleV0gLSBuZXh0S2V5SW5kZXhbYi5rZXldO1xuICAgIH0gZWxzZSBpZiAocHJldk9yZGVyQSAhPSBudWxsICYmIHByZXZPcmRlckIgIT0gbnVsbCkge1xuICAgICAgLy8gYm90aCBrZXlzIGluIHByZXZcbiAgICAgIHJldHVybiBwcmV2S2V5SW5kZXhbYS5rZXldIC0gcHJldktleUluZGV4W2Iua2V5XTtcbiAgICB9IGVsc2UgaWYgKG5leHRPcmRlckEgIT0gbnVsbCkge1xuICAgICAgLy8ga2V5IGEgaW4gbmV4dCwga2V5IGIgaW4gcHJldlxuXG4gICAgICAvLyBob3cgdG8gZGV0ZXJtaW5lIHRoZSBvcmRlciBiZXR3ZWVuIGEgYW5kIGI/IFdlIGZpbmQgYSBcInBpdm90XCIgKHRlcm1cbiAgICAgIC8vIGFidXNlKSwgYSBrZXkgcHJlc2VudCBpbiBib3RoIHByZXYgYW5kIG5leHQsIHRoYXQgaXMgc2FuZHdpY2hlZCBiZXR3ZWVuXG4gICAgICAvLyBhIGFuZCBiLiBJbiB0aGUgY29udGV4dCBvZiBvdXIgYWJvdmUgZXhhbXBsZSwgaWYgd2UncmUgY29tcGFyaW5nIGEgYW5kXG4gICAgICAvLyBkLCBiJ3MgKHRoZSBvbmx5KSBwaXZvdFxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwaXZvdCA9IG5leHRbaV0ua2V5O1xuICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwcmV2S2V5SW5kZXgsIHBpdm90KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5leHRPcmRlckEgPCBuZXh0S2V5SW5kZXhbcGl2b3RdICYmIHByZXZPcmRlckIgPiBwcmV2S2V5SW5kZXhbcGl2b3RdKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9IGVsc2UgaWYgKG5leHRPcmRlckEgPiBuZXh0S2V5SW5kZXhbcGl2b3RdICYmIHByZXZPcmRlckIgPCBwcmV2S2V5SW5kZXhbcGl2b3RdKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIHBsdWdnYWJsZS4gZGVmYXVsdCB0bzogbmV4dCBiaWdnZXIgdGhhbiBwcmV2XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgLy8gcHJldk9yZGVyQSwgbmV4dE9yZGVyQlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbmV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHBpdm90ID0gbmV4dFtpXS5rZXk7XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwcmV2S2V5SW5kZXgsIHBpdm90KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0T3JkZXJCIDwgbmV4dEtleUluZGV4W3Bpdm90XSAmJiBwcmV2T3JkZXJBID4gcHJldktleUluZGV4W3Bpdm90XSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0gZWxzZSBpZiAobmV4dE9yZGVyQiA+IG5leHRLZXlJbmRleFtwaXZvdF0gJiYgcHJldk9yZGVyQSA8IHByZXZLZXlJbmRleFtwaXZvdF0pIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBwbHVnZ2FibGUuIGRlZmF1bHQgdG86IG5leHQgYmlnZ2VyIHRoYW4gcHJldlxuICAgIHJldHVybiAtMTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuLy8gdG8gbG9vcCB0aHJvdWdoIGFuZCBmaW5kIGEga2V5J3MgaW5kZXggZWFjaCB0aW1lKSwgYnV0IEkgbm8gbG9uZ2VyIGNhcmVcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhY3QtbW90aW9uL2xpYi9tZXJnZURpZmYuanNcbi8vIG1vZHVsZSBpZCA9IDIzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gc3ByaW5nO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfcHJlc2V0cyA9IHJlcXVpcmUoJy4vcHJlc2V0cycpO1xuXG52YXIgX3ByZXNldHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcHJlc2V0cyk7XG5cbnZhciBkZWZhdWx0Q29uZmlnID0gX2V4dGVuZHMoe30sIF9wcmVzZXRzMlsnZGVmYXVsdCddLm5vV29iYmxlLCB7XG4gIHByZWNpc2lvbjogMC4wMVxufSk7XG5cbmZ1bmN0aW9uIHNwcmluZyh2YWwsIGNvbmZpZykge1xuICByZXR1cm4gX2V4dGVuZHMoe30sIGRlZmF1bHRDb25maWcsIGNvbmZpZywgeyB2YWw6IHZhbCB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L3JlYWN0LW1vdGlvbi9saWIvc3ByaW5nLmpzXG4vLyBtb2R1bGUgaWQgPSAyNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0ge1xuICBub1dvYmJsZTogeyBzdGlmZm5lc3M6IDE3MCwgZGFtcGluZzogMjYgfSwgLy8gdGhlIGRlZmF1bHQsIGlmIG5vdGhpbmcgcHJvdmlkZWRcbiAgZ2VudGxlOiB7IHN0aWZmbmVzczogMTIwLCBkYW1waW5nOiAxNCB9LFxuICB3b2JibHk6IHsgc3RpZmZuZXNzOiAxODAsIGRhbXBpbmc6IDEyIH0sXG4gIHN0aWZmOiB7IHN0aWZmbmVzczogMjEwLCBkYW1waW5nOiAyMCB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhY3QtbW90aW9uL2xpYi9wcmVzZXRzLmpzXG4vLyBtb2R1bGUgaWQgPSAyNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzWydkZWZhdWx0J10gPSByZW9yZGVyS2V5cztcblxudmFyIGhhc1dhcm5lZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiByZW9yZGVyS2V5cygpIHtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnZGV2ZWxvcG1lbnQnKSB7XG4gICAgaWYgKCFoYXNXYXJuZWQpIHtcbiAgICAgIGhhc1dhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCdgcmVvcmRlcktleXNgIGhhcyBiZWVuIHJlbW92ZWQsIHNpbmNlIGl0IGlzIG5vIGxvbmdlciBuZWVkZWQgZm9yIFRyYW5zaXRpb25Nb3Rpb25cXCdzIG5ldyBzdHlsZXMgYXJyYXkgQVBJLicpO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vcmVhY3QtbW90aW9uL2xpYi9yZW9yZGVyS2V5cy5qc1xuLy8gbW9kdWxlIGlkID0gMjZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY29uc3QgcmVhY3QxMyA9IGlzUmVhY3QxMyhSZWFjdCk7XG52YXIgZGlkV2FybkFib3V0Q2hpbGQgPSBmYWxzZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRET01Ob2RlKGNvbXBvbmVudCl7XG4gICAgaWYoIXJlYWN0MTMpe1xuICAgICAgICByZXR1cm4gY29tcG9uZW50O1xuICAgIH1lbHNle1xuICAgICAgICByZXR1cm4gUmVhY3QuZmluZERPTU5vZGUoY29tcG9uZW50KTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3YXJuQWJvdXRGdW5jdGlvbkNoaWxkKCkge1xuICAgIGlmIChkaWRXYXJuQWJvdXRDaGlsZCB8fCByZWFjdDEzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkFib3V0Q2hpbGQgPSB0cnVlO1xuICAgIGNvbnNvbGUuZXJyb3IoJ1dpdGggUmVhY3QgMC4xNCBhbmQgbGF0ZXIgdmVyc2lvbnMsIHlvdSBubyBsb25nZXIgbmVlZCB0byB3cmFwIDxTY3JvbGxBcmVhPiBjaGlsZCBpbnRvIGEgZnVuY3Rpb24uJyk7XG4gIH1cblxuZXhwb3J0IGZ1bmN0aW9uIHdhcm5BYm91dEVsZW1lbnRDaGlsZCgpIHtcbiAgICBpZiAoZGlkV2FybkFib3V0Q2hpbGQgfHwgIXJlYWN0MTMpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkFib3V0Q2hpbGQgPSB0cnVlO1xuICAgIGNvbnNvbGUuZXJyb3IoICdXaXRoIFJlYWN0IDAuMTMsIHlvdSBuZWVkIHRvIHdyYXAgPFNjcm9sbEFyZWE+IGNoaWxkIGludG8gYSBmdW5jdGlvbi4nICk7XG4gIH1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlT3JaZXJvKG51bWJlcil7XG4gICAgcmV0dXJuIG51bWJlciA8IDAgPyAwIDogbnVtYmVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbW9kaWZ5T2JqVmFsdWVzIChvYmosIG1vZGlmaWVyID0geCA9PiB4KXtcbiAgICBsZXQgbW9kaWZpZWRPYmogPSB7fTtcbiAgICBmb3IobGV0IGtleSBpbiBvYmope1xuICAgICAgICBpZihvYmouaGFzT3duUHJvcGVydHkoa2V5KSkgbW9kaWZpZWRPYmpba2V5XSA9IG1vZGlmaWVyKG9ialtrZXldKTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIG1vZGlmaWVkT2JqO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWFjdDEzKFJlYWN0KSB7XG4gICAgY29uc3QgeyB2ZXJzaW9uIH0gPSBSZWFjdDtcbiAgICBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnRzID0gdmVyc2lvbi5zcGxpdCgnLicpO1xuICAgIGNvbnN0IG1ham9yID0gcGFyc2VJbnQocGFydHNbMF0sIDEwKTtcbiAgICBjb25zdCBtaW5vciA9IHBhcnNlSW50KHBhcnRzWzFdLCAxMCk7XG5cbiAgICByZXR1cm4gbWFqb3IgPT09IDAgJiYgbWlub3IgPT09IDEzO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2pzL3V0aWxzLmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgeyBNb3Rpb24sIHNwcmluZyB9IGZyb20gJ3JlYWN0LW1vdGlvbic7XG5pbXBvcnQgeyBtb2RpZnlPYmpWYWx1ZXMgfSBmcm9tICcuL3V0aWxzJztcblxuY2xhc3MgU2Nyb2xsQmFyIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3Rvcihwcm9wcyl7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcbiAgICAgICAgbGV0IG5ld1N0YXRlID0gdGhpcy5jYWxjdWxhdGVTdGF0ZShwcm9wcyk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBwb3NpdGlvbjogbmV3U3RhdGUucG9zaXRpb24sXG4gICAgICAgICAgICBzY3JvbGxTaXplOiBuZXdTdGF0ZS5zY3JvbGxTaXplLFxuICAgICAgICAgICAgaXNEcmFnZ2luZzogZmFsc2UsXG4gICAgICAgICAgICBsYXN0Q2xpZW50UG9zaXRpb246IDBcbiAgICAgICAgfTtcblxuICAgICAgICBpZihwcm9wcy50eXBlID09PSAndmVydGljYWwnKXtcbiAgICAgICAgICAgIHRoaXMuYmluZGVkSGFuZGxlTW91c2VNb3ZlID0gdGhpcy5oYW5kbGVNb3VzZU1vdmVGb3JWZXJ0aWNhbC5iaW5kKHRoaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5iaW5kZWRIYW5kbGVNb3VzZU1vdmUgPSB0aGlzLmhhbmRsZU1vdXNlTW92ZUZvckhvcml6b250YWwuYmluZCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYmluZGVkSGFuZGxlTW91c2VVcCA9IHRoaXMuaGFuZGxlTW91c2VVcC5iaW5kKHRoaXMpO1xuICAgIH1cblxuICAgIGNvbXBvbmVudERpZE1vdW50KCl7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm93bmVyRG9jdW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIHRoaXMuYmluZGVkSGFuZGxlTW91c2VNb3ZlKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLmJpbmRlZEhhbmRsZU1vdXNlVXApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpe1xuICAgICAgICB0aGlzLnNldFN0YXRlKHRoaXMuY2FsY3VsYXRlU3RhdGUobmV4dFByb3BzKSk7XG4gICAgfVxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKXtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub3duZXJEb2N1bWVudCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vd25lckRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdGhpcy5iaW5kZWRIYW5kbGVNb3VzZU1vdmUpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vd25lckRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuYmluZGVkSGFuZGxlTW91c2VVcCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYWxjdWxhdGVGcmFjdGlvbmFsUG9zaXRpb24ocmVhbENvbnRlbnRTaXplLCBjb250YWluZXJTaXplLCBjb250ZW50UG9zaXRpb24pe1xuICAgICAgICBsZXQgcmVsYXRpdmVTaXplID0gcmVhbENvbnRlbnRTaXplIC0gY29udGFpbmVyU2l6ZTtcblxuICAgICAgICByZXR1cm4gMSAtICgocmVsYXRpdmVTaXplIC0gY29udGVudFBvc2l0aW9uKSAvIHJlbGF0aXZlU2l6ZSk7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlU3RhdGUocHJvcHMpe1xuICAgICAgICBsZXQgZnJhY3Rpb25hbFBvc2l0aW9uID0gdGhpcy5jYWxjdWxhdGVGcmFjdGlvbmFsUG9zaXRpb24ocHJvcHMucmVhbFNpemUsIHByb3BzLmNvbnRhaW5lclNpemUsIHByb3BzLnBvc2l0aW9uKTtcbiAgICAgICAgbGV0IHByb3BvcnRpb25hbFRvUGFnZVNjcm9sbFNpemUgPSBwcm9wcy5jb250YWluZXJTaXplICogcHJvcHMuY29udGFpbmVyU2l6ZSAvIHByb3BzLnJlYWxTaXplO1xuICAgICAgICBsZXQgc2Nyb2xsU2l6ZSA9IHByb3BvcnRpb25hbFRvUGFnZVNjcm9sbFNpemUgPCBwcm9wcy5taW5TY3JvbGxTaXplID8gcHJvcHMubWluU2Nyb2xsU2l6ZSA6IHByb3BvcnRpb25hbFRvUGFnZVNjcm9sbFNpemU7XG5cbiAgICAgICAgbGV0IHNjcm9sbFBvc2l0aW9uID0gKHByb3BzLmNvbnRhaW5lclNpemUgLSBzY3JvbGxTaXplKSAqIGZyYWN0aW9uYWxQb3NpdGlvbjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNjcm9sbFNpemU6IHNjcm9sbFNpemUsXG4gICAgICAgICAgICBwb3NpdGlvbjogTWF0aC5yb3VuZChzY3JvbGxQb3NpdGlvbilcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZW5kZXIoKXtcbiAgICAgICAgbGV0IHtzbW9vdGhTY3JvbGxpbmcsIGlzRHJhZ2dpbmcsIHR5cGUsIHNjcm9sbGJhclN0eWxlLCBjb250YWluZXJTdHlsZX0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgaXNWb3JpemlvbnRhbCA9IHR5cGUgPT09ICdob3Jpem9udGFsJztcbiAgICAgICAgbGV0IGlzVmVydGljYWwgPSB0eXBlID09PSAndmVydGljYWwnO1xuICAgICAgICBsZXQgc2Nyb2xsU3R5bGVzID0gdGhpcy5jcmVhdGVTY3JvbGxTdHlsZXMoKTtcbiAgICAgICAgbGV0IHNwcmluZ2lmaWVkU2Nyb2xsU3R5bGVzID0gc21vb3RoU2Nyb2xsaW5nID8gbW9kaWZ5T2JqVmFsdWVzKHNjcm9sbFN0eWxlcywgeCA9PiBzcHJpbmcoeCkpIDogc2Nyb2xsU3R5bGVzO1xuXG4gICAgICAgIGxldCBzY3JvbGxiYXJDbGFzc2VzID0gYHNjcm9sbGJhci1jb250YWluZXIgJHtpc0RyYWdnaW5nID8gJ2FjdGl2ZScgOiAnJ30gJHtpc1Zvcml6aW9udGFsID8gJ2hvcml6b250YWwnIDogJyd9ICR7aXNWZXJ0aWNhbCA/ICd2ZXJ0aWNhbCcgOiAnJ31gO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8TW90aW9uIHN0eWxlPXtzcHJpbmdpZmllZFNjcm9sbFN0eWxlc30+XG4gICAgICAgICAgICAgICAgeyBzdHlsZSA9PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e3Njcm9sbGJhckNsYXNzZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT17Y29udGFpbmVyU3R5bGV9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbk1vdXNlRG93bj17dGhpcy5oYW5kbGVTY3JvbGxCYXJDb250YWluZXJDbGljay5iaW5kKHRoaXMpfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmPXsgeCA9PiB0aGlzLnNjcm9sbGJhckNvbnRhaW5lciA9IHggfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwic2Nyb2xsYmFyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZT17eyAuLi5zY3JvbGxiYXJTdHlsZSwgLi4uc3R5bGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbk1vdXNlRG93bj17dGhpcy5oYW5kbGVNb3VzZURvd24uYmluZCh0aGlzKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvTW90aW9uPlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGhhbmRsZVNjcm9sbEJhckNvbnRhaW5lckNsaWNrKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBsZXQgbXVsdGlwbGllciA9IHRoaXMuY29tcHV0ZU11bHRpcGxpZXIoKTtcbiAgICAgICAgbGV0IGNsaWVudFBvc2l0aW9uID0gdGhpcy5pc1ZlcnRpY2FsKCkgPyBlLmNsaWVudFkgOiBlLmNsaWVudFg7XG4gICAgICAgIGxldCB7IHRvcCwgbGVmdCB9ID0gdGhpcy5zY3JvbGxiYXJDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGxldCBjbGllbnRTY3JvbGxQb3NpdGlvbiA9IHRoaXMuaXNWZXJ0aWNhbCgpID8gdG9wIDogbGVmdDtcblxuICAgICAgICBsZXQgcG9zaXRpb24gPSBjbGllbnRQb3NpdGlvbiAtIGNsaWVudFNjcm9sbFBvc2l0aW9uO1xuICAgICAgICBsZXQgcHJvcG9ydGlvbmFsVG9QYWdlU2Nyb2xsU2l6ZSA9IHRoaXMucHJvcHMuY29udGFpbmVyU2l6ZSAqIHRoaXMucHJvcHMuY29udGFpbmVyU2l6ZSAvIHRoaXMucHJvcHMucmVhbFNpemU7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7aXNEcmFnZ2luZzogdHJ1ZSwgbGFzdENsaWVudFBvc2l0aW9uOiBjbGllbnRQb3NpdGlvbiB9KTtcbiAgICAgICAgdGhpcy5wcm9wcy5vblBvc2l0aW9uQ2hhbmdlKChwb3NpdGlvbiAtIHByb3BvcnRpb25hbFRvUGFnZVNjcm9sbFNpemUgLyAyKSAvIG11bHRpcGxpZXIpO1xuICAgIH1cblxuICAgIGhhbmRsZU1vdXNlTW92ZUZvckhvcml6b250YWwoZSl7XG4gICAgICAgIGxldCBtdWx0aXBsaWVyID0gdGhpcy5jb21wdXRlTXVsdGlwbGllcigpO1xuXG4gICAgICAgIGlmKHRoaXMuc3RhdGUuaXNEcmFnZ2luZyl7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBsZXQgZGVsdGFYID0gdGhpcy5zdGF0ZS5sYXN0Q2xpZW50UG9zaXRpb24gLSBlLmNsaWVudFg7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbGFzdENsaWVudFBvc2l0aW9uOiBlLmNsaWVudFggfSk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uTW92ZSgwLCBkZWx0YVggLyBtdWx0aXBsaWVyKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsKGUpe1xuICAgICAgICBsZXQgbXVsdGlwbGllciA9IHRoaXMuY29tcHV0ZU11bHRpcGxpZXIoKTtcblxuICAgICAgICBpZih0aGlzLnN0YXRlLmlzRHJhZ2dpbmcpe1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgbGV0IGRlbHRhWSA9IHRoaXMuc3RhdGUubGFzdENsaWVudFBvc2l0aW9uIC0gZS5jbGllbnRZO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxhc3RDbGllbnRQb3NpdGlvbjogZS5jbGllbnRZIH0pO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk1vdmUoZGVsdGFZIC8gbXVsdGlwbGllciwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoYW5kbGVNb3VzZURvd24oZSl7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgbGV0IGxhc3RDbGllbnRQb3NpdGlvbiA9IHRoaXMuaXNWZXJ0aWNhbCgpID8gZS5jbGllbnRZOiBlLmNsaWVudFg7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6IHRydWUsIGxhc3RDbGllbnRQb3NpdGlvbjogbGFzdENsaWVudFBvc2l0aW9uIH0pO1xuXG4gICAgICAgIHRoaXMucHJvcHMub25Gb2N1cygpO1xuICAgIH1cblxuICAgIGhhbmRsZU1vdXNlVXAoZSl7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlU2Nyb2xsU3R5bGVzKCl7XG4gICAgICAgIGlmKHRoaXMucHJvcHMudHlwZSA9PT0gJ3ZlcnRpY2FsJyl7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGhlaWdodDogdGhpcy5zdGF0ZS5zY3JvbGxTaXplLFxuICAgICAgICAgICAgICAgIG1hcmdpblRvcDogdGhpcy5zdGF0ZS5wb3NpdGlvblxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMuc3RhdGUuc2Nyb2xsU2l6ZSxcbiAgICAgICAgICAgICAgICBtYXJnaW5MZWZ0OiB0aGlzLnN0YXRlLnBvc2l0aW9uXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29tcHV0ZU11bHRpcGxpZXIoKXtcbiAgICAgICAgcmV0dXJuICh0aGlzLnByb3BzLmNvbnRhaW5lclNpemUpIC8gdGhpcy5wcm9wcy5yZWFsU2l6ZTtcbiAgICB9XG5cbiAgICBpc1ZlcnRpY2FsKCl7XG4gICAgICAgcmV0dXJuIHRoaXMucHJvcHMudHlwZSA9PT0gJ3ZlcnRpY2FsJztcbiAgICB9XG59XG5cblNjcm9sbEJhci5wcm9wVHlwZXMgPSB7XG4gICAgb25Nb3ZlOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvblBvc2l0aW9uQ2hhbmdlOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBvbkZvY3VzOiBQcm9wVHlwZXMuZnVuYyxcbiAgICByZWFsU2l6ZTogUHJvcFR5cGVzLm51bWJlcixcbiAgICBjb250YWluZXJTaXplOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIHBvc2l0aW9uOiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIGNvbnRhaW5lclN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIHNjcm9sbGJhclN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIHR5cGU6IFByb3BUeXBlcy5vbmVPZihbJ3ZlcnRpY2FsJywgJ2hvcml6b250YWwnXSksXG4gICAgb3duZXJEb2N1bWVudDogUHJvcFR5cGVzLmFueSxcbiAgICBzbW9vdGhTY3JvbGxpbmc6IFByb3BUeXBlcy5ib29sLFxuICAgIG1pblNjcm9sbFNpemU6IFByb3BUeXBlcy5udW1iZXJcbn07XG5cblNjcm9sbEJhci5kZWZhdWx0UHJvcHMgPSB7XG4gICAgdHlwZSA6ICd2ZXJ0aWNhbCcsXG4gICAgc21vb3RoU2Nyb2xsaW5nOiBmYWxzZSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNjcm9sbEJhcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9qcy9TY3JvbGxiYXIuanN4Il0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/dist/scrollArea.js b/dist/scrollArea.js new file mode 100644 index 0000000..cc98f80 --- /dev/null +++ b/dist/scrollArea.js @@ -0,0 +1,4173 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("react")); + else if(typeof define === 'function' && define.amd) + define(["react"], factory); + else if(typeof exports === 'object') + exports["ScrollArea"] = factory(require("react")); + else + root["ScrollArea"] = factory(root["React"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_6__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + __webpack_require__(1); + + var _ScrollArea = __webpack_require__(5); + + var _ScrollArea2 = _interopRequireDefault(_ScrollArea); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + exports.default = _ScrollArea2.default; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + // style-loader: Adds some css to the DOM by adding a