1
|
(()=>{var __webpack_modules__={382:function(__unused_webpack_module,exports,__webpack_require__){eval("(function (global, factory) {\n true ? factory(exports, __webpack_require__(424), __webpack_require__(690), __webpack_require__(728)) :\n 0;\n})(this, (function (exports, _slicedToArray, _classCallCheck, _createClass) { 'use strict';\n\n var createExtendedExponentialRampToValueAutomationEvent = function createExtendedExponentialRampToValueAutomationEvent(value, endTime, insertTime) {\n return {\n endTime: endTime,\n insertTime: insertTime,\n type: 'exponentialRampToValue',\n value: value\n };\n };\n\n var createExtendedLinearRampToValueAutomationEvent = function createExtendedLinearRampToValueAutomationEvent(value, endTime, insertTime) {\n return {\n endTime: endTime,\n insertTime: insertTime,\n type: 'linearRampToValue',\n value: value\n };\n };\n\n var createSetValueAutomationEvent = function createSetValueAutomationEvent(value, startTime) {\n return {\n startTime: startTime,\n type: 'setValue',\n value: value\n };\n };\n\n var createSetValueCurveAutomationEvent = function createSetValueCurveAutomationEvent(values, startTime, duration) {\n return {\n duration: duration,\n startTime: startTime,\n type: 'setValueCurve',\n values: values\n };\n };\n\n var getTargetValueAtTime = function getTargetValueAtTime(time, valueAtStartTime, _ref) {\n var startTime = _ref.startTime,\n target = _ref.target,\n timeConstant = _ref.timeConstant;\n return target + (valueAtStartTime - target) * Math.exp((startTime - time) / timeConstant);\n };\n\n var isExponentialRampToValueAutomationEvent = function isExponentialRampToValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'exponentialRampToValue';\n };\n\n var isLinearRampToValueAutomationEvent = function isLinearRampToValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'linearRampToValue';\n };\n\n var isAnyRampToValueAutomationEvent = function isAnyRampToValueAutomationEvent(automationEvent) {\n return isExponentialRampToValueAutomationEvent(automationEvent) || isLinearRampToValueAutomationEvent(automationEvent);\n };\n\n var isSetValueAutomationEvent = function isSetValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'setValue';\n };\n\n var isSetValueCurveAutomationEvent = function isSetValueCurveAutomationEvent(automationEvent) {\n return automationEvent.type === 'setValueCurve';\n };\n\n var getValueOfAutomationEventAtIndexAtTime = function getValueOfAutomationEventAtIndexAtTime(automationEvents, index, time, defaultValue) {\n var automationEvent = automationEvents[index];\n return automationEvent === undefined ? defaultValue : isAnyRampToValueAutomationEvent(automationEvent) || isSetValueAutomationEvent(automationEvent) ? automationEvent.value : isSetValueCurveAutomationEvent(automationEvent) ? automationEvent.values[automationEvent.values.length - 1] : getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(automationEvents, index - 1, automationEvent.startTime, defaultValue), automationEvent);\n };\n\n var getEndTimeAndValueOfPreviousAutomationEvent = function getEndTimeAndValueOfPreviousAutomationEvent(automationEvents, index, currentAutomationEvent, nextAutomationEvent, defaultValue) {\n return currentAutomationEvent === undefined ? [nextAutomationEvent.insertTime, defaultValue] : isAnyRampToValueAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.endTime, currentAutomationEvent.value] : isSetValueAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.startTime, currentAutomationEvent.value] : isSetValueCurveAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.startTime + currentAutomationEvent.duration, currentAutomationEvent.values[currentAutomationEvent.values.length - 1]] : [currentAutomationEvent.startTime, getValueOfAutomationEventAtIndexAtTime(automationEvents, index - 1, currentAutomationEvent.startTime, defaultValue)];\n };\n\n var isCancelAndHoldAutomationEvent = function isCancelAndHoldAutomationEvent(automationEvent) {\n return automationEvent.type === 'cancelAndHold';\n };\n\n var isCancelScheduledValuesAutomationEvent = function isCancelScheduledValuesAutomationEvent(automationEvent) {\n return automationEvent.type === 'cancelScheduledValues';\n };\n\n var getEventTime = function getEventTime(automationEvent) {\n if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) {\n return automationEvent.cancelTime;\n }\n if (isExponentialRampToValueAutomationEvent(automationEvent) || isLinearRampToValueAutomationEvent(automationEvent)) {\n return automationEvent.endTime;\n }\n return automationEvent.startTime;\n };\n\n var getExponentialRampValueAtTime = function getExponentialRampValueAtTime(time, startTime, valueAtStartTime, _ref) {\n var endTime = _ref.endTime,\n value = _ref.value;\n if (valueAtStartTime === value) {\n return value;\n }\n if (0 < valueAtStartTime && 0 < value || valueAtStartTime < 0 && value < 0) {\n return valueAtStartTime * Math.pow(value / valueAtStartTime, (time - startTime) / (endTime - startTime));\n }\n return 0;\n };\n\n var getLinearRampValueAtTime = function getLinearRampValueAtTime(time, startTime, valueAtStartTime, _ref) {\n var endTime = _ref.endTime,\n value = _ref.value;\n return valueAtStartTime + (time - startTime) / (endTime - startTime) * (value - valueAtStartTime);\n };\n\n var interpolateValue = function interpolateValue(values, theoreticIndex) {\n var lowerIndex = Math.floor(theoreticIndex);\n var upperIndex = Math.ceil(theoreticIndex);\n if (lowerIndex === upperIndex) {\n return values[lowerIndex];\n }\n return (1 - (theoreticIndex - lowerIndex)) * values[lowerIndex] + (1 - (upperIndex - theoreticIndex)) * values[upperIndex];\n };\n\n var getValueCurveValueAtTime = function getValueCurveValueAtTime(time, _ref) {\n var duration = _ref.duration,\n startTime = _ref.startTime,\n values = _ref.values;\n var theoreticIndex = (time - startTime) / duration * (values.length - 1);\n return interpolateValue(values, theoreticIndex);\n };\n\n var isSetTargetAutomationEvent = function isSetTargetAutomationEvent(automationEvent) {\n return automationEvent.type === 'setTarget';\n };\n\n var AutomationEventList = /*#__PURE__*/function (_Symbol$iterator) {\n function AutomationEventList(defaultValue) {\n _classCallCheck(this, AutomationEventList);\n this._automationEvents = [];\n this._currenTime = 0;\n this._defaultValue = defaultValue;\n }\n _createClass(AutomationEventList, [{\n key: _Symbol$iterator,\n value: function value() {\n return this._automationEvents[Symbol.iterator]();\n }\n }, {\n key: \"add\",\n value: function add(automationEvent) {\n var eventTime = getEventTime(automationEvent);\n if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) {\n var index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n if (isCancelScheduledValuesAutomationEvent(automationEvent) && isSetValueCurveAutomationEvent(currentAutomationEvent)) {\n return currentAutomationEvent.startTime + currentAutomationEvent.duration >= eventTime;\n }\n return getEventTime(currentAutomationEvent) >= eventTime;\n });\n var removedAutomationEvent = this._automationEvents[index];\n if (index !== -1) {\n this._automationEvents = this._automationEvents.slice(0, index);\n }\n if (isCancelAndHoldAutomationEvent(automationEvent)) {\n var lastAutomationEvent = this._automationEvents[this._automationEvents.length - 1];\n if (removedAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(removedAutomationEvent)) {\n if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) {\n throw new Error('The internal list is malformed.');\n }\n var startTime = lastAutomationEvent === undefined ? removedAutomationEvent.insertTime : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.startTime + lastAutomationEvent.duration : getEventTime(lastAutomationEvent);\n var startValue = lastAutomationEvent === undefined ? this._defaultValue : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.values[lastAutomationEvent.values.length - 1] : lastAutomationEvent.value;\n var value = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? getExponentialRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent) : getLinearRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent);\n var truncatedAutomationEvent = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? createExtendedExponentialRampToValueAutomationEvent(value, eventTime, this._currenTime) : createExtendedLinearRampToValueAutomationEvent(value, eventTime, this._currenTime);\n this._automationEvents.push(truncatedAutomationEvent);\n }\n if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) {\n this._automationEvents.push(createSetValueAutomationEvent(this.getValue(eventTime), eventTime));\n }\n if (lastAutomationEvent !== undefined && isSetValueCurveAutomationEvent(lastAutomationEvent) && lastAutomationEvent.startTime + lastAutomationEvent.duration > eventTime) {\n var duration = eventTime - lastAutomationEvent.startTime;\n var ratio = (lastAutomationEvent.values.length - 1) / lastAutomationEvent.duration;\n var length = Math.max(2, 1 + Math.ceil(duration * ratio));\n var fraction = duration / (length - 1) * ratio;\n var values = lastAutomationEvent.values.slice(0, length);\n if (fraction < 1) {\n for (var i = 1; i < length; i += 1) {\n var factor = fraction * i % 1;\n values[i] = lastAutomationEvent.values[i - 1] * (1 - factor) + lastAutomationEvent.values[i] * factor;\n }\n }\n this._automationEvents[this._automationEvents.length - 1] = createSetValueCurveAutomationEvent(values, lastAutomationEvent.startTime, duration);\n }\n }\n } else {\n var _index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n return getEventTime(currentAutomationEvent) > eventTime;\n });\n var previousAutomationEvent = _index === -1 ? this._automationEvents[this._automationEvents.length - 1] : this._automationEvents[_index - 1];\n if (previousAutomationEvent !== undefined && isSetValueCurveAutomationEvent(previousAutomationEvent) && getEventTime(previousAutomationEvent) + previousAutomationEvent.duration > eventTime) {\n return false;\n }\n var persistentAutomationEvent = isExponentialRampToValueAutomationEvent(automationEvent) ? createExtendedExponentialRampToValueAutomationEvent(automationEvent.value, automationEvent.endTime, this._currenTime) : isLinearRampToValueAutomationEvent(automationEvent) ? createExtendedLinearRampToValueAutomationEvent(automationEvent.value, eventTime, this._currenTime) : automationEvent;\n if (_index === -1) {\n this._automationEvents.push(persistentAutomationEvent);\n } else {\n if (isSetValueCurveAutomationEvent(automationEvent) && eventTime + automationEvent.duration > getEventTime(this._automationEvents[_index])) {\n return false;\n }\n this._automationEvents.splice(_index, 0, persistentAutomationEvent);\n }\n }\n return true;\n }\n }, {\n key: \"flush\",\n value: function flush(time) {\n var index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n return getEventTime(currentAutomationEvent) > time;\n });\n if (index > 1) {\n var remainingAutomationEvents = this._automationEvents.slice(index - 1);\n var firstRemainingAutomationEvent = remainingAutomationEvents[0];\n if (isSetTargetAutomationEvent(firstRemainingAutomationEvent)) {\n remainingAutomationEvents.unshift(createSetValueAutomationEvent(getValueOfAutomationEventAtIndexAtTime(this._automationEvents, index - 2, firstRemainingAutomationEvent.startTime, this._defaultValue), firstRemainingAutomationEvent.startTime));\n }\n this._automationEvents = remainingAutomationEvents;\n }\n }\n }, {\n key: \"getValue\",\n value: function getValue(time) {\n if (this._automationEvents.length === 0) {\n return this._defaultValue;\n }\n var indexOfNextEvent = this._automationEvents.findIndex(function (automationEvent) {\n return getEventTime(automationEvent) > time;\n });\n var nextAutomationEvent = this._automationEvents[indexOfNextEvent];\n var indexOfCurrentEvent = (indexOfNextEvent === -1 ? this._automationEvents.length : indexOfNextEvent) - 1;\n var currentAutomationEvent = this._automationEvents[indexOfCurrentEvent];\n if (currentAutomationEvent !== undefined && isSetTargetAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || nextAutomationEvent.insertTime > time)) {\n return getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(this._automationEvents, indexOfCurrentEvent - 1, currentAutomationEvent.startTime, this._defaultValue), currentAutomationEvent);\n }\n if (currentAutomationEvent !== undefined && isSetValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) {\n return currentAutomationEvent.value;\n }\n if (currentAutomationEvent !== undefined && isSetValueCurveAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || currentAutomationEvent.startTime + currentAutomationEvent.duration > time)) {\n if (time < currentAutomationEvent.startTime + currentAutomationEvent.duration) {\n return getValueCurveValueAtTime(time, currentAutomationEvent);\n }\n return currentAutomationEvent.values[currentAutomationEvent.values.length - 1];\n }\n if (currentAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) {\n return currentAutomationEvent.value;\n }\n if (nextAutomationEvent !== undefined && isExponentialRampToValueAutomationEvent(nextAutomationEvent)) {\n var _getEndTimeAndValueOf = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue),\n _getEndTimeAndValueOf2 = _slicedToArray(_getEndTimeAndValueOf, 2),\n startTime = _getEndTimeAndValueOf2[0],\n value = _getEndTimeAndValueOf2[1];\n return getExponentialRampValueAtTime(time, startTime, value, nextAutomationEvent);\n }\n if (nextAutomationEvent !== undefined && isLinearRampToValueAutomationEvent(nextAutomationEvent)) {\n var _getEndTimeAndValueOf3 = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue),\n _getEndTimeAndValueOf4 = _slicedToArray(_getEndTimeAndValueOf3, 2),\n _startTime = _getEndTimeAndValueOf4[0],\n _value = _getEndTimeAndValueOf4[1];\n return getLinearRampValueAtTime(time, _startTime, _value, nextAutomationEvent);\n }\n return this._defaultValue;\n }\n }]);\n return AutomationEventList;\n }(Symbol.iterator);\n\n var createCancelAndHoldAutomationEvent = function createCancelAndHoldAutomationEvent(cancelTime) {\n return {\n cancelTime: cancelTime,\n type: 'cancelAndHold'\n };\n };\n\n var createCancelScheduledValuesAutomationEvent = function createCancelScheduledValuesAutomationEvent(cancelTime) {\n return {\n cancelTime: cancelTime,\n type: 'cancelScheduledValues'\n };\n };\n\n var createExponentialRampToValueAutomationEvent = function createExponentialRampToValueAutomationEvent(value, endTime) {\n return {\n endTime: endTime,\n type: 'exponentialRampToValue',\n value: value\n };\n };\n\n var createLinearRampToValueAutomationEvent = function createLinearRampToValueAutomationEvent(value, endTime) {\n return {\n endTime: endTime,\n type: 'linearRampToValue',\n value: value\n };\n };\n\n var createSetTargetAutomationEvent = function createSetTargetAutomationEvent(target, startTime, timeConstant) {\n return {\n startTime: startTime,\n target: target,\n timeConstant: timeConstant,\n type: 'setTarget'\n };\n };\n\n exports.AutomationEventList = AutomationEventList;\n exports.createCancelAndHoldAutomationEvent = createCancelAndHoldAutomationEvent;\n exports.createCancelScheduledValuesAutomationEvent = createCancelScheduledValuesAutomationEvent;\n exports.createExponentialRampToValueAutomationEvent = createExponentialRampToValueAutomationEvent;\n exports.createLinearRampToValueAutomationEvent = createLinearRampToValueAutomationEvent;\n exports.createSetTargetAutomationEvent = createSetTargetAutomationEvent;\n exports.createSetValueAutomationEvent = createSetValueAutomationEvent;\n exports.createSetValueCurveAutomationEvent = createSetValueCurveAutomationEvent;\n\n}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzgyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0EsSUFBSSxLQUE0RCxvQkFBb0IsbUJBQU8sQ0FBQyxHQUFzQyxHQUFHLG1CQUFPLENBQUMsR0FBdUMsR0FBRyxtQkFBTyxDQUFDLEdBQW9DO0FBQ25PLElBQUksQ0FDcUw7QUFDekwsQ0FBQyw2RUFBNkU7O0FBRTlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFlBQVk7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9hdXRvbWF0aW9uLWV2ZW50cy9idWlsZC9lczUvYnVuZGxlLmpzPzA0ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMsIHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvc2xpY2VkVG9BcnJheScpLCByZXF1aXJlKCdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrJyksIHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3MnKSkgOlxuICAgIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnLCAnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5JywgJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2snLCAnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcyddLCBmYWN0b3J5KSA6XG4gICAgKGdsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwuYXV0b21hdGlvbkV2ZW50cyA9IHt9LCBnbG9iYWwuX3NsaWNlZFRvQXJyYXksIGdsb2JhbC5fY2xhc3NDYWxsQ2hlY2ssIGdsb2JhbC5fY3JlYXRlQ2xhc3MpKTtcbn0pKHRoaXMsIChmdW5jdGlvbiAoZXhwb3J0cywgX3NsaWNlZFRvQXJyYXksIF9jbGFzc0NhbGxDaGVjaywgX2NyZWF0ZUNsYXNzKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBjcmVhdGVFeHRlbmRlZEV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVFeHRlbmRlZEV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUsIGluc2VydFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgIGluc2VydFRpbWU6IGluc2VydFRpbWUsXG4gICAgICAgIHR5cGU6ICdleHBvbmVudGlhbFJhbXBUb1ZhbHVlJyxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB2YXIgY3JlYXRlRXh0ZW5kZWRMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGNyZWF0ZUV4dGVuZGVkTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUsIGluc2VydFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgIGluc2VydFRpbWU6IGluc2VydFRpbWUsXG4gICAgICAgIHR5cGU6ICdsaW5lYXJSYW1wVG9WYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIHN0YXJ0VGltZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnRUaW1lOiBzdGFydFRpbWUsXG4gICAgICAgIHR5cGU6ICdzZXRWYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZHVyYXRpb246IGR1cmF0aW9uLFxuICAgICAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICAgICAgdHlwZTogJ3NldFZhbHVlQ3VydmUnLFxuICAgICAgICB2YWx1ZXM6IHZhbHVlc1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGdldFRhcmdldFZhbHVlQXRUaW1lID0gZnVuY3Rpb24gZ2V0VGFyZ2V0VmFsdWVBdFRpbWUodGltZSwgdmFsdWVBdFN0YXJ0VGltZSwgX3JlZikge1xuICAgICAgdmFyIHN0YXJ0VGltZSA9IF9yZWYuc3RhcnRUaW1lLFxuICAgICAgICB0YXJnZXQgPSBfcmVmLnRhcmdldCxcbiAgICAgICAgdGltZUNvbnN0YW50ID0gX3JlZi50aW1lQ29uc3RhbnQ7XG4gICAgICByZXR1cm4gdGFyZ2V0ICsgKHZhbHVlQXRTdGFydFRpbWUgLSB0YXJnZXQpICogTWF0aC5leHAoKHN0YXJ0VGltZSAtIHRpbWUpIC8gdGltZUNvbnN0YW50KTtcbiAgICB9O1xuXG4gICAgdmFyIGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWUnO1xuICAgIH07XG5cbiAgICB2YXIgaXNMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdsaW5lYXJSYW1wVG9WYWx1ZSc7XG4gICAgfTtcblxuICAgIHZhciBpc0FueVJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBpc0V4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSB8fCBpc0xpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCk7XG4gICAgfTtcblxuICAgIHZhciBpc1NldFZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gaXNTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJztcbiAgICB9O1xuXG4gICAgdmFyIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlQ3VydmUnO1xuICAgIH07XG5cbiAgICB2YXIgZ2V0VmFsdWVPZkF1dG9tYXRpb25FdmVudEF0SW5kZXhBdFRpbWUgPSBmdW5jdGlvbiBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZShhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCwgdGltZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICB2YXIgYXV0b21hdGlvbkV2ZW50ID0gYXV0b21hdGlvbkV2ZW50c1tpbmRleF07XG4gICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50ID09PSB1bmRlZmluZWQgPyBkZWZhdWx0VmFsdWUgOiBpc0FueVJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgfHwgaXNTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpID8gYXV0b21hdGlvbkV2ZW50LnZhbHVlIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgPyBhdXRvbWF0aW9uRXZlbnQudmFsdWVzW2F1dG9tYXRpb25FdmVudC52YWx1ZXMubGVuZ3RoIC0gMV0gOiBnZXRUYXJnZXRWYWx1ZUF0VGltZSh0aW1lLCBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZShhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCAtIDEsIGF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIGRlZmF1bHRWYWx1ZSksIGF1dG9tYXRpb25FdmVudCk7XG4gICAgfTtcblxuICAgIHZhciBnZXRFbmRUaW1lQW5kVmFsdWVPZlByZXZpb3VzQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gZ2V0RW5kVGltZUFuZFZhbHVlT2ZQcmV2aW91c0F1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCwgY3VycmVudEF1dG9tYXRpb25FdmVudCwgbmV4dEF1dG9tYXRpb25FdmVudCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICByZXR1cm4gY3VycmVudEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkID8gW25leHRBdXRvbWF0aW9uRXZlbnQuaW5zZXJ0VGltZSwgZGVmYXVsdFZhbHVlXSA6IGlzQW55UmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgPyBbY3VycmVudEF1dG9tYXRpb25FdmVudC5lbmRUaW1lLCBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnZhbHVlXSA6IGlzU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgPyBbY3VycmVudEF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQudmFsdWVdIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpID8gW2N1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgY3VycmVudEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbiwgY3VycmVudEF1dG9tYXRpb25FdmVudC52YWx1ZXNbY3VycmVudEF1dG9tYXRpb25FdmVudC52YWx1ZXMubGVuZ3RoIC0gMV1dIDogW2N1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lLCBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZShhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCAtIDEsIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lLCBkZWZhdWx0VmFsdWUpXTtcbiAgICB9O1xuXG4gICAgdmFyIGlzQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2NhbmNlbEFuZEhvbGQnO1xuICAgIH07XG5cbiAgICB2YXIgaXNDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBpc0NhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2NhbmNlbFNjaGVkdWxlZFZhbHVlcyc7XG4gICAgfTtcblxuICAgIHZhciBnZXRFdmVudFRpbWUgPSBmdW5jdGlvbiBnZXRFdmVudFRpbWUoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICBpZiAoaXNDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgfHwgaXNDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50LmNhbmNlbFRpbWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgfHwgaXNMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpKSB7XG4gICAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQuZW5kVGltZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lO1xuICAgIH07XG5cbiAgICB2YXIgZ2V0RXhwb25lbnRpYWxSYW1wVmFsdWVBdFRpbWUgPSBmdW5jdGlvbiBnZXRFeHBvbmVudGlhbFJhbXBWYWx1ZUF0VGltZSh0aW1lLCBzdGFydFRpbWUsIHZhbHVlQXRTdGFydFRpbWUsIF9yZWYpIHtcbiAgICAgIHZhciBlbmRUaW1lID0gX3JlZi5lbmRUaW1lLFxuICAgICAgICB2YWx1ZSA9IF9yZWYudmFsdWU7XG4gICAgICBpZiAodmFsdWVBdFN0YXJ0VGltZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKDAgPCB2YWx1ZUF0U3RhcnRUaW1lICYmIDAgPCB2YWx1ZSB8fCB2YWx1ZUF0U3RhcnRUaW1lIDwgMCAmJiB2YWx1ZSA8IDApIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlQXRTdGFydFRpbWUgKiBNYXRoLnBvdyh2YWx1ZSAvIHZhbHVlQXRTdGFydFRpbWUsICh0aW1lIC0gc3RhcnRUaW1lKSAvIChlbmRUaW1lIC0gc3RhcnRUaW1lKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9O1xuXG4gICAgdmFyIGdldExpbmVhclJhbXBWYWx1ZUF0VGltZSA9IGZ1bmN0aW9uIGdldExpbmVhclJhbXBWYWx1ZUF0VGltZSh0aW1lLCBzdGFydFRpbWUsIHZhbHVlQXRTdGFydFRpbWUsIF9yZWYpIHtcbiAgICAgIHZhciBlbmRUaW1lID0gX3JlZi5lbmRUaW1lLFxuICAgICAgICB2YWx1ZSA9IF9yZWYudmFsdWU7XG4gICAgICByZXR1cm4gdmFsdWVBdFN0YXJ0VGltZSArICh0aW1lIC0gc3RhcnRUaW1lKSAvIChlbmRUaW1lIC0gc3RhcnRUaW1lKSAqICh2YWx1ZSAtIHZhbHVlQXRTdGFydFRpbWUpO1xuICAgIH07XG5cbiAgICB2YXIgaW50ZXJwb2xhdGVWYWx1ZSA9IGZ1bmN0aW9uIGludGVycG9sYXRlVmFsdWUodmFsdWVzLCB0aGVvcmV0aWNJbmRleCkge1xuICAgICAgdmFyIGxvd2VySW5kZXggPSBNYXRoLmZsb29yKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgIHZhciB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgIGlmIChsb3dlckluZGV4ID09PSB1cHBlckluZGV4KSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXNbbG93ZXJJbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZXNbbG93ZXJJbmRleF0gKyAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIHZhbHVlc1t1cHBlckluZGV4XTtcbiAgICB9O1xuXG4gICAgdmFyIGdldFZhbHVlQ3VydmVWYWx1ZUF0VGltZSA9IGZ1bmN0aW9uIGdldFZhbHVlQ3VydmVWYWx1ZUF0VGltZSh0aW1lLCBfcmVmKSB7XG4gICAgICB2YXIgZHVyYXRpb24gPSBfcmVmLmR1cmF0aW9uLFxuICAgICAgICBzdGFydFRpbWUgPSBfcmVmLnN0YXJ0VGltZSxcbiAgICAgICAgdmFsdWVzID0gX3JlZi52YWx1ZXM7XG4gICAgICB2YXIgdGhlb3JldGljSW5kZXggPSAodGltZSAtIHN0YXJ0VGltZSkgLyBkdXJhdGlvbiAqICh2YWx1ZXMubGVuZ3RoIC0gMSk7XG4gICAgICByZXR1cm4gaW50ZXJwb2xhdGVWYWx1ZSh2YWx1ZXMsIHRoZW9yZXRpY0luZGV4KTtcbiAgICB9O1xuXG4gICAgdmFyIGlzU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gaXNTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRUYXJnZXQnO1xuICAgIH07XG5cbiAgICB2YXIgQXV0b21hdGlvbkV2ZW50TGlzdCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1N5bWJvbCRpdGVyYXRvcikge1xuICAgICAgZnVuY3Rpb24gQXV0b21hdGlvbkV2ZW50TGlzdChkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEF1dG9tYXRpb25FdmVudExpc3QpO1xuICAgICAgICB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzID0gW107XG4gICAgICAgIHRoaXMuX2N1cnJlblRpbWUgPSAwO1xuICAgICAgICB0aGlzLl9kZWZhdWx0VmFsdWUgPSBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgICBfY3JlYXRlQ2xhc3MoQXV0b21hdGlvbkV2ZW50TGlzdCwgW3tcbiAgICAgICAga2V5OiBfU3ltYm9sJGl0ZXJhdG9yLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9tYXRpb25FdmVudHNbU3ltYm9sLml0ZXJhdG9yXSgpO1xuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGtleTogXCJhZGRcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgICAgICB2YXIgZXZlbnRUaW1lID0gZ2V0RXZlbnRUaW1lKGF1dG9tYXRpb25FdmVudCk7XG4gICAgICAgICAgaWYgKGlzQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHx8IGlzQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkpIHtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2F1dG9tYXRpb25FdmVudHMuZmluZEluZGV4KGZ1bmN0aW9uIChjdXJyZW50QXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICAgICAgICAgIGlmIChpc0NhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpICYmIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChjdXJyZW50QXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnN0YXJ0VGltZSArIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuZHVyYXRpb24gPj0gZXZlbnRUaW1lO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBnZXRFdmVudFRpbWUoY3VycmVudEF1dG9tYXRpb25FdmVudCkgPj0gZXZlbnRUaW1lO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcmVtb3ZlZEF1dG9tYXRpb25FdmVudCA9IHRoaXMuX2F1dG9tYXRpb25FdmVudHNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzID0gdGhpcy5fYXV0b21hdGlvbkV2ZW50cy5zbGljZSgwLCBpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkpIHtcbiAgICAgICAgICAgICAgdmFyIGxhc3RBdXRvbWF0aW9uRXZlbnQgPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzW3RoaXMuX2F1dG9tYXRpb25FdmVudHMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgIGlmIChyZW1vdmVkQXV0b21hdGlvbkV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChyZW1vdmVkQXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGlmIChsYXN0QXV0b21hdGlvbkV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaXNTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQobGFzdEF1dG9tYXRpb25FdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGludGVybmFsIGxpc3QgaXMgbWFsZm9ybWVkLicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgc3RhcnRUaW1lID0gbGFzdEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkID8gcmVtb3ZlZEF1dG9tYXRpb25FdmVudC5pbnNlcnRUaW1lIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGxhc3RBdXRvbWF0aW9uRXZlbnQpID8gbGFzdEF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUgKyBsYXN0QXV0b21hdGlvbkV2ZW50LmR1cmF0aW9uIDogZ2V0RXZlbnRUaW1lKGxhc3RBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgICAgICAgIHZhciBzdGFydFZhbHVlID0gbGFzdEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkID8gdGhpcy5fZGVmYXVsdFZhbHVlIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGxhc3RBdXRvbWF0aW9uRXZlbnQpID8gbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXNbbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXMubGVuZ3RoIC0gMV0gOiBsYXN0QXV0b21hdGlvbkV2ZW50LnZhbHVlO1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChyZW1vdmVkQXV0b21hdGlvbkV2ZW50KSA/IGdldEV4cG9uZW50aWFsUmFtcFZhbHVlQXRUaW1lKGV2ZW50VGltZSwgc3RhcnRUaW1lLCBzdGFydFZhbHVlLCByZW1vdmVkQXV0b21hdGlvbkV2ZW50KSA6IGdldExpbmVhclJhbXBWYWx1ZUF0VGltZShldmVudFRpbWUsIHN0YXJ0VGltZSwgc3RhcnRWYWx1ZSwgcmVtb3ZlZEF1dG9tYXRpb25FdmVudCk7XG4gICAgICAgICAgICAgICAgdmFyIHRydW5jYXRlZEF1dG9tYXRpb25FdmVudCA9IGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChyZW1vdmVkQXV0b21hdGlvbkV2ZW50KSA/IGNyZWF0ZUV4dGVuZGVkRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZXZlbnRUaW1lLCB0aGlzLl9jdXJyZW5UaW1lKSA6IGNyZWF0ZUV4dGVuZGVkTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGV2ZW50VGltZSwgdGhpcy5fY3VycmVuVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXV0b21hdGlvbkV2ZW50cy5wdXNoKHRydW5jYXRlZEF1dG9tYXRpb25FdmVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGxhc3RBdXRvbWF0aW9uRXZlbnQgIT09IHVuZGVmaW5lZCAmJiBpc1NldFRhcmdldEF1dG9tYXRpb25FdmVudChsYXN0QXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1dG9tYXRpb25FdmVudHMucHVzaChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCh0aGlzLmdldFZhbHVlKGV2ZW50VGltZSksIGV2ZW50VGltZSkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChsYXN0QXV0b21hdGlvbkV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGxhc3RBdXRvbWF0aW9uRXZlbnQpICYmIGxhc3RBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgbGFzdEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbiA+IGV2ZW50VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbiA9IGV2ZW50VGltZSAtIGxhc3RBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lO1xuICAgICAgICAgICAgICAgIHZhciByYXRpbyA9IChsYXN0QXV0b21hdGlvbkV2ZW50LnZhbHVlcy5sZW5ndGggLSAxKSAvIGxhc3RBdXRvbWF0aW9uRXZlbnQuZHVyYXRpb247XG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IE1hdGgubWF4KDIsIDEgKyBNYXRoLmNlaWwoZHVyYXRpb24gKiByYXRpbykpO1xuICAgICAgICAgICAgICAgIHZhciBmcmFjdGlvbiA9IGR1cmF0aW9uIC8gKGxlbmd0aCAtIDEpICogcmF0aW87XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IGxhc3RBdXRvbWF0aW9uRXZlbnQudmFsdWVzLnNsaWNlKDAsIGxlbmd0aCk7XG4gICAgICAgICAgICAgICAgaWYgKGZyYWN0aW9uIDwgMSkge1xuICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZmFjdG9yID0gZnJhY3Rpb24gKiBpICUgMTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXNbaSAtIDFdICogKDEgLSBmYWN0b3IpICsgbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXNbaV0gKiBmYWN0b3I7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2F1dG9tYXRpb25FdmVudHNbdGhpcy5fYXV0b21hdGlvbkV2ZW50cy5sZW5ndGggLSAxXSA9IGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQodmFsdWVzLCBsYXN0QXV0b21hdGlvbkV2ZW50LnN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBfaW5kZXggPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmZpbmRJbmRleChmdW5jdGlvbiAoY3VycmVudEF1dG9tYXRpb25FdmVudCkge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0RXZlbnRUaW1lKGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpID4gZXZlbnRUaW1lO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcHJldmlvdXNBdXRvbWF0aW9uRXZlbnQgPSBfaW5kZXggPT09IC0xID8gdGhpcy5fYXV0b21hdGlvbkV2ZW50c1t0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmxlbmd0aCAtIDFdIDogdGhpcy5fYXV0b21hdGlvbkV2ZW50c1tfaW5kZXggLSAxXTtcbiAgICAgICAgICAgIGlmIChwcmV2aW91c0F1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChwcmV2aW91c0F1dG9tYXRpb25FdmVudCkgJiYgZ2V0RXZlbnRUaW1lKHByZXZpb3VzQXV0b21hdGlvbkV2ZW50KSArIHByZXZpb3VzQXV0b21hdGlvbkV2ZW50LmR1cmF0aW9uID4gZXZlbnRUaW1lKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwZXJzaXN0ZW50QXV0b21hdGlvbkV2ZW50ID0gaXNFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgPyBjcmVhdGVFeHRlbmRlZEV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50LnZhbHVlLCBhdXRvbWF0aW9uRXZlbnQuZW5kVGltZSwgdGhpcy5fY3VycmVuVGltZSkgOiBpc0xpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgPyBjcmVhdGVFeHRlbmRlZExpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudC52YWx1ZSwgZXZlbnRUaW1lLCB0aGlzLl9jdXJyZW5UaW1lKSA6IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgIGlmIChfaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgIHRoaXMuX2F1dG9tYXRpb25FdmVudHMucHVzaChwZXJzaXN0ZW50QXV0b21hdGlvbkV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChpc1NldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSAmJiBldmVudFRpbWUgKyBhdXRvbWF0aW9uRXZlbnQuZHVyYXRpb24gPiBnZXRFdmVudFRpbWUodGhpcy5fYXV0b21hdGlvbkV2ZW50c1tfaW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLnNwbGljZShfaW5kZXgsIDAsIHBlcnNpc3RlbnRBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSwge1xuICAgICAgICBrZXk6IFwiZmx1c2hcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZsdXNoKHRpbWUpIHtcbiAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmZpbmRJbmRleChmdW5jdGlvbiAoY3VycmVudEF1dG9tYXRpb25FdmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldEV2ZW50VGltZShjdXJyZW50QXV0b21hdGlvbkV2ZW50KSA+IHRpbWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gMSkge1xuICAgICAgICAgICAgdmFyIHJlbWFpbmluZ0F1dG9tYXRpb25FdmVudHMgPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLnNsaWNlKGluZGV4IC0gMSk7XG4gICAgICAgICAgICB2YXIgZmlyc3RSZW1haW5pbmdBdXRvbWF0aW9uRXZlbnQgPSByZW1haW5pbmdBdXRvbWF0aW9uRXZlbnRzWzBdO1xuICAgICAgICAgICAgaWYgKGlzU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50KGZpcnN0UmVtYWluaW5nQXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICByZW1haW5pbmdBdXRvbWF0aW9uRXZlbnRzLnVuc2hpZnQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoZ2V0VmFsdWVPZkF1dG9tYXRpb25FdmVudEF0SW5kZXhBdFRpbWUodGhpcy5fYXV0b21hdGlvbkV2ZW50cywgaW5kZXggLSAyLCBmaXJzdFJlbWFpbmluZ0F1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIHRoaXMuX2RlZmF1bHRWYWx1ZSksIGZpcnN0UmVtYWluaW5nQXV0b21hdGlvbkV2ZW50LnN0YXJ0VGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYXV0b21hdGlvbkV2ZW50cyA9IHJlbWFpbmluZ0F1dG9tYXRpb25FdmVudHM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGtleTogXCJnZXRWYWx1ZVwiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VmFsdWUodGltZSkge1xuICAgICAgICAgIGlmICh0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGluZGV4T2ZOZXh0RXZlbnQgPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmZpbmRJbmRleChmdW5jdGlvbiAoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RXZlbnRUaW1lKGF1dG9tYXRpb25FdmVudCkgPiB0aW1lO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHZhciBuZXh0QXV0b21hdGlvbkV2ZW50ID0gdGhpcy5fYXV0b21hdGlvbkV2ZW50c1tpbmRleE9mTmV4dEV2ZW50XTtcbiAgICAgICAgICB2YXIgaW5kZXhPZkN1cnJlbnRFdmVudCA9IChpbmRleE9mTmV4dEV2ZW50ID09PSAtMSA/IHRoaXMuX2F1dG9tYXRpb25FdmVudHMubGVuZ3RoIDogaW5kZXhPZk5leHRFdmVudCkgLSAxO1xuICAgICAgICAgIHZhciBjdXJyZW50QXV0b21hdGlvbkV2ZW50ID0gdGhpcy5fYXV0b21hdGlvbkV2ZW50c1tpbmRleE9mQ3VycmVudEV2ZW50XTtcbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50KGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpICYmIChuZXh0QXV0b21hdGlvbkV2ZW50ID09PSB1bmRlZmluZWQgfHwgIWlzQW55UmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQobmV4dEF1dG9tYXRpb25FdmVudCkgfHwgbmV4dEF1dG9tYXRpb25FdmVudC5pbnNlcnRUaW1lID4gdGltZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRUYXJnZXRWYWx1ZUF0VGltZSh0aW1lLCBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZSh0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLCBpbmRleE9mQ3VycmVudEV2ZW50IC0gMSwgY3VycmVudEF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIHRoaXMuX2RlZmF1bHRWYWx1ZSksIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgJiYgKG5leHRBdXRvbWF0aW9uRXZlbnQgPT09IHVuZGVmaW5lZCB8fCAhaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChuZXh0QXV0b21hdGlvbkV2ZW50KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChjdXJyZW50QXV0b21hdGlvbkV2ZW50KSAmJiAobmV4dEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkIHx8ICFpc0FueVJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KG5leHRBdXRvbWF0aW9uRXZlbnQpIHx8IGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgY3VycmVudEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbiA+IHRpbWUpKSB7XG4gICAgICAgICAgICBpZiAodGltZSA8IGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgY3VycmVudEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbikge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0VmFsdWVDdXJ2ZVZhbHVlQXRUaW1lKHRpbWUsIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQudmFsdWVzW2N1cnJlbnRBdXRvbWF0aW9uRXZlbnQudmFsdWVzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzQW55UmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgJiYgKG5leHRBdXRvbWF0aW9uRXZlbnQgPT09IHVuZGVmaW5lZCB8fCAhaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChuZXh0QXV0b21hdGlvbkV2ZW50KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobmV4dEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChuZXh0QXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgdmFyIF9nZXRFbmRUaW1lQW5kVmFsdWVPZiA9IGdldEVuZFRpbWVBbmRWYWx1ZU9mUHJldmlvdXNBdXRvbWF0aW9uRXZlbnQodGhpcy5fYXV0b21hdGlvbkV2ZW50cywgaW5kZXhPZkN1cnJlbnRFdmVudCwgY3VycmVudEF1dG9tYXRpb25FdmVudCwgbmV4dEF1dG9tYXRpb25FdmVudCwgdGhpcy5fZGVmYXVsdFZhbHVlKSxcbiAgICAgICAgICAgICAgX2dldEVuZFRpbWVBbmRWYWx1ZU9mMiA9IF9zbGljZWRUb0FycmF5KF9nZXRFbmRUaW1lQW5kVmFsdWVPZiwgMiksXG4gICAgICAgICAgICAgIHN0YXJ0VGltZSA9IF9nZXRFbmRUaW1lQW5kVmFsdWVPZjJbMF0sXG4gICAgICAgICAgICAgIHZhbHVlID0gX2dldEVuZFRpbWVBbmRWYWx1ZU9mMlsxXTtcbiAgICAgICAgICAgIHJldHVybiBnZXRFeHBvbmVudGlhbFJhbXBWYWx1ZUF0VGltZSh0aW1lLCBzdGFydFRpbWUsIHZhbHVlLCBuZXh0QXV0b21hdGlvbkV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG5leHRBdXRvbWF0aW9uRXZlbnQgIT09IHVuZGVmaW5lZCAmJiBpc0xpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KG5leHRBdXRvbWF0aW9uRXZlbnQpKSB7XG4gICAgICAgICAgICB2YXIgX2dldEVuZFRpbWVBbmRWYWx1ZU9mMyA9IGdldEVuZFRpbWVBbmRWYWx1ZU9mUHJldmlvdXNBdXRvbWF0aW9uRXZlbnQodGhpcy5fYXV0b21hdGlvbkV2ZW50cywgaW5kZXhPZkN1cnJlbnRFdmVudCwgY3VycmVudEF1dG9tYXRpb25FdmVudCwgbmV4dEF1dG9tYXRpb25FdmVudCwgdGhpcy5fZGVmYXVsdFZhbHVlKSxcbiAgICAgICAgICAgICAgX2dldEVuZFRpbWVBbmRWYWx1ZU9mNCA9IF9zbGljZWRUb0FycmF5KF9nZXRFbmRUaW1lQW5kVmFsdWVPZjMsIDIpLFxuICAgICAgICAgICAgICBfc3RhcnRUaW1lID0gX2dldEVuZFRpbWVBbmRWYWx1ZU9mNFswXSxcbiAgICAgICAgICAgICAgX3ZhbHVlID0gX2dldEVuZFRpbWVBbmRWYWx1ZU9mNFsxXTtcbiAgICAgICAgICAgIHJldHVybiBnZXRMaW5lYXJSYW1wVmFsdWVBdFRpbWUodGltZSwgX3N0YXJ0VGltZSwgX3ZhbHVlLCBuZXh0QXV0b21hdGlvbkV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfV0pO1xuICAgICAgcmV0dXJuIEF1dG9tYXRpb25FdmVudExpc3Q7XG4gICAgfShTeW1ib2wuaXRlcmF0b3IpO1xuXG4gICAgdmFyIGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNhbmNlbFRpbWU6IGNhbmNlbFRpbWUsXG4gICAgICAgIHR5cGU6ICdjYW5jZWxBbmRIb2xkJ1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjYW5jZWxUaW1lOiBjYW5jZWxUaW1lLFxuICAgICAgICB0eXBlOiAnY2FuY2VsU2NoZWR1bGVkVmFsdWVzJ1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbmRUaW1lOiBlbmRUaW1lLFxuICAgICAgICB0eXBlOiAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgIHR5cGU6ICdsaW5lYXJSYW1wVG9WYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICAgIHRpbWVDb25zdGFudDogdGltZUNvbnN0YW50LFxuICAgICAgICB0eXBlOiAnc2V0VGFyZ2V0J1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgZXhwb3J0cy5BdXRvbWF0aW9uRXZlbnRMaXN0ID0gQXV0b21hdGlvbkV2ZW50TGlzdDtcbiAgICBleHBvcnRzLmNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQgPSBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50ID0gY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQ7XG4gICAgZXhwb3J0cy5jcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50ID0gY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQgPSBjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudDtcbiAgICBleHBvcnRzLmNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgPSBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50O1xuXG59KSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///382\n")},441:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/react/index.js\nvar react = __webpack_require__(294);\n// EXTERNAL MODULE: ./node_modules/react-dom/client.js\nvar client = __webpack_require__(745);\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/version.js\nconst version = "14.7.77";\n//# sourceMappingURL=version.js.map\n// EXTERNAL MODULE: ./node_modules/automation-events/build/es5/bundle.js\nvar bundle = __webpack_require__(382);\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/abort-error.js\nconst createAbortError = () => new DOMException(\'\', \'AbortError\');\n//# sourceMappingURL=abort-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-active-input-connection-to-audio-node.js\nconst createAddActiveInputConnectionToAudioNode = (insertElementInSet) => {\n return (activeInputs, source, [output, input, eventListener], ignoreDuplicates) => {\n insertElementInSet(activeInputs[input], [source, output, eventListener], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output, ignoreDuplicates);\n };\n};\n//# sourceMappingURL=add-active-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-node-connections.js\nconst createAddAudioNodeConnections = (audioNodeConnectionsStore) => {\n return (audioNode, audioNodeRenderer, nativeAudioNode) => {\n const activeInputs = [];\n for (let i = 0; i < nativeAudioNode.numberOfInputs; i += 1) {\n activeInputs.push(new Set());\n }\n audioNodeConnectionsStore.set(audioNode, {\n activeInputs,\n outputs: new Set(),\n passiveInputs: new WeakMap(),\n renderer: audioNodeRenderer\n });\n };\n};\n//# sourceMappingURL=add-audio-node-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-param-connections.js\nconst createAddAudioParamConnections = (audioParamConnectionsStore) => {\n return (audioParam, audioParamRenderer) => {\n audioParamConnectionsStore.set(audioParam, { activeInputs: new Set(), passiveInputs: new WeakMap(), renderer: audioParamRenderer });\n };\n};\n//# sourceMappingURL=add-audio-param-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/globals.js\nconst ACTIVE_AUDIO_NODE_STORE = new WeakSet();\nconst AUDIO_NODE_CONNECTIONS_STORE = new WeakMap();\nconst AUDIO_NODE_STORE = new WeakMap();\nconst AUDIO_PARAM_CONNECTIONS_STORE = new WeakMap();\nconst AUDIO_PARAM_STORE = new WeakMap();\nconst CONTEXT_STORE = new WeakMap();\nconst EVENT_LISTENERS = new WeakMap();\nconst CYCLE_COUNTERS = new WeakMap();\n// This clunky name is borrowed from the spec. :-)\nconst NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS = new WeakMap();\nconst NODE_TO_PROCESSOR_MAPS = new WeakMap();\n//# sourceMappingURL=globals.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-constructible.js\nconst handler = {\n construct() {\n return handler;\n }\n};\nconst isConstructible = (constructible) => {\n try {\n const proxy = new Proxy(constructible, handler);\n new proxy(); // tslint:disable-line:no-unused-expression\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=is-constructible.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/split-import-statements.js\n/*\n * This massive regex tries to cover all the following cases.\n *\n * import \'./path\';\n * import defaultImport from \'./path\';\n * import { namedImport } from \'./path\';\n * import { namedImport as renamendImport } from \'./path\';\n * import * as namespaceImport from \'./path\';\n * import defaultImport, { namedImport } from \'./path\';\n * import defaultImport, { namedImport as renamendImport } from \'./path\';\n * import defaultImport, * as namespaceImport from \'./path\';\n */\nconst IMPORT_STATEMENT_REGEX = /^import(?:(?:[\\s]+[\\w]+|(?:[\\s]+[\\w]+[\\s]*,)?[\\s]*\\{[\\s]*[\\w]+(?:[\\s]+as[\\s]+[\\w]+)?(?:[\\s]*,[\\s]*[\\w]+(?:[\\s]+as[\\s]+[\\w]+)?)*[\\s]*}|(?:[\\s]+[\\w]+[\\s]*,)?[\\s]*\\*[\\s]+as[\\s]+[\\w]+)[\\s]+from)?(?:[\\s]*)("([^"\\\\]|\\\\.)+"|\'([^\'\\\\]|\\\\.)+\')(?:[\\s]*);?/; // tslint:disable-line:max-line-length\nconst splitImportStatements = (source, url) => {\n const importStatements = [];\n let sourceWithoutImportStatements = source.replace(/^[\\s]+/, \'\');\n let result = sourceWithoutImportStatements.match(IMPORT_STATEMENT_REGEX);\n while (result !== null) {\n const unresolvedUrl = result[1].slice(1, -1);\n const importStatementWithResolvedUrl = result[0]\n .replace(/([\\s]+)?;?$/, \'\')\n .replace(unresolvedUrl, new URL(unresolvedUrl, url).toString());\n importStatements.push(importStatementWithResolvedUrl);\n sourceWithoutImportStatements = sourceWithoutImportStatements.slice(result[0].length).replace(/^[\\s]+/, \'\');\n result = sourceWithoutImportStatements.match(IMPORT_STATEMENT_REGEX);\n }\n return [importStatements.join(\';\'), sourceWithoutImportStatements];\n};\n//# sourceMappingURL=split-import-statements.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-worklet-module.js\n\n\n\nconst verifyParameterDescriptors = (parameterDescriptors) => {\n if (parameterDescriptors !== undefined && !Array.isArray(parameterDescriptors)) {\n throw new TypeError(\'The parameterDescriptors property of given value for processorCtor is not an array.\');\n }\n};\nconst verifyProcessorCtor = (processorCtor) => {\n if (!isConstructible(processorCtor)) {\n throw new TypeError(\'The given value for processorCtor should be a constructor.\');\n }\n if (processorCtor.prototype === null || typeof processorCtor.prototype !== \'object\') {\n throw new TypeError(\'The given value for processorCtor should have a prototype.\');\n }\n};\nconst createAddAudioWorkletModule = (cacheTestResult, createNotSupportedError, evaluateSource, exposeCurrentFrameAndCurrentTime, fetchSource, getNativeContext, getOrCreateBackupOfflineAudioContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, ongoingRequests, resolvedRequests, testAudioWorkletProcessorPostMessageSupport, window) => {\n let index = 0;\n return (context, moduleURL, options = { credentials: \'omit\' }) => {\n const resolvedRequestsOfContext = resolvedRequests.get(context);\n if (resolvedRequestsOfContext !== undefined && resolvedRequestsOfContext.has(moduleURL)) {\n return Promise.resolve();\n }\n const ongoingRequestsOfContext = ongoingRequests.get(context);\n if (ongoingRequestsOfContext !== undefined) {\n const promiseOfOngoingRequest = ongoingRequestsOfContext.get(moduleURL);\n if (promiseOfOngoingRequest !== undefined) {\n return promiseOfOngoingRequest;\n }\n }\n const nativeContext = getNativeContext(context);\n // Bug #59: Safari does not implement the audioWorklet property.\n const promise = nativeContext.audioWorklet === undefined\n ? fetchSource(moduleURL)\n .then(([source, absoluteUrl]) => {\n const [importStatements, sourceWithoutImportStatements] = splitImportStatements(source, absoluteUrl);\n /*\n * This is the unminified version of the code used below:\n *\n * ```js\n * ${ importStatements };\n * ((a, b) => {\n * (a[b] = a[b] || [ ]).push(\n * (AudioWorkletProcessor, global, registerProcessor, sampleRate, self, window) => {\n * ${ sourceWithoutImportStatements }\n * }\n * );\n * })(window, \'_AWGS\');\n * ```\n */\n // tslint:disable-next-line:max-line-length\n const wrappedSource = `${importStatements};((a,b)=>{(a[b]=a[b]||[]).push((AudioWorkletProcessor,global,registerProcessor,sampleRate,self,window)=>{${sourceWithoutImportStatements}\n})})(window,\'_AWGS\')`;\n // @todo Evaluating the given source code is a possible security problem.\n return evaluateSource(wrappedSource);\n })\n .then(() => {\n const evaluateAudioWorkletGlobalScope = window._AWGS.pop();\n if (evaluateAudioWorkletGlobalScope === undefined) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n throw new SyntaxError();\n }\n exposeCurrentFrameAndCurrentTime(nativeContext.currentTime, nativeContext.sampleRate, () => evaluateAudioWorkletGlobalScope(class AudioWorkletProcessor {\n }, undefined, (name, processorCtor) => {\n if (name.trim() === \'\') {\n throw createNotSupportedError();\n }\n const nodeNameToProcessorConstructorMap = NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.get(nativeContext);\n if (nodeNameToProcessorConstructorMap !== undefined) {\n if (nodeNameToProcessorConstructorMap.has(name)) {\n throw createNotSupportedError();\n }\n verifyProcessorCtor(processorCtor);\n verifyParameterDescriptors(processorCtor.parameterDescriptors);\n nodeNameToProcessorConstructorMap.set(name, processorCtor);\n }\n else {\n verifyProcessorCtor(processorCtor);\n verifyParameterDescriptors(processorCtor.parameterDescriptors);\n NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.set(nativeContext, new Map([[name, processorCtor]]));\n }\n }, nativeContext.sampleRate, undefined, undefined));\n })\n : Promise.all([\n fetchSource(moduleURL),\n Promise.resolve(cacheTestResult(testAudioWorkletProcessorPostMessageSupport, testAudioWorkletProcessorPostMessageSupport))\n ]).then(([[source, absoluteUrl], isSupportingPostMessage]) => {\n const currentIndex = index + 1;\n index = currentIndex;\n const [importStatements, sourceWithoutImportStatements] = splitImportStatements(source, absoluteUrl);\n /*\n * Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\n *\n * This is the unminified version of the code used below.\n *\n * ```js\n * class extends AudioWorkletProcessor {\n *\n * __buffers = new WeakSet();\n *\n * constructor () {\n * super();\n *\n * this.port.postMessage = ((postMessage) => {\n * return (message, transferables) => {\n * const filteredTransferables = (transferables)\n * ? transferables.filter((transferable) => !this.__buffers.has(transferable))\n * : transferables;\n *\n * return postMessage.call(this.port, message, filteredTransferables);\n * };\n * })(this.port.postMessage);\n * }\n * }\n * ```\n */\n const patchedAudioWorkletProcessor = isSupportingPostMessage\n ? \'AudioWorkletProcessor\'\n : \'class extends AudioWorkletProcessor {__b=new WeakSet();constructor(){super();(p=>p.postMessage=(q=>(m,t)=>q.call(p,m,t?t.filter(u=>!this.__b.has(u)):t))(p.postMessage))(this.port)}}\';\n /*\n * Bug #170: Chrome and Edge do call process() with an array with empty channelData for each input if no input is connected.\n *\n * Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\n *\n * Bug #190: Safari doesn\'t throw an error when loading an unparsable module.\n *\n * This is the unminified version of the code used below:\n *\n * ```js\n * `${ importStatements };\n * ((AudioWorkletProcessor, registerProcessor) => {${ sourceWithoutImportStatements }\n * })(\n * ${ patchedAudioWorkletProcessor },\n * (name, processorCtor) => registerProcessor(name, class extends processorCtor {\n *\n * __collectBuffers = (array) => {\n * array.forEach((element) => this.__buffers.add(element.buffer));\n * };\n *\n * process (inputs, outputs, parameters) {\n * inputs.forEach(this.__collectBuffers);\n * outputs.forEach(this.__collectBuffers);\n * this.__collectBuffers(Object.values(parameters));\n *\n * return super.process(\n * (inputs.map((input) => input.some((channelData) => channelData.length === 0)) ? [ ] : input),\n * outputs,\n * parameters\n * );\n * }\n *\n * })\n * );\n *\n * registerProcessor(`__sac${currentIndex}`, class extends AudioWorkletProcessor{\n *\n * process () {\n * return false;\n * }\n *\n * })`\n * ```\n */\n const memberDefinition = isSupportingPostMessage ? \'\' : \'__c = (a) => a.forEach(e=>this.__b.add(e.buffer));\';\n const bufferRegistration = isSupportingPostMessage\n ? \'\'\n : \'i.forEach(this.__c);o.forEach(this.__c);this.__c(Object.values(p));\';\n const wrappedSource = `${importStatements};((AudioWorkletProcessor,registerProcessor)=>{${sourceWithoutImportStatements}\n})(${patchedAudioWorkletProcessor},(n,p)=>registerProcessor(n,class extends p{${memberDefinition}process(i,o,p){${bufferRegistration}return super.process(i.map(j=>j.some(k=>k.length===0)?[]:j),o,p)}}));registerProcessor(\'__sac${currentIndex}\',class extends AudioWorkletProcessor{process(){return !1}})`;\n const blob = new Blob([wrappedSource], { type: \'application/javascript; charset=utf-8\' });\n const url = URL.createObjectURL(blob);\n return nativeContext.audioWorklet\n .addModule(url, options)\n .then(() => {\n if (isNativeOfflineAudioContext(nativeContext)) {\n return nativeContext;\n }\n // Bug #186: Chrome and Edge do not allow to create an AudioWorkletNode on a closed AudioContext.\n const backupOfflineAudioContext = getOrCreateBackupOfflineAudioContext(nativeContext);\n return backupOfflineAudioContext.audioWorklet.addModule(url, options).then(() => backupOfflineAudioContext);\n })\n .then((nativeContextOrBackupOfflineAudioContext) => {\n if (nativeAudioWorkletNodeConstructor === null) {\n throw new SyntaxError();\n }\n try {\n // Bug #190: Safari doesn\'t throw an error when loading an unparsable module.\n new nativeAudioWorkletNodeConstructor(nativeContextOrBackupOfflineAudioContext, `__sac${currentIndex}`); // tslint:disable-line:no-unused-expression\n }\n catch {\n throw new SyntaxError();\n }\n })\n .finally(() => URL.revokeObjectURL(url));\n });\n if (ongoingRequestsOfContext === undefined) {\n ongoingRequests.set(context, new Map([[moduleURL, promise]]));\n }\n else {\n ongoingRequestsOfContext.set(moduleURL, promise);\n }\n promise\n .then(() => {\n const updatedResolvedRequestsOfContext = resolvedRequests.get(context);\n if (updatedResolvedRequestsOfContext === undefined) {\n resolvedRequests.set(context, new Set([moduleURL]));\n }\n else {\n updatedResolvedRequestsOfContext.add(moduleURL);\n }\n })\n .finally(() => {\n const updatedOngoingRequestsOfContext = ongoingRequests.get(context);\n if (updatedOngoingRequestsOfContext !== undefined) {\n updatedOngoingRequestsOfContext.delete(moduleURL);\n }\n });\n return promise;\n };\n};\n//# sourceMappingURL=add-audio-worklet-module.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-value-for-key.js\nconst getValueForKey = (map, key) => {\n const value = map.get(key);\n if (value === undefined) {\n throw new Error(\'A value with the given key could not be found.\');\n }\n return value;\n};\n//# sourceMappingURL=get-value-for-key.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/pick-element-from-set.js\nconst pickElementFromSet = (set, predicate) => {\n const matchingElements = Array.from(set).filter(predicate);\n if (matchingElements.length > 1) {\n throw Error(\'More than one element was found.\');\n }\n if (matchingElements.length === 0) {\n throw Error(\'No element was found.\');\n }\n const [matchingElement] = matchingElements;\n set.delete(matchingElement);\n return matchingElement;\n};\n//# sourceMappingURL=pick-element-from-set.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-passive-input-connection-to-audio-node.js\n\n\nconst deletePassiveInputConnectionToAudioNode = (passiveInputs, source, output, input) => {\n const passiveInputConnections = getValueForKey(passiveInputs, source);\n const matchingConnection = pickElementFromSet(passiveInputConnections, (passiveInputConnection) => passiveInputConnection[0] === output && passiveInputConnection[1] === input);\n if (passiveInputConnections.size === 0) {\n passiveInputs.delete(source);\n }\n return matchingConnection;\n};\n//# sourceMappingURL=delete-passive-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-event-listeners-of-audio-node.js\n\n\nconst getEventListenersOfAudioNode = (audioNode) => {\n return getValueForKey(EVENT_LISTENERS, audioNode);\n};\n//# sourceMappingURL=get-event-listeners-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-active.js\n\n\nconst setInternalStateToActive = (audioNode) => {\n if (ACTIVE_AUDIO_NODE_STORE.has(audioNode)) {\n throw new Error(\'The AudioNode is already stored.\');\n }\n ACTIVE_AUDIO_NODE_STORE.add(audioNode);\n getEventListenersOfAudioNode(audioNode).forEach((eventListener) => eventListener(true));\n};\n//# sourceMappingURL=set-internal-state-to-active.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-worklet-node.js\nconst isAudioWorkletNode = (audioNode) => {\n return \'port\' in audioNode;\n};\n//# sourceMappingURL=audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-passive.js\n\n\nconst setInternalStateToPassive = (audioNode) => {\n if (!ACTIVE_AUDIO_NODE_STORE.has(audioNode)) {\n throw new Error(\'The AudioNode is not stored.\');\n }\n ACTIVE_AUDIO_NODE_STORE["delete"](audioNode);\n getEventListenersOfAudioNode(audioNode).forEach((eventListener) => eventListener(false));\n};\n//# sourceMappingURL=set-internal-state-to-passive.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-passive-when-necessary.js\n\n\n// Set the internalState of the audioNode to \'passive\' if it is not an AudioWorkletNode and if it has no \'active\' input connections.\nconst setInternalStateToPassiveWhenNecessary = (audioNode, activeInputs) => {\n if (!isAudioWorkletNode(audioNode) && activeInputs.every((connections) => connections.size === 0)) {\n setInternalStateToPassive(audioNode);\n }\n};\n//# sourceMappingURL=set-internal-state-to-passive-when-necessary.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-connection-to-audio-node.js\n\n\n\nconst createAddConnectionToAudioNode = (addActiveInputConnectionToAudioNode, addPassiveInputConnectionToAudioNode, connectNativeAudioNodeToNativeAudioNode, deleteActiveInputConnectionToAudioNode, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getAudioNodeTailTime, getEventListenersOfAudioNode, getNativeAudioNode, insertElementInSet, isActiveAudioNode, isPartOfACycle, isPassiveAudioNode) => {\n const tailTimeTimeoutIds = new WeakMap();\n return (source, destination, output, input, isOffline) => {\n const { activeInputs, passiveInputs } = getAudioNodeConnections(destination);\n const { outputs } = getAudioNodeConnections(source);\n const eventListeners = getEventListenersOfAudioNode(source);\n const eventListener = (isActive) => {\n const nativeDestinationAudioNode = getNativeAudioNode(destination);\n const nativeSourceAudioNode = getNativeAudioNode(source);\n if (isActive) {\n const partialConnection = deletePassiveInputConnectionToAudioNode(passiveInputs, source, output, input);\n addActiveInputConnectionToAudioNode(activeInputs, source, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n connectNativeAudioNodeToNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output, input);\n }\n if (isPassiveAudioNode(destination)) {\n setInternalStateToActive(destination);\n }\n }\n else {\n const partialConnection = deleteActiveInputConnectionToAudioNode(activeInputs, source, output, input);\n addPassiveInputConnectionToAudioNode(passiveInputs, input, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n disconnectNativeAudioNodeFromNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output, input);\n }\n const tailTime = getAudioNodeTailTime(destination);\n if (tailTime === 0) {\n if (isActiveAudioNode(destination)) {\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n }\n else {\n const tailTimeTimeoutId = tailTimeTimeoutIds.get(destination);\n if (tailTimeTimeoutId !== undefined) {\n clearTimeout(tailTimeTimeoutId);\n }\n tailTimeTimeoutIds.set(destination, setTimeout(() => {\n if (isActiveAudioNode(destination)) {\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n }, tailTime * 1000));\n }\n }\n };\n if (insertElementInSet(outputs, [destination, output, input], (outputConnection) => outputConnection[0] === destination && outputConnection[1] === output && outputConnection[2] === input, true)) {\n eventListeners.add(eventListener);\n if (isActiveAudioNode(source)) {\n addActiveInputConnectionToAudioNode(activeInputs, source, [output, input, eventListener], true);\n }\n else {\n addPassiveInputConnectionToAudioNode(passiveInputs, input, [source, output, eventListener], true);\n }\n return true;\n }\n return false;\n };\n};\n//# sourceMappingURL=add-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-passive-input-connection-to-audio-node.js\nconst createAddPassiveInputConnectionToAudioNode = (insertElementInSet) => {\n return (passiveInputs, input, [source, output, eventListener], ignoreDuplicates) => {\n const passiveInputConnections = passiveInputs.get(source);\n if (passiveInputConnections === undefined) {\n passiveInputs.set(source, new Set([[output, input, eventListener]]));\n }\n else {\n insertElementInSet(passiveInputConnections, [output, input, eventListener], (passiveInputConnection) => passiveInputConnection[0] === output && passiveInputConnection[1] === input, ignoreDuplicates);\n }\n };\n};\n//# sourceMappingURL=add-passive-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-silent-connection.js\nconst createAddSilentConnection = (createNativeGainNode) => {\n return (nativeContext, nativeAudioScheduledSourceNode) => {\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeAudioScheduledSourceNode.connect(nativeGainNode).connect(nativeContext.destination);\n const disconnect = () => {\n nativeAudioScheduledSourceNode.removeEventListener(\'ended\', disconnect);\n nativeAudioScheduledSourceNode.disconnect(nativeGainNode);\n nativeGainNode.disconnect();\n };\n nativeAudioScheduledSourceNode.addEventListener(\'ended\', disconnect);\n };\n};\n//# sourceMappingURL=add-silent-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-unrendered-audio-worklet-node.js\nconst createAddUnrenderedAudioWorkletNode = (getUnrenderedAudioWorkletNodes) => {\n return (nativeContext, audioWorkletNode) => {\n getUnrenderedAudioWorkletNodes(nativeContext).add(audioWorkletNode);\n };\n};\n//# sourceMappingURL=add-unrendered-audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/analyser-node-constructor.js\nconst DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n fftSize: 2048,\n maxDecibels: -30,\n minDecibels: -100,\n smoothingTimeConstant: 0.8\n};\nconst createAnalyserNodeConstructor = (audionNodeConstructor, createAnalyserNodeRenderer, createIndexSizeError, createNativeAnalyserNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class AnalyserNode extends audionNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...DEFAULT_OPTIONS, ...options };\n const nativeAnalyserNode = createNativeAnalyserNode(nativeContext, mergedOptions);\n const analyserNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createAnalyserNodeRenderer() : null));\n super(context, false, nativeAnalyserNode, analyserNodeRenderer);\n this._nativeAnalyserNode = nativeAnalyserNode;\n }\n get fftSize() {\n return this._nativeAnalyserNode.fftSize;\n }\n set fftSize(value) {\n this._nativeAnalyserNode.fftSize = value;\n }\n get frequencyBinCount() {\n return this._nativeAnalyserNode.frequencyBinCount;\n }\n get maxDecibels() {\n return this._nativeAnalyserNode.maxDecibels;\n }\n set maxDecibels(value) {\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n const maxDecibels = this._nativeAnalyserNode.maxDecibels;\n this._nativeAnalyserNode.maxDecibels = value;\n if (!(value > this._nativeAnalyserNode.minDecibels)) {\n this._nativeAnalyserNode.maxDecibels = maxDecibels;\n throw createIndexSizeError();\n }\n }\n get minDecibels() {\n return this._nativeAnalyserNode.minDecibels;\n }\n set minDecibels(value) {\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n const minDecibels = this._nativeAnalyserNode.minDecibels;\n this._nativeAnalyserNode.minDecibels = value;\n if (!(this._nativeAnalyserNode.maxDecibels > value)) {\n this._nativeAnalyserNode.minDecibels = minDecibels;\n throw createIndexSizeError();\n }\n }\n get smoothingTimeConstant() {\n return this._nativeAnalyserNode.smoothingTimeConstant;\n }\n set smoothingTimeConstant(value) {\n this._nativeAnalyserNode.smoothingTimeConstant = value;\n }\n getByteFrequencyData(array) {\n this._nativeAnalyserNode.getByteFrequencyData(array);\n }\n getByteTimeDomainData(array) {\n this._nativeAnalyserNode.getByteTimeDomainData(array);\n }\n getFloatFrequencyData(array) {\n this._nativeAnalyserNode.getFloatFrequencyData(array);\n }\n getFloatTimeDomainData(array) {\n this._nativeAnalyserNode.getFloatTimeDomainData(array);\n }\n };\n};\n//# sourceMappingURL=analyser-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-owned-by-context.js\nconst isOwnedByContext = (nativeAudioNode, nativeContext) => {\n return nativeAudioNode.context === nativeContext;\n};\n//# sourceMappingURL=is-owned-by-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/analyser-node-renderer-factory.js\n\nconst createAnalyserNodeRendererFactory = (createNativeAnalyserNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAnalyserNodes = new WeakMap();\n const createAnalyserNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAnalyserNode = getNativeAudioNode(proxy);\n // If the initially used nativeAnalyserNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAnalyserNodeIsOwnedByContext = isOwnedByContext(nativeAnalyserNode, nativeOfflineAudioContext);\n if (!nativeAnalyserNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAnalyserNode.channelCount,\n channelCountMode: nativeAnalyserNode.channelCountMode,\n channelInterpretation: nativeAnalyserNode.channelInterpretation,\n fftSize: nativeAnalyserNode.fftSize,\n maxDecibels: nativeAnalyserNode.maxDecibels,\n minDecibels: nativeAnalyserNode.minDecibels,\n smoothingTimeConstant: nativeAnalyserNode.smoothingTimeConstant\n };\n nativeAnalyserNode = createNativeAnalyserNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAnalyserNodes.set(nativeOfflineAudioContext, nativeAnalyserNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAnalyserNode);\n return nativeAnalyserNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAnalyserNode = renderedNativeAnalyserNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAnalyserNode !== undefined) {\n return Promise.resolve(renderedNativeAnalyserNode);\n }\n return createAnalyserNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=analyser-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-copy-channel-methods-out-of-bounds-support.js\nconst testAudioBufferCopyChannelMethodsOutOfBoundsSupport = (nativeAudioBuffer) => {\n try {\n nativeAudioBuffer.copyToChannel(new Float32Array(1), 0, -1);\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-copy-channel-methods-out-of-bounds-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/index-size-error.js\nconst createIndexSizeError = () => new DOMException(\'\', \'IndexSizeError\');\n//# sourceMappingURL=index-size-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-get-channel-data-method.js\n\nconst wrapAudioBufferGetChannelDataMethod = (audioBuffer) => {\n audioBuffer.getChannelData = ((getChannelData) => {\n return (channel) => {\n try {\n return getChannelData.call(audioBuffer, channel);\n }\n catch (err) {\n if (err.code === 12) {\n throw createIndexSizeError();\n }\n throw err;\n }\n };\n })(audioBuffer.getChannelData);\n};\n//# sourceMappingURL=wrap-audio-buffer-get-channel-data-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-constructor.js\n\n\nconst audio_buffer_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createAudioBufferConstructor = (audioBufferStore, cacheTestResult, createNotSupportedError, nativeAudioBufferConstructor, nativeOfflineAudioContextConstructor, testNativeAudioBufferConstructorSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n let nativeOfflineAudioContext = null;\n return class AudioBuffer {\n constructor(options) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const { length, numberOfChannels, sampleRate } = { ...audio_buffer_constructor_DEFAULT_OPTIONS, ...options };\n if (nativeOfflineAudioContext === null) {\n nativeOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n }\n /*\n * Bug #99: Firefox does not throw a NotSupportedError when the numberOfChannels is zero. But it only does it when using the\n * factory function. But since Firefox also supports the constructor everything should be fine.\n */\n const audioBuffer = nativeAudioBufferConstructor !== null &&\n cacheTestResult(testNativeAudioBufferConstructorSupport, testNativeAudioBufferConstructorSupport)\n ? new nativeAudioBufferConstructor({ length, numberOfChannels, sampleRate })\n : nativeOfflineAudioContext.createBuffer(numberOfChannels, length, sampleRate);\n // Bug #99: Safari does not throw an error when the numberOfChannels is zero.\n if (audioBuffer.numberOfChannels === 0) {\n throw createNotSupportedError();\n }\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n }\n else if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n /*\n * This does violate all good pratices but it is necessary to allow this AudioBuffer to be used with native\n * (Offline)AudioContexts.\n */\n return audioBuffer;\n }\n static [Symbol.hasInstance](instance) {\n return ((instance !== null && typeof instance === \'object\' && Object.getPrototypeOf(instance) === AudioBuffer.prototype) ||\n audioBufferStore.has(instance));\n }\n };\n};\n//# sourceMappingURL=audio-buffer-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/constants.js\nconst MOST_NEGATIVE_SINGLE_FLOAT = -3.4028234663852886e38;\nconst MOST_POSITIVE_SINGLE_FLOAT = -MOST_NEGATIVE_SINGLE_FLOAT;\n//# sourceMappingURL=constants.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-active-audio-node.js\n\nconst isActiveAudioNode = (audioNode) => ACTIVE_AUDIO_NODE_STORE.has(audioNode);\n//# sourceMappingURL=is-active-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-source-node-constructor.js\n\n\n\n\nconst audio_buffer_source_node_constructor_DEFAULT_OPTIONS = {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n // Bug #149: Safari does not yet support the detune AudioParam.\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n};\nconst createAudioBufferSourceNodeConstructor = (audioNodeConstructor, createAudioBufferSourceNodeRenderer, createAudioParam, createInvalidStateError, createNativeAudioBufferSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class AudioBufferSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...audio_buffer_source_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const audioBufferSourceNodeRenderer = ((isOffline ? createAudioBufferSourceNodeRenderer() : null));\n super(context, false, nativeAudioBufferSourceNode, audioBufferSourceNodeRenderer);\n this._audioBufferSourceNodeRenderer = audioBufferSourceNodeRenderer;\n this._isBufferNullified = false;\n this._isBufferSet = mergedOptions.buffer !== null;\n this._nativeAudioBufferSourceNode = nativeAudioBufferSourceNode;\n this._onended = null;\n // Bug #73: Safari does not export the correct values for maxValue and minValue.\n this._playbackRate = createAudioParam(this, isOffline, nativeAudioBufferSourceNode.playbackRate, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n }\n get buffer() {\n if (this._isBufferNullified) {\n return null;\n }\n return this._nativeAudioBufferSourceNode.buffer;\n }\n set buffer(value) {\n this._nativeAudioBufferSourceNode.buffer = value;\n // Bug #72: Only Chrome & Edge do not allow to reassign the buffer yet.\n if (value !== null) {\n if (this._isBufferSet) {\n throw createInvalidStateError();\n }\n this._isBufferSet = true;\n }\n }\n get loop() {\n return this._nativeAudioBufferSourceNode.loop;\n }\n set loop(value) {\n this._nativeAudioBufferSourceNode.loop = value;\n }\n get loopEnd() {\n return this._nativeAudioBufferSourceNode.loopEnd;\n }\n set loopEnd(value) {\n this._nativeAudioBufferSourceNode.loopEnd = value;\n }\n get loopStart() {\n return this._nativeAudioBufferSourceNode.loopStart;\n }\n set loopStart(value) {\n this._nativeAudioBufferSourceNode.loopStart = value;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeAudioBufferSourceNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeAudioBufferSourceNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n get playbackRate() {\n return this._playbackRate;\n }\n start(when = 0, offset = 0, duration) {\n this._nativeAudioBufferSourceNode.start(when, offset, duration);\n if (this._audioBufferSourceNodeRenderer !== null) {\n this._audioBufferSourceNodeRenderer.start = duration === undefined ? [when, offset] : [when, offset, duration];\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeAudioBufferSourceNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeAudioBufferSourceNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeAudioBufferSourceNode.stop(when);\n if (this._audioBufferSourceNodeRenderer !== null) {\n this._audioBufferSourceNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=audio-buffer-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-source-node-renderer-factory.js\n\nconst createAudioBufferSourceNodeRendererFactory = (connectAudioParam, createNativeAudioBufferSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioBufferSourceNodes = new WeakMap();\n let start = null;\n let stop = null;\n const createAudioBufferSourceNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioBufferSourceNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeAudioBufferSourceNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeAudioBufferSourceNodeIsOwnedByContext = isOwnedByContext(nativeAudioBufferSourceNode, nativeOfflineAudioContext);\n if (!nativeAudioBufferSourceNodeIsOwnedByContext) {\n const options = {\n buffer: nativeAudioBufferSourceNode.buffer,\n channelCount: nativeAudioBufferSourceNode.channelCount,\n channelCountMode: nativeAudioBufferSourceNode.channelCountMode,\n channelInterpretation: nativeAudioBufferSourceNode.channelInterpretation,\n // Bug #149: Safari does not yet support the detune AudioParam.\n loop: nativeAudioBufferSourceNode.loop,\n loopEnd: nativeAudioBufferSourceNode.loopEnd,\n loopStart: nativeAudioBufferSourceNode.loopStart,\n playbackRate: nativeAudioBufferSourceNode.playbackRate.value\n };\n nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeAudioBufferSourceNode.start(...start);\n }\n if (stop !== null) {\n nativeAudioBufferSourceNode.stop(stop);\n }\n }\n renderedNativeAudioBufferSourceNodes.set(nativeOfflineAudioContext, nativeAudioBufferSourceNode);\n if (!nativeAudioBufferSourceNodeIsOwnedByContext) {\n // Bug #149: Safari does not yet support the detune AudioParam.\n await renderAutomation(nativeOfflineAudioContext, proxy.playbackRate, nativeAudioBufferSourceNode.playbackRate);\n }\n else {\n // Bug #149: Safari does not yet support the detune AudioParam.\n await connectAudioParam(nativeOfflineAudioContext, proxy.playbackRate, nativeAudioBufferSourceNode.playbackRate);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioBufferSourceNode);\n return nativeAudioBufferSourceNode;\n };\n return {\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioBufferSourceNode = renderedNativeAudioBufferSourceNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioBufferSourceNode !== undefined) {\n return Promise.resolve(renderedNativeAudioBufferSourceNode);\n }\n return createAudioBufferSourceNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=audio-buffer-source-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-buffer-source-node.js\nconst isAudioBufferSourceNode = (audioNode) => {\n return \'playbackRate\' in audioNode;\n};\n//# sourceMappingURL=audio-buffer-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/biquad-filter-node.js\nconst isBiquadFilterNode = (audioNode) => {\n return \'frequency\' in audioNode && \'gain\' in audioNode;\n};\n//# sourceMappingURL=biquad-filter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/constant-source-node.js\nconst isConstantSourceNode = (audioNode) => {\n return \'offset\' in audioNode;\n};\n//# sourceMappingURL=constant-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/gain-node.js\nconst isGainNode = (audioNode) => {\n return !(\'frequency\' in audioNode) && \'gain\' in audioNode;\n};\n//# sourceMappingURL=gain-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/oscillator-node.js\nconst isOscillatorNode = (audioNode) => {\n return \'detune\' in audioNode && \'frequency\' in audioNode;\n};\n//# sourceMappingURL=oscillator-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/stereo-panner-node.js\nconst isStereoPannerNode = (audioNode) => {\n return \'pan\' in audioNode;\n};\n//# sourceMappingURL=stereo-panner-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-node-connections.js\n\n\nconst getAudioNodeConnections = (audioNode) => {\n return getValueForKey(AUDIO_NODE_CONNECTIONS_STORE, audioNode);\n};\n//# sourceMappingURL=get-audio-node-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-param-connections.js\n\n\nconst getAudioParamConnections = (audioParam) => {\n return getValueForKey(AUDIO_PARAM_CONNECTIONS_STORE, audioParam);\n};\n//# sourceMappingURL=get-audio-param-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/deactivate-active-audio-node-input-connections.js\n\n\n\n\n\n\n\n\n\n\n\nconst deactivateActiveAudioNodeInputConnections = (audioNode, trace) => {\n const { activeInputs } = getAudioNodeConnections(audioNode);\n activeInputs.forEach((connections) => connections.forEach(([source]) => {\n if (!trace.includes(audioNode)) {\n deactivateActiveAudioNodeInputConnections(source, [...trace, audioNode]);\n }\n }));\n const audioParams = isAudioBufferSourceNode(audioNode)\n ? [\n // Bug #149: Safari does not yet support the detune AudioParam.\n audioNode.playbackRate\n ]\n : isAudioWorkletNode(audioNode)\n ? Array.from(audioNode.parameters.values())\n : isBiquadFilterNode(audioNode)\n ? [audioNode.Q, audioNode.detune, audioNode.frequency, audioNode.gain]\n : isConstantSourceNode(audioNode)\n ? [audioNode.offset]\n : isGainNode(audioNode)\n ? [audioNode.gain]\n : isOscillatorNode(audioNode)\n ? [audioNode.detune, audioNode.frequency]\n : isStereoPannerNode(audioNode)\n ? [audioNode.pan]\n : [];\n for (const audioParam of audioParams) {\n const audioParamConnections = getAudioParamConnections(audioParam);\n if (audioParamConnections !== undefined) {\n audioParamConnections.activeInputs.forEach(([source]) => deactivateActiveAudioNodeInputConnections(source, trace));\n }\n }\n if (isActiveAudioNode(audioNode)) {\n setInternalStateToPassive(audioNode);\n }\n};\n//# sourceMappingURL=deactivate-active-audio-node-input-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/deactivate-audio-graph.js\n\nconst deactivateAudioGraph = (context) => {\n deactivateActiveAudioNodeInputConnections(context.destination, []);\n};\n//# sourceMappingURL=deactivate-audio-graph.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-valid-latency-hint.js\nconst isValidLatencyHint = (latencyHint) => {\n return (latencyHint === undefined ||\n typeof latencyHint === \'number\' ||\n (typeof latencyHint === \'string\' && (latencyHint === \'balanced\' || latencyHint === \'interactive\' || latencyHint === \'playback\')));\n};\n//# sourceMappingURL=is-valid-latency-hint.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-context-constructor.js\n\n\nconst createAudioContextConstructor = (baseAudioContextConstructor, createInvalidStateError, createNotSupportedError, createUnknownError, mediaElementAudioSourceNodeConstructor, mediaStreamAudioDestinationNodeConstructor, mediaStreamAudioSourceNodeConstructor, mediaStreamTrackAudioSourceNodeConstructor, nativeAudioContextConstructor) => {\n return class AudioContext extends baseAudioContextConstructor {\n constructor(options = {}) {\n if (nativeAudioContextConstructor === null) {\n throw new Error(\'Missing the native AudioContext constructor.\');\n }\n let nativeAudioContext;\n try {\n nativeAudioContext = new nativeAudioContextConstructor(options);\n }\n catch (err) {\n // Bug #192 Safari does throw a SyntaxError if the sampleRate is not supported.\n if (err.code === 12 && err.message === \'sampleRate is not in range\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n // Bug #131 Safari returns null when there are four other AudioContexts running already.\n if (nativeAudioContext === null) {\n throw createUnknownError();\n }\n // Bug #51 Only Chrome and Edge throw an error if the given latencyHint is invalid.\n if (!isValidLatencyHint(options.latencyHint)) {\n throw new TypeError(`The provided value \'${options.latencyHint}\' is not a valid enum value of type AudioContextLatencyCategory.`);\n }\n // Bug #150 Safari does not support setting the sampleRate.\n if (options.sampleRate !== undefined && nativeAudioContext.sampleRate !== options.sampleRate) {\n throw createNotSupportedError();\n }\n super(nativeAudioContext, 2);\n const { latencyHint } = options;\n const { sampleRate } = nativeAudioContext;\n // @todo The values for \'balanced\', \'interactive\' and \'playback\' are just copied from Chrome\'s implementation.\n this._baseLatency =\n typeof nativeAudioContext.baseLatency === \'number\'\n ? nativeAudioContext.baseLatency\n : latencyHint === \'balanced\'\n ? 512 / sampleRate\n : latencyHint === \'interactive\' || latencyHint === undefined\n ? 256 / sampleRate\n : latencyHint === \'playback\'\n ? 1024 / sampleRate\n : /*\n * @todo The min (256) and max (16384) values are taken from the allowed bufferSize values of a\n * ScriptProcessorNode.\n */\n (Math.max(2, Math.min(128, Math.round((latencyHint * sampleRate) / 128))) * 128) / sampleRate;\n this._nativeAudioContext = nativeAudioContext;\n // Bug #188: Safari will set the context\'s state to \'interrupted\' in case the user switches tabs.\n if (nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n this._nativeGainNode = nativeAudioContext.createGain();\n this._nativeOscillatorNode = nativeAudioContext.createOscillator();\n this._nativeGainNode.gain.value = 1e-37;\n this._nativeOscillatorNode.connect(this._nativeGainNode).connect(nativeAudioContext.destination);\n this._nativeOscillatorNode.start();\n }\n else {\n this._nativeGainNode = null;\n this._nativeOscillatorNode = null;\n }\n this._state = null;\n /*\n * Bug #34: Chrome and Edge pretend to be running right away, but fire an onstatechange event when the state actually changes\n * to \'running\'.\n */\n if (nativeAudioContext.state === \'running\') {\n this._state = \'suspended\';\n const revokeState = () => {\n if (this._state === \'suspended\') {\n this._state = null;\n }\n nativeAudioContext.removeEventListener(\'statechange\', revokeState);\n };\n nativeAudioContext.addEventListener(\'statechange\', revokeState);\n }\n }\n get baseLatency() {\n return this._baseLatency;\n }\n get state() {\n return this._state !== null ? this._state : this._nativeAudioContext.state;\n }\n close() {\n // Bug #35: Firefox does not throw an error if the AudioContext was closed before.\n if (this.state === \'closed\') {\n return this._nativeAudioContext.close().then(() => {\n throw createInvalidStateError();\n });\n }\n // Bug #34: If the state was set to suspended before it should be revoked now.\n if (this._state === \'suspended\') {\n this._state = null;\n }\n return this._nativeAudioContext.close().then(() => {\n if (this._nativeGainNode !== null && this._nativeOscillatorNode !== null) {\n this._nativeOscillatorNode.stop();\n this._nativeGainNode.disconnect();\n this._nativeOscillatorNode.disconnect();\n }\n deactivateAudioGraph(this);\n });\n }\n createMediaElementSource(mediaElement) {\n return new mediaElementAudioSourceNodeConstructor(this, { mediaElement });\n }\n createMediaStreamDestination() {\n return new mediaStreamAudioDestinationNodeConstructor(this);\n }\n createMediaStreamSource(mediaStream) {\n return new mediaStreamAudioSourceNodeConstructor(this, { mediaStream });\n }\n createMediaStreamTrackSource(mediaStreamTrack) {\n return new mediaStreamTrackAudioSourceNodeConstructor(this, { mediaStreamTrack });\n }\n resume() {\n if (this._state === \'suspended\') {\n return new Promise((resolve, reject) => {\n const resolvePromise = () => {\n this._nativeAudioContext.removeEventListener(\'statechange\', resolvePromise);\n if (this._nativeAudioContext.state === \'running\') {\n resolve();\n }\n else {\n this.resume().then(resolve, reject);\n }\n };\n this._nativeAudioContext.addEventListener(\'statechange\', resolvePromise);\n });\n }\n return this._nativeAudioContext.resume().catch((err) => {\n // Bug #55: Chrome and Edge do throw an InvalidAccessError instead of an InvalidStateError.\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined || err.code === 15) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n suspend() {\n return this._nativeAudioContext.suspend().catch((err) => {\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-destination-node-constructor.js\nconst createAudioDestinationNodeConstructor = (audioNodeConstructor, createAudioDestinationNodeRenderer, createIndexSizeError, createInvalidStateError, createNativeAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext, renderInputsOfAudioNode) => {\n return class AudioDestinationNode extends audioNodeConstructor {\n constructor(context, channelCount) {\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const nativeAudioDestinationNode = createNativeAudioDestinationNode(nativeContext, channelCount, isOffline);\n const audioDestinationNodeRenderer = ((isOffline ? createAudioDestinationNodeRenderer(renderInputsOfAudioNode) : null));\n super(context, false, nativeAudioDestinationNode, audioDestinationNodeRenderer);\n this._isNodeOfNativeOfflineAudioContext = isOffline;\n this._nativeAudioDestinationNode = nativeAudioDestinationNode;\n }\n get channelCount() {\n return this._nativeAudioDestinationNode.channelCount;\n }\n set channelCount(value) {\n // Bug #52: Chrome, Edge & Safari do not throw an exception at all.\n // Bug #54: Firefox does throw an IndexSizeError.\n if (this._isNodeOfNativeOfflineAudioContext) {\n throw createInvalidStateError();\n }\n // Bug #47: The AudioDestinationNode in Safari does not initialize the maxChannelCount property correctly.\n if (value > this._nativeAudioDestinationNode.maxChannelCount) {\n throw createIndexSizeError();\n }\n this._nativeAudioDestinationNode.channelCount = value;\n }\n get channelCountMode() {\n return this._nativeAudioDestinationNode.channelCountMode;\n }\n set channelCountMode(value) {\n // Bug #53: No browser does throw an exception yet.\n if (this._isNodeOfNativeOfflineAudioContext) {\n throw createInvalidStateError();\n }\n this._nativeAudioDestinationNode.channelCountMode = value;\n }\n get maxChannelCount() {\n return this._nativeAudioDestinationNode.maxChannelCount;\n }\n };\n};\n//# sourceMappingURL=audio-destination-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-destination-node-renderer-factory.js\nconst createAudioDestinationNodeRenderer = (renderInputsOfAudioNode) => {\n const renderedNativeAudioDestinationNodes = new WeakMap();\n const createAudioDestinationNode = async (proxy, nativeOfflineAudioContext) => {\n const nativeAudioDestinationNode = nativeOfflineAudioContext.destination;\n renderedNativeAudioDestinationNodes.set(nativeOfflineAudioContext, nativeAudioDestinationNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioDestinationNode);\n return nativeAudioDestinationNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioDestinationNode = renderedNativeAudioDestinationNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioDestinationNode !== undefined) {\n return Promise.resolve(renderedNativeAudioDestinationNode);\n }\n return createAudioDestinationNode(proxy, nativeOfflineAudioContext);\n }\n };\n};\n//# sourceMappingURL=audio-destination-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-listener-factory.js\n\nconst createAudioListenerFactory = (createAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeScriptProcessorNode, createNotSupportedError, getFirstSample, isNativeOfflineAudioContext, overwriteAccessors) => {\n return (context, nativeContext) => {\n const nativeListener = nativeContext.listener;\n // Bug #117: Only Chrome & Edge support the new interface already.\n const createFakeAudioParams = () => {\n const buffer = new Float32Array(1);\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 9\n });\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n let isScriptProcessorNodeCreated = false;\n let lastOrientation = [0, 0, -1, 0, 1, 0];\n let lastPosition = [0, 0, 0];\n const createScriptProcessorNode = () => {\n if (isScriptProcessorNodeCreated) {\n return;\n }\n isScriptProcessorNodeCreated = true;\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, 256, 9, 0);\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer }) => {\n const orientation = [\n getFirstSample(inputBuffer, buffer, 0),\n getFirstSample(inputBuffer, buffer, 1),\n getFirstSample(inputBuffer, buffer, 2),\n getFirstSample(inputBuffer, buffer, 3),\n getFirstSample(inputBuffer, buffer, 4),\n getFirstSample(inputBuffer, buffer, 5)\n ];\n if (orientation.some((value, index) => value !== lastOrientation[index])) {\n nativeListener.setOrientation(...orientation); // tslint:disable-line:deprecation\n lastOrientation = orientation;\n }\n const positon = [\n getFirstSample(inputBuffer, buffer, 6),\n getFirstSample(inputBuffer, buffer, 7),\n getFirstSample(inputBuffer, buffer, 8)\n ];\n if (positon.some((value, index) => value !== lastPosition[index])) {\n nativeListener.setPosition(...positon); // tslint:disable-line:deprecation\n lastPosition = positon;\n }\n };\n channelMergerNode.connect(scriptProcessorNode);\n };\n const createSetOrientation = (index) => (value) => {\n if (value !== lastOrientation[index]) {\n lastOrientation[index] = value;\n nativeListener.setOrientation(...lastOrientation); // tslint:disable-line:deprecation\n }\n };\n const createSetPosition = (index) => (value) => {\n if (value !== lastPosition[index]) {\n lastPosition[index] = value;\n nativeListener.setPosition(...lastPosition); // tslint:disable-line:deprecation\n }\n };\n const createFakeAudioParam = (input, initialValue, setValue) => {\n const constantSourceNode = createNativeConstantSourceNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: initialValue\n });\n constantSourceNode.connect(channelMergerNode, 0, input);\n // @todo This should be stopped when the context is closed.\n constantSourceNode.start();\n Object.defineProperty(constantSourceNode.offset, \'defaultValue\', {\n get() {\n return initialValue;\n }\n });\n /*\n * Bug #62 & #74: Safari does not support ConstantSourceNodes and does not export the correct values for maxValue and\n * minValue for GainNodes.\n */\n const audioParam = createAudioParam({ context }, isOffline, constantSourceNode.offset, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n overwriteAccessors(audioParam, \'value\', (get) => () => get.call(audioParam), (set) => (value) => {\n try {\n set.call(audioParam, value);\n }\n catch (err) {\n if (err.code !== 9) {\n throw err;\n }\n }\n createScriptProcessorNode();\n if (isOffline) {\n // Bug #117: Using setOrientation() and setPosition() doesn\'t work with an OfflineAudioContext.\n setValue(value);\n }\n });\n audioParam.cancelAndHoldAtTime = ((cancelAndHoldAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = cancelAndHoldAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.cancelAndHoldAtTime);\n audioParam.cancelScheduledValues = ((cancelScheduledValues) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = cancelScheduledValues.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.cancelScheduledValues);\n audioParam.exponentialRampToValueAtTime = ((exponentialRampToValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = exponentialRampToValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.exponentialRampToValueAtTime);\n audioParam.linearRampToValueAtTime = ((linearRampToValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = linearRampToValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.linearRampToValueAtTime);\n audioParam.setTargetAtTime = ((setTargetAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setTargetAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setTargetAtTime);\n audioParam.setValueAtTime = ((setValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setValueAtTime);\n audioParam.setValueCurveAtTime = ((setValueCurveAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setValueCurveAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setValueCurveAtTime);\n return audioParam;\n };\n return {\n forwardX: createFakeAudioParam(0, 0, createSetOrientation(0)),\n forwardY: createFakeAudioParam(1, 0, createSetOrientation(1)),\n forwardZ: createFakeAudioParam(2, -1, createSetOrientation(2)),\n positionX: createFakeAudioParam(6, 0, createSetPosition(0)),\n positionY: createFakeAudioParam(7, 0, createSetPosition(1)),\n positionZ: createFakeAudioParam(8, 0, createSetPosition(2)),\n upX: createFakeAudioParam(3, 0, createSetOrientation(3)),\n upY: createFakeAudioParam(4, 1, createSetOrientation(4)),\n upZ: createFakeAudioParam(5, 0, createSetOrientation(5))\n };\n };\n const { forwardX, forwardY, forwardZ, positionX, positionY, positionZ, upX, upY, upZ } = nativeListener.forwardX === undefined ? createFakeAudioParams() : nativeListener;\n return {\n get forwardX() {\n return forwardX;\n },\n get forwardY() {\n return forwardY;\n },\n get forwardZ() {\n return forwardZ;\n },\n get positionX() {\n return positionX;\n },\n get positionY() {\n return positionY;\n },\n get positionZ() {\n return positionZ;\n },\n get upX() {\n return upX;\n },\n get upY() {\n return upY;\n },\n get upZ() {\n return upZ;\n }\n };\n };\n};\n//# sourceMappingURL=audio-listener-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-node.js\nconst isAudioNode = (audioNodeOrAudioParam) => {\n return \'context\' in audioNodeOrAudioParam;\n};\n//# sourceMappingURL=audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-node-output-connection.js\n\nconst isAudioNodeOutputConnection = (outputConnection) => {\n return isAudioNode(outputConnection[0]);\n};\n//# sourceMappingURL=audio-node-output-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/insert-element-in-set.js\nconst insertElementInSet = (set, element, predicate, ignoreDuplicates) => {\n for (const lmnt of set) {\n if (predicate(lmnt)) {\n if (ignoreDuplicates) {\n return false;\n }\n throw Error(\'The set contains at least one similar element.\');\n }\n }\n set.add(element);\n return true;\n};\n//# sourceMappingURL=insert-element-in-set.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/add-active-input-connection-to-audio-param.js\n\nconst addActiveInputConnectionToAudioParam = (activeInputs, source, [output, eventListener], ignoreDuplicates) => {\n insertElementInSet(activeInputs, [source, output, eventListener], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output, ignoreDuplicates);\n};\n//# sourceMappingURL=add-active-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/add-passive-input-connection-to-audio-param.js\n\nconst addPassiveInputConnectionToAudioParam = (passiveInputs, [source, output, eventListener], ignoreDuplicates) => {\n const passiveInputConnections = passiveInputs.get(source);\n if (passiveInputConnections === undefined) {\n passiveInputs.set(source, new Set([[output, eventListener]]));\n }\n else {\n insertElementInSet(passiveInputConnections, [output, eventListener], (passiveInputConnection) => passiveInputConnection[0] === output, ignoreDuplicates);\n }\n};\n//# sourceMappingURL=add-passive-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/native-audio-node-faker.js\nconst isNativeAudioNodeFaker = (nativeAudioNodeOrNativeAudioNodeFaker) => {\n return \'inputs\' in nativeAudioNodeOrNativeAudioNodeFaker;\n};\n//# sourceMappingURL=native-audio-node-faker.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/connect-native-audio-node-to-native-audio-node.js\n\nconst connectNativeAudioNodeToNativeAudioNode = (nativeSourceAudioNode, nativeDestinationAudioNode, output, input) => {\n if (isNativeAudioNodeFaker(nativeDestinationAudioNode)) {\n const fakeNativeDestinationAudioNode = nativeDestinationAudioNode.inputs[input];\n nativeSourceAudioNode.connect(fakeNativeDestinationAudioNode, output, 0);\n return [fakeNativeDestinationAudioNode, output, 0];\n }\n nativeSourceAudioNode.connect(nativeDestinationAudioNode, output, input);\n return [nativeDestinationAudioNode, output, input];\n};\n//# sourceMappingURL=connect-native-audio-node-to-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-active-input-connection.js\nconst deleteActiveInputConnection = (activeInputConnections, source, output) => {\n for (const activeInputConnection of activeInputConnections) {\n if (activeInputConnection[0] === source && activeInputConnection[1] === output) {\n activeInputConnections.delete(activeInputConnection);\n return activeInputConnection;\n }\n }\n return null;\n};\n//# sourceMappingURL=delete-active-input-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-active-input-connection-to-audio-param.js\n\nconst deleteActiveInputConnectionToAudioParam = (activeInputs, source, output) => {\n return pickElementFromSet(activeInputs, (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output);\n};\n//# sourceMappingURL=delete-active-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-event-listeners-of-audio-node.js\n\nconst deleteEventListenerOfAudioNode = (audioNode, eventListener) => {\n const eventListeners = getEventListenersOfAudioNode(audioNode);\n if (!eventListeners.delete(eventListener)) {\n throw new Error(\'Missing the expected event listener.\');\n }\n};\n//# sourceMappingURL=delete-event-listeners-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-passive-input-connection-to-audio-param.js\n\n\nconst deletePassiveInputConnectionToAudioParam = (passiveInputs, source, output) => {\n const passiveInputConnections = getValueForKey(passiveInputs, source);\n const matchingConnection = pickElementFromSet(passiveInputConnections, (passiveInputConnection) => passiveInputConnection[0] === output);\n if (passiveInputConnections.size === 0) {\n passiveInputs.delete(source);\n }\n return matchingConnection;\n};\n//# sourceMappingURL=delete-passive-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/disconnect-native-audio-node-from-native-audio-node.js\n\nconst disconnectNativeAudioNodeFromNativeAudioNode = (nativeSourceAudioNode, nativeDestinationAudioNode, output, input) => {\n if (isNativeAudioNodeFaker(nativeDestinationAudioNode)) {\n nativeSourceAudioNode.disconnect(nativeDestinationAudioNode.inputs[input], output, 0);\n }\n else {\n nativeSourceAudioNode.disconnect(nativeDestinationAudioNode, output, input);\n }\n};\n//# sourceMappingURL=disconnect-native-audio-node-from-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-native-audio-node.js\n\n\nconst getNativeAudioNode = (audioNode) => {\n return getValueForKey(AUDIO_NODE_STORE, audioNode);\n};\n//# sourceMappingURL=get-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-native-audio-param.js\n\n\nconst getNativeAudioParam = (audioParam) => {\n return getValueForKey(AUDIO_PARAM_STORE, audioParam);\n};\n//# sourceMappingURL=get-native-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-part-of-a-cycle.js\n\nconst isPartOfACycle = (audioNode) => {\n return CYCLE_COUNTERS.has(audioNode);\n};\n//# sourceMappingURL=is-part-of-a-cycle.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-passive-audio-node.js\n\nconst isPassiveAudioNode = (audioNode) => {\n return !ACTIVE_AUDIO_NODE_STORE.has(audioNode);\n};\n//# sourceMappingURL=is-passive-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-node-disconnect-method-support.js\nconst testAudioNodeDisconnectMethodSupport = (nativeAudioContext, nativeAudioWorkletNodeConstructor) => {\n return new Promise((resolve) => {\n /*\n * This bug existed in Safari up until v14.0.2. Since AudioWorklets were not supported in Safari until v14.1 the presence of the\n * constructor for an AudioWorkletNode can be used here to skip the test.\n */\n if (nativeAudioWorkletNodeConstructor !== null) {\n resolve(true);\n }\n else {\n const analyzer = nativeAudioContext.createScriptProcessor(256, 1, 1); // tslint:disable-line deprecation\n const dummy = nativeAudioContext.createGain();\n // Bug #95: Safari does not play one sample buffers.\n const ones = nativeAudioContext.createBuffer(1, 2, 44100);\n const channelData = ones.getChannelData(0);\n channelData[0] = 1;\n channelData[1] = 1;\n const source = nativeAudioContext.createBufferSource();\n source.buffer = ones;\n source.loop = true;\n source.connect(analyzer).connect(nativeAudioContext.destination);\n source.connect(dummy);\n source.disconnect(dummy);\n // tslint:disable-next-line:deprecation\n analyzer.onaudioprocess = (event) => {\n const chnnlDt = event.inputBuffer.getChannelData(0); // tslint:disable-line deprecation\n if (Array.prototype.some.call(chnnlDt, (sample) => sample === 1)) {\n resolve(true);\n }\n else {\n resolve(false);\n }\n source.stop();\n analyzer.onaudioprocess = null; // tslint:disable-line:deprecation\n source.disconnect(analyzer);\n analyzer.disconnect(nativeAudioContext.destination);\n };\n source.start();\n }\n });\n};\n//# sourceMappingURL=test-audio-node-disconnect-method-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/visit-each-audio-node-once.js\nconst visitEachAudioNodeOnce = (cycles, visitor) => {\n const counts = new Map();\n for (const cycle of cycles) {\n for (const audioNode of cycle) {\n const count = counts.get(audioNode);\n counts.set(audioNode, count === undefined ? 1 : count + 1);\n }\n }\n counts.forEach((count, audioNode) => visitor(audioNode, count));\n};\n//# sourceMappingURL=visit-each-audio-node-once.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/native-audio-node.js\nconst isNativeAudioNode = (nativeAudioNodeOrAudioParam) => {\n return \'context\' in nativeAudioNodeOrAudioParam;\n};\n//# sourceMappingURL=native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-node-disconnect-method.js\n\nconst wrapAudioNodeDisconnectMethod = (nativeAudioNode) => {\n const connections = new Map();\n nativeAudioNode.connect = ((connect) => {\n // tslint:disable-next-line:invalid-void no-inferrable-types\n return (destination, output = 0, input = 0) => {\n const returnValue = isNativeAudioNode(destination) ? connect(destination, output, input) : connect(destination, output);\n // Save the new connection only if the calls to connect above didn\'t throw an error.\n const connectionsToDestination = connections.get(destination);\n if (connectionsToDestination === undefined) {\n connections.set(destination, [{ input, output }]);\n }\n else {\n if (connectionsToDestination.every((connection) => connection.input !== input || connection.output !== output)) {\n connectionsToDestination.push({ input, output });\n }\n }\n return returnValue;\n };\n })(nativeAudioNode.connect.bind(nativeAudioNode));\n nativeAudioNode.disconnect = ((disconnect) => {\n return (destinationOrOutput, output, input) => {\n disconnect.apply(nativeAudioNode);\n if (destinationOrOutput === undefined) {\n connections.clear();\n }\n else if (typeof destinationOrOutput === \'number\') {\n for (const [destination, connectionsToDestination] of connections) {\n const filteredConnections = connectionsToDestination.filter((connection) => connection.output !== destinationOrOutput);\n if (filteredConnections.length === 0) {\n connections.delete(destination);\n }\n else {\n connections.set(destination, filteredConnections);\n }\n }\n }\n else if (connections.has(destinationOrOutput)) {\n if (output === undefined) {\n connections.delete(destinationOrOutput);\n }\n else {\n const connectionsToDestination = connections.get(destinationOrOutput);\n if (connectionsToDestination !== undefined) {\n const filteredConnections = connectionsToDestination.filter((connection) => connection.output !== output && (connection.input !== input || input === undefined));\n if (filteredConnections.length === 0) {\n connections.delete(destinationOrOutput);\n }\n else {\n connections.set(destinationOrOutput, filteredConnections);\n }\n }\n }\n }\n for (const [destination, connectionsToDestination] of connections) {\n connectionsToDestination.forEach((connection) => {\n if (isNativeAudioNode(destination)) {\n nativeAudioNode.connect(destination, connection.output, connection.input);\n }\n else {\n nativeAudioNode.connect(destination, connection.output);\n }\n });\n }\n };\n })(nativeAudioNode.disconnect);\n};\n//# sourceMappingURL=wrap-audio-node-disconnect-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-node-constructor.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst addConnectionToAudioParamOfAudioContext = (source, destination, output, isOffline) => {\n const { activeInputs, passiveInputs } = getAudioParamConnections(destination);\n const { outputs } = getAudioNodeConnections(source);\n const eventListeners = getEventListenersOfAudioNode(source);\n const eventListener = (isActive) => {\n const nativeAudioNode = getNativeAudioNode(source);\n const nativeAudioParam = getNativeAudioParam(destination);\n if (isActive) {\n const partialConnection = deletePassiveInputConnectionToAudioParam(passiveInputs, source, output);\n addActiveInputConnectionToAudioParam(activeInputs, source, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n nativeAudioNode.connect(nativeAudioParam, output);\n }\n }\n else {\n const partialConnection = deleteActiveInputConnectionToAudioParam(activeInputs, source, output);\n addPassiveInputConnectionToAudioParam(passiveInputs, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n nativeAudioNode.disconnect(nativeAudioParam, output);\n }\n }\n };\n if (insertElementInSet(outputs, [destination, output], (outputConnection) => outputConnection[0] === destination && outputConnection[1] === output, true)) {\n eventListeners.add(eventListener);\n if (isActiveAudioNode(source)) {\n addActiveInputConnectionToAudioParam(activeInputs, source, [output, eventListener], true);\n }\n else {\n addPassiveInputConnectionToAudioParam(passiveInputs, [source, output, eventListener], true);\n }\n return true;\n }\n return false;\n};\nconst deleteInputConnectionOfAudioNode = (source, destination, output, input) => {\n const { activeInputs, passiveInputs } = getAudioNodeConnections(destination);\n const activeInputConnection = deleteActiveInputConnection(activeInputs[input], source, output);\n if (activeInputConnection === null) {\n const passiveInputConnection = deletePassiveInputConnectionToAudioNode(passiveInputs, source, output, input);\n return [passiveInputConnection[2], false];\n }\n return [activeInputConnection[2], true];\n};\nconst deleteInputConnectionOfAudioParam = (source, destination, output) => {\n const { activeInputs, passiveInputs } = getAudioParamConnections(destination);\n const activeInputConnection = deleteActiveInputConnection(activeInputs, source, output);\n if (activeInputConnection === null) {\n const passiveInputConnection = deletePassiveInputConnectionToAudioParam(passiveInputs, source, output);\n return [passiveInputConnection[1], false];\n }\n return [activeInputConnection[2], true];\n};\nconst deleteInputsOfAudioNode = (source, isOffline, destination, output, input) => {\n const [listener, isActive] = deleteInputConnectionOfAudioNode(source, destination, output, input);\n if (listener !== null) {\n deleteEventListenerOfAudioNode(source, listener);\n if (isActive && !isOffline && !isPartOfACycle(source)) {\n disconnectNativeAudioNodeFromNativeAudioNode(getNativeAudioNode(source), getNativeAudioNode(destination), output, input);\n }\n }\n if (isActiveAudioNode(destination)) {\n const { activeInputs } = getAudioNodeConnections(destination);\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n};\nconst deleteInputsOfAudioParam = (source, isOffline, destination, output) => {\n const [listener, isActive] = deleteInputConnectionOfAudioParam(source, destination, output);\n if (listener !== null) {\n deleteEventListenerOfAudioNode(source, listener);\n if (isActive && !isOffline && !isPartOfACycle(source)) {\n getNativeAudioNode(source).disconnect(getNativeAudioParam(destination), output);\n }\n }\n};\nconst deleteAnyConnection = (source, isOffline) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n const destinations = [];\n for (const outputConnection of audioNodeConnectionsOfSource.outputs) {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n destinations.push(outputConnection[0]);\n }\n audioNodeConnectionsOfSource.outputs.clear();\n return destinations;\n};\nconst deleteConnectionAtOutput = (source, isOffline, output) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n const destinations = [];\n for (const outputConnection of audioNodeConnectionsOfSource.outputs) {\n if (outputConnection[1] === output) {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n destinations.push(outputConnection[0]);\n audioNodeConnectionsOfSource.outputs.delete(outputConnection);\n }\n }\n return destinations;\n};\nconst deleteConnectionToDestination = (source, isOffline, destination, output, input) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n return Array.from(audioNodeConnectionsOfSource.outputs)\n .filter((outputConnection) => outputConnection[0] === destination &&\n (output === undefined || outputConnection[1] === output) &&\n (input === undefined || outputConnection[2] === input))\n .map((outputConnection) => {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n audioNodeConnectionsOfSource.outputs.delete(outputConnection);\n return outputConnection[0];\n });\n};\nconst createAudioNodeConstructor = (addAudioNodeConnections, addConnectionToAudioNode, cacheTestResult, createIncrementCycleCounter, createIndexSizeError, createInvalidAccessError, createNotSupportedError, decrementCycleCounter, detectCycles, eventTargetConstructor, getNativeContext, isNativeAudioContext, isNativeAudioNode, isNativeAudioParam, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor) => {\n return class AudioNode extends eventTargetConstructor {\n constructor(context, isActive, nativeAudioNode, audioNodeRenderer) {\n super(nativeAudioNode);\n this._context = context;\n this._nativeAudioNode = nativeAudioNode;\n const nativeContext = getNativeContext(context);\n // Bug #12: Safari does not support to disconnect a specific destination.\n if (isNativeAudioContext(nativeContext) &&\n true !==\n cacheTestResult(testAudioNodeDisconnectMethodSupport, () => {\n return testAudioNodeDisconnectMethodSupport(nativeContext, nativeAudioWorkletNodeConstructor);\n })) {\n wrapAudioNodeDisconnectMethod(nativeAudioNode);\n }\n AUDIO_NODE_STORE.set(this, nativeAudioNode);\n EVENT_LISTENERS.set(this, new Set());\n if (context.state !== \'closed\' && isActive) {\n setInternalStateToActive(this);\n }\n addAudioNodeConnections(this, audioNodeRenderer, nativeAudioNode);\n }\n get channelCount() {\n return this._nativeAudioNode.channelCount;\n }\n set channelCount(value) {\n this._nativeAudioNode.channelCount = value;\n }\n get channelCountMode() {\n return this._nativeAudioNode.channelCountMode;\n }\n set channelCountMode(value) {\n this._nativeAudioNode.channelCountMode = value;\n }\n get channelInterpretation() {\n return this._nativeAudioNode.channelInterpretation;\n }\n set channelInterpretation(value) {\n this._nativeAudioNode.channelInterpretation = value;\n }\n get context() {\n return this._context;\n }\n get numberOfInputs() {\n return this._nativeAudioNode.numberOfInputs;\n }\n get numberOfOutputs() {\n return this._nativeAudioNode.numberOfOutputs;\n }\n // tslint:disable-next-line:invalid-void\n connect(destination, output = 0, input = 0) {\n // Bug #174: Safari does expose a wrong numberOfOutputs for MediaStreamAudioDestinationNodes.\n if (output < 0 || output >= this._nativeAudioNode.numberOfOutputs) {\n throw createIndexSizeError();\n }\n const nativeContext = getNativeContext(this._context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (isNativeAudioNode(destination) || isNativeAudioParam(destination)) {\n throw createInvalidAccessError();\n }\n if (isAudioNode(destination)) {\n const nativeDestinationAudioNode = getNativeAudioNode(destination);\n try {\n const connection = connectNativeAudioNodeToNativeAudioNode(this._nativeAudioNode, nativeDestinationAudioNode, output, input);\n const isPassive = isPassiveAudioNode(this);\n if (isOffline || isPassive) {\n this._nativeAudioNode.disconnect(...connection);\n }\n if (this.context.state !== \'closed\' && !isPassive && isPassiveAudioNode(destination)) {\n setInternalStateToActive(destination);\n }\n }\n catch (err) {\n // Bug #41: Safari does not throw the correct exception so far.\n if (err.code === 12) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n const isNewConnectionToAudioNode = addConnectionToAudioNode(this, destination, output, input, isOffline);\n // Bug #164: Only Firefox detects cycles so far.\n if (isNewConnectionToAudioNode) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, createIncrementCycleCounter(isOffline));\n }\n return destination;\n }\n const nativeAudioParam = getNativeAudioParam(destination);\n /*\n * Bug #73, #147 & #153: Safari does not support to connect an input signal to the playbackRate AudioParam of an\n * AudioBufferSourceNode. This can\'t be easily detected and that\'s why the outdated name property is used here to identify\n * Safari. In addition to that the maxValue property is used to only detect the affected versions below v14.0.2.\n */\n if (nativeAudioParam.name === \'playbackRate\' && nativeAudioParam.maxValue === 1024) {\n throw createNotSupportedError();\n }\n try {\n this._nativeAudioNode.connect(nativeAudioParam, output);\n if (isOffline || isPassiveAudioNode(this)) {\n this._nativeAudioNode.disconnect(nativeAudioParam, output);\n }\n }\n catch (err) {\n // Bug #58: Safari doesn\'t throw an InvalidAccessError yet.\n if (err.code === 12) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n const isNewConnectionToAudioParam = addConnectionToAudioParamOfAudioContext(this, destination, output, isOffline);\n // Bug #164: Only Firefox detects cycles so far.\n if (isNewConnectionToAudioParam) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, createIncrementCycleCounter(isOffline));\n }\n }\n disconnect(destinationOrOutput, output, input) {\n let destinations;\n const nativeContext = getNativeContext(this._context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (destinationOrOutput === undefined) {\n destinations = deleteAnyConnection(this, isOffline);\n }\n else if (typeof destinationOrOutput === \'number\') {\n if (destinationOrOutput < 0 || destinationOrOutput >= this.numberOfOutputs) {\n throw createIndexSizeError();\n }\n destinations = deleteConnectionAtOutput(this, isOffline, destinationOrOutput);\n }\n else {\n if (output !== undefined && (output < 0 || output >= this.numberOfOutputs)) {\n throw createIndexSizeError();\n }\n if (isAudioNode(destinationOrOutput) && input !== undefined && (input < 0 || input >= destinationOrOutput.numberOfInputs)) {\n throw createIndexSizeError();\n }\n destinations = deleteConnectionToDestination(this, isOffline, destinationOrOutput, output, input);\n if (destinations.length === 0) {\n throw createInvalidAccessError();\n }\n }\n // Bug #164: Only Firefox detects cycles so far.\n for (const destination of destinations) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, decrementCycleCounter);\n }\n }\n };\n};\n//# sourceMappingURL=audio-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-param-factory.js\n\nconst createAudioParamFactory = (addAudioParamConnections, audioParamAudioNodeStore, audioParamStore, createAudioParamRenderer, createCancelAndHoldAutomationEvent, createCancelScheduledValuesAutomationEvent, createExponentialRampToValueAutomationEvent, createLinearRampToValueAutomationEvent, createSetTargetAutomationEvent, createSetValueAutomationEvent, createSetValueCurveAutomationEvent, nativeAudioContextConstructor, setValueAtTimeUntilPossible) => {\n return (audioNode, isAudioParamOfOfflineAudioContext, nativeAudioParam, maxValue = null, minValue = null) => {\n // Bug #196 Only Safari sets the defaultValue to the initial value.\n const defaultValue = nativeAudioParam.value;\n const automationEventList = new bundle.AutomationEventList(defaultValue);\n const audioParamRenderer = isAudioParamOfOfflineAudioContext ? createAudioParamRenderer(automationEventList) : null;\n const audioParam = {\n get defaultValue() {\n return defaultValue;\n },\n get maxValue() {\n return maxValue === null ? nativeAudioParam.maxValue : maxValue;\n },\n get minValue() {\n return minValue === null ? nativeAudioParam.minValue : minValue;\n },\n get value() {\n return nativeAudioParam.value;\n },\n set value(value) {\n nativeAudioParam.value = value;\n // Bug #98: Firefox & Safari do not yet treat the value setter like a call to setValueAtTime().\n audioParam.setValueAtTime(value, audioNode.context.currentTime);\n },\n cancelAndHoldAtTime(cancelTime) {\n // Bug #28: Firefox & Safari do not yet implement cancelAndHoldAtTime().\n if (typeof nativeAudioParam.cancelAndHoldAtTime === \'function\') {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelAndHoldAutomationEvent(cancelTime));\n nativeAudioParam.cancelAndHoldAtTime(cancelTime);\n }\n else {\n const previousLastEvent = Array.from(automationEventList).pop();\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelAndHoldAutomationEvent(cancelTime));\n const currentLastEvent = Array.from(automationEventList).pop();\n nativeAudioParam.cancelScheduledValues(cancelTime);\n if (previousLastEvent !== currentLastEvent && currentLastEvent !== undefined) {\n if (currentLastEvent.type === \'exponentialRampToValue\') {\n nativeAudioParam.exponentialRampToValueAtTime(currentLastEvent.value, currentLastEvent.endTime);\n }\n else if (currentLastEvent.type === \'linearRampToValue\') {\n nativeAudioParam.linearRampToValueAtTime(currentLastEvent.value, currentLastEvent.endTime);\n }\n else if (currentLastEvent.type === \'setValue\') {\n nativeAudioParam.setValueAtTime(currentLastEvent.value, currentLastEvent.startTime);\n }\n else if (currentLastEvent.type === \'setValueCurve\') {\n nativeAudioParam.setValueCurveAtTime(currentLastEvent.values, currentLastEvent.startTime, currentLastEvent.duration);\n }\n }\n }\n return audioParam;\n },\n cancelScheduledValues(cancelTime) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelScheduledValuesAutomationEvent(cancelTime));\n nativeAudioParam.cancelScheduledValues(cancelTime);\n return audioParam;\n },\n exponentialRampToValueAtTime(value, endTime) {\n // Bug #45: Safari does not throw an error yet.\n if (value === 0) {\n throw new RangeError();\n }\n // Bug #187: Safari does not throw an error yet.\n if (!Number.isFinite(endTime) || endTime < 0) {\n throw new RangeError();\n }\n const currentTime = audioNode.context.currentTime;\n if (audioParamRenderer === null) {\n automationEventList.flush(currentTime);\n }\n // Bug #194: Firefox does not implicitly call setValueAtTime() if there is no previous event.\n if (Array.from(automationEventList).length === 0) {\n automationEventList.add(createSetValueAutomationEvent(defaultValue, currentTime));\n nativeAudioParam.setValueAtTime(defaultValue, currentTime);\n }\n automationEventList.add(createExponentialRampToValueAutomationEvent(value, endTime));\n nativeAudioParam.exponentialRampToValueAtTime(value, endTime);\n return audioParam;\n },\n linearRampToValueAtTime(value, endTime) {\n const currentTime = audioNode.context.currentTime;\n if (audioParamRenderer === null) {\n automationEventList.flush(currentTime);\n }\n // Bug #195: Firefox does not implicitly call setValueAtTime() if there is no previous event.\n if (Array.from(automationEventList).length === 0) {\n automationEventList.add(createSetValueAutomationEvent(defaultValue, currentTime));\n nativeAudioParam.setValueAtTime(defaultValue, currentTime);\n }\n automationEventList.add(createLinearRampToValueAutomationEvent(value, endTime));\n nativeAudioParam.linearRampToValueAtTime(value, endTime);\n return audioParam;\n },\n setTargetAtTime(target, startTime, timeConstant) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetTargetAutomationEvent(target, startTime, timeConstant));\n nativeAudioParam.setTargetAtTime(target, startTime, timeConstant);\n return audioParam;\n },\n setValueAtTime(value, startTime) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueAutomationEvent(value, startTime));\n nativeAudioParam.setValueAtTime(value, startTime);\n return audioParam;\n },\n setValueCurveAtTime(values, startTime, duration) {\n // Bug 183: Safari only accepts a Float32Array.\n const convertedValues = values instanceof Float32Array ? values : new Float32Array(values);\n /*\n * Bug #152: Safari does not correctly interpolate the values of the curve.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the\n * existence of the webkitAudioContext is used as a workaround here.\n */\n if (nativeAudioContextConstructor !== null && nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n const endTime = startTime + duration;\n const sampleRate = audioNode.context.sampleRate;\n const firstSample = Math.ceil(startTime * sampleRate);\n const lastSample = Math.floor(endTime * sampleRate);\n const numberOfInterpolatedValues = lastSample - firstSample;\n const interpolatedValues = new Float32Array(numberOfInterpolatedValues);\n for (let i = 0; i < numberOfInterpolatedValues; i += 1) {\n const theoreticIndex = ((convertedValues.length - 1) / duration) * ((firstSample + i) / sampleRate - startTime);\n const lowerIndex = Math.floor(theoreticIndex);\n const upperIndex = Math.ceil(theoreticIndex);\n interpolatedValues[i] =\n lowerIndex === upperIndex\n ? convertedValues[lowerIndex]\n : (1 - (theoreticIndex - lowerIndex)) * convertedValues[lowerIndex] +\n (1 - (upperIndex - theoreticIndex)) * convertedValues[upperIndex];\n }\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueCurveAutomationEvent(interpolatedValues, startTime, duration));\n nativeAudioParam.setValueCurveAtTime(interpolatedValues, startTime, duration);\n const timeOfLastSample = lastSample / sampleRate;\n if (timeOfLastSample < endTime) {\n setValueAtTimeUntilPossible(audioParam, interpolatedValues[interpolatedValues.length - 1], timeOfLastSample);\n }\n setValueAtTimeUntilPossible(audioParam, convertedValues[convertedValues.length - 1], endTime);\n }\n else {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueCurveAutomationEvent(convertedValues, startTime, duration));\n nativeAudioParam.setValueCurveAtTime(convertedValues, startTime, duration);\n }\n return audioParam;\n }\n };\n audioParamStore.set(audioParam, nativeAudioParam);\n audioParamAudioNodeStore.set(audioParam, audioNode);\n addAudioParamConnections(audioParam, audioParamRenderer);\n return audioParam;\n };\n};\n//# sourceMappingURL=audio-param-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-param-renderer.js\nconst createAudioParamRenderer = (automationEventList) => {\n return {\n replay(audioParam) {\n for (const automationEvent of automationEventList) {\n if (automationEvent.type === \'exponentialRampToValue\') {\n const { endTime, value } = automationEvent;\n audioParam.exponentialRampToValueAtTime(value, endTime);\n }\n else if (automationEvent.type === \'linearRampToValue\') {\n const { endTime, value } = automationEvent;\n audioParam.linearRampToValueAtTime(value, endTime);\n }\n else if (automationEvent.type === \'setTarget\') {\n const { startTime, target, timeConstant } = automationEvent;\n audioParam.setTargetAtTime(target, startTime, timeConstant);\n }\n else if (automationEvent.type === \'setValue\') {\n const { startTime, value } = automationEvent;\n audioParam.setValueAtTime(value, startTime);\n }\n else if (automationEvent.type === \'setValueCurve\') {\n const { duration, startTime, values } = automationEvent;\n audioParam.setValueCurveAtTime(values, startTime, duration);\n }\n else {\n throw new Error("Can\'t apply an unknown automation.");\n }\n }\n }\n };\n};\n//# sourceMappingURL=audio-param-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/read-only-map.js\nclass ReadOnlyMap {\n constructor(parameters) {\n this._map = new Map(parameters);\n }\n get size() {\n return this._map.size;\n }\n entries() {\n return this._map.entries();\n }\n forEach(callback, thisArg = null) {\n return this._map.forEach((value, key) => callback.call(thisArg, value, key, this));\n }\n get(name) {\n return this._map.get(name);\n }\n has(name) {\n return this._map.has(name);\n }\n keys() {\n return this._map.keys();\n }\n values() {\n return this._map.values();\n }\n}\n//# sourceMappingURL=read-only-map.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-worklet-node-constructor.js\n\n\nconst audio_worklet_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n // Bug #61: The channelCountMode should be \'max\' according to the spec but is set to \'explicit\' to achieve consistent behavior.\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {},\n processorOptions: {}\n};\nconst createAudioWorkletNodeConstructor = (addUnrenderedAudioWorkletNode, audioNodeConstructor, createAudioParam, createAudioWorkletNodeRenderer, createNativeAudioWorkletNode, getAudioNodeConnections, getBackupOfflineAudioContext, getNativeContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, sanitizeAudioWorkletNodeOptions, setActiveAudioWorkletNodeInputs, testAudioWorkletNodeOptionsClonability, wrapEventListener) => {\n return class AudioWorkletNode extends audioNodeConstructor {\n constructor(context, name, options) {\n var _a;\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const mergedOptions = sanitizeAudioWorkletNodeOptions({ ...audio_worklet_node_constructor_DEFAULT_OPTIONS, ...options });\n // Bug #191: Safari doesn\'t throw an error if the options aren\'t clonable.\n testAudioWorkletNodeOptionsClonability(mergedOptions);\n const nodeNameToProcessorConstructorMap = NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.get(nativeContext);\n const processorConstructor = nodeNameToProcessorConstructorMap === null || nodeNameToProcessorConstructorMap === void 0 ? void 0 : nodeNameToProcessorConstructorMap.get(name);\n // Bug #186: Chrome and Edge do not allow to create an AudioWorkletNode on a closed AudioContext.\n const nativeContextOrBackupOfflineAudioContext = isOffline || nativeContext.state !== \'closed\'\n ? nativeContext\n : (_a = getBackupOfflineAudioContext(nativeContext)) !== null && _a !== void 0 ? _a : nativeContext;\n const nativeAudioWorkletNode = createNativeAudioWorkletNode(nativeContextOrBackupOfflineAudioContext, isOffline ? null : context.baseLatency, nativeAudioWorkletNodeConstructor, name, processorConstructor, mergedOptions);\n const audioWorkletNodeRenderer = ((isOffline ? createAudioWorkletNodeRenderer(name, mergedOptions, processorConstructor) : null));\n /*\n * @todo Add a mechanism to switch an AudioWorkletNode to passive once the process() function of the AudioWorkletProcessor\n * returns false.\n */\n super(context, true, nativeAudioWorkletNode, audioWorkletNodeRenderer);\n const parameters = [];\n nativeAudioWorkletNode.parameters.forEach((nativeAudioParam, nm) => {\n const audioParam = createAudioParam(this, isOffline, nativeAudioParam);\n parameters.push([nm, audioParam]);\n });\n this._nativeAudioWorkletNode = nativeAudioWorkletNode;\n this._onprocessorerror = null;\n this._parameters = new ReadOnlyMap(parameters);\n /*\n * Bug #86 & #87: Invoking the renderer of an AudioWorkletNode might be necessary if it has no direct or indirect connection to\n * the destination.\n */\n if (isOffline) {\n addUnrenderedAudioWorkletNode(nativeContext, this);\n }\n const { activeInputs } = getAudioNodeConnections(this);\n setActiveAudioWorkletNodeInputs(nativeAudioWorkletNode, activeInputs);\n }\n get onprocessorerror() {\n return this._onprocessorerror;\n }\n set onprocessorerror(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeAudioWorkletNode.onprocessorerror = wrappedListener;\n const nativeOnProcessorError = this._nativeAudioWorkletNode.onprocessorerror;\n this._onprocessorerror =\n nativeOnProcessorError !== null && nativeOnProcessorError === wrappedListener\n ? value\n : nativeOnProcessorError;\n }\n get parameters() {\n if (this._parameters === null) {\n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n return this._nativeAudioWorkletNode.parameters;\n }\n return this._parameters;\n }\n get port() {\n return this._nativeAudioWorkletNode.port;\n }\n };\n};\n//# sourceMappingURL=audio-worklet-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/copy-from-channel.js\nfunction copyFromChannel(audioBuffer, \n// @todo There is currently no way to define something like { [ key: number | string ]: Float32Array }\nparent, key, channelNumber, bufferOffset) {\n if (typeof audioBuffer.copyFromChannel === \'function\') {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength === 0) {\n parent[key] = new Float32Array(128);\n }\n audioBuffer.copyFromChannel(parent[key], channelNumber, bufferOffset);\n // Bug #5: Safari does not support copyFromChannel().\n }\n else {\n const channelData = audioBuffer.getChannelData(channelNumber);\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength === 0) {\n parent[key] = channelData.slice(bufferOffset, bufferOffset + 128);\n }\n else {\n const slicedInput = new Float32Array(channelData.buffer, bufferOffset * Float32Array.BYTES_PER_ELEMENT, 128);\n parent[key].set(slicedInput);\n }\n }\n}\n//# sourceMappingURL=copy-from-channel.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/copy-to-channel.js\nconst copyToChannel = (audioBuffer, parent, key, channelNumber, bufferOffset) => {\n if (typeof audioBuffer.copyToChannel === \'function\') {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength !== 0) {\n audioBuffer.copyToChannel(parent[key], channelNumber, bufferOffset);\n }\n // Bug #5: Safari does not support copyToChannel().\n }\n else {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength !== 0) {\n audioBuffer.getChannelData(channelNumber).set(parent[key], bufferOffset);\n }\n }\n};\n//# sourceMappingURL=copy-to-channel.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-nested-arrays.js\nconst createNestedArrays = (x, y) => {\n const arrays = [];\n for (let i = 0; i < x; i += 1) {\n const array = [];\n const length = typeof y === \'number\' ? y : y[i];\n for (let j = 0; j < length; j += 1) {\n array.push(new Float32Array(128));\n }\n arrays.push(array);\n }\n return arrays;\n};\n//# sourceMappingURL=create-nested-arrays.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-worklet-processor.js\n\n\n\nconst getAudioWorkletProcessor = (nativeOfflineAudioContext, proxy) => {\n const nodeToProcessorMap = getValueForKey(NODE_TO_PROCESSOR_MAPS, nativeOfflineAudioContext);\n const nativeAudioWorkletNode = getNativeAudioNode(proxy);\n return getValueForKey(nodeToProcessorMap, nativeAudioWorkletNode);\n};\n//# sourceMappingURL=get-audio-worklet-processor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-worklet-node-renderer-factory.js\n\n\n\n\n\n\nconst processBuffer = async (proxy, renderedBuffer, nativeOfflineAudioContext, options, outputChannelCount, processorConstructor, exposeCurrentFrameAndCurrentTime) => {\n // Ceil the length to the next full render quantum.\n // Bug #17: Safari does not yet expose the length.\n const length = renderedBuffer === null ? Math.ceil(proxy.context.length / 128) * 128 : renderedBuffer.length;\n const numberOfInputChannels = options.channelCount * options.numberOfInputs;\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const processedBuffer = numberOfOutputChannels === 0\n ? null\n : nativeOfflineAudioContext.createBuffer(numberOfOutputChannels, length, nativeOfflineAudioContext.sampleRate);\n if (processorConstructor === undefined) {\n throw new Error(\'Missing the processor constructor.\');\n }\n const audioNodeConnections = getAudioNodeConnections(proxy);\n const audioWorkletProcessor = await getAudioWorkletProcessor(nativeOfflineAudioContext, proxy);\n const inputs = createNestedArrays(options.numberOfInputs, options.channelCount);\n const outputs = createNestedArrays(options.numberOfOutputs, outputChannelCount);\n const parameters = Array.from(proxy.parameters.keys()).reduce((prmtrs, name) => ({ ...prmtrs, [name]: new Float32Array(128) }), {});\n for (let i = 0; i < length; i += 128) {\n if (options.numberOfInputs > 0 && renderedBuffer !== null) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < options.channelCount; k += 1) {\n copyFromChannel(renderedBuffer, inputs[j], k, k, i);\n }\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined && renderedBuffer !== null) {\n processorConstructor.parameterDescriptors.forEach(({ name }, index) => {\n copyFromChannel(renderedBuffer, parameters, name, numberOfInputChannels + index, i);\n });\n }\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (outputs[j][k].byteLength === 0) {\n outputs[j][k] = new Float32Array(128);\n }\n }\n }\n try {\n const potentiallyEmptyInputs = inputs.map((input, index) => {\n if (audioNodeConnections.activeInputs[index].size === 0) {\n return [];\n }\n return input;\n });\n const activeSourceFlag = exposeCurrentFrameAndCurrentTime(i / nativeOfflineAudioContext.sampleRate, nativeOfflineAudioContext.sampleRate, () => audioWorkletProcessor.process(potentiallyEmptyInputs, outputs, parameters));\n if (processedBuffer !== null) {\n for (let j = 0, outputChannelSplitterNodeOutput = 0; j < options.numberOfOutputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n copyToChannel(processedBuffer, outputs[j], k, outputChannelSplitterNodeOutput + k, i);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[j];\n }\n }\n if (!activeSourceFlag) {\n break;\n }\n }\n catch (error) {\n proxy.dispatchEvent(new ErrorEvent(\'processorerror\', {\n colno: error.colno,\n filename: error.filename,\n lineno: error.lineno,\n message: error.message\n }));\n break;\n }\n }\n return processedBuffer;\n};\nconst createAudioWorkletNodeRendererFactory = (connectAudioParam, connectMultipleOutputs, createNativeAudioBufferSourceNode, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, deleteUnrenderedAudioWorkletNode, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getNativeAudioNode, nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return (name, options, processorConstructor) => {\n const renderedNativeAudioNodes = new WeakMap();\n let processedBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioWorkletNode = getNativeAudioNode(proxy);\n let nativeOutputNodes = null;\n const nativeAudioWorkletNodeIsOwnedByContext = isOwnedByContext(nativeAudioWorkletNode, nativeOfflineAudioContext);\n const outputChannelCount = Array.isArray(options.outputChannelCount)\n ? options.outputChannelCount\n : Array.from(options.outputChannelCount);\n // Bug #61: Only Chrome, Edge & Firefox have an implementation of the AudioWorkletNode yet.\n if (nativeAudioWorkletNodeConstructor === null) {\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const outputChannelSplitterNode = createNativeChannelSplitterNode(nativeOfflineAudioContext, {\n channelCount: Math.max(1, numberOfOutputChannels),\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: Math.max(1, numberOfOutputChannels)\n });\n const outputChannelMergerNodes = [];\n for (let i = 0; i < proxy.numberOfOutputs; i += 1) {\n outputChannelMergerNodes.push(createNativeChannelMergerNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: outputChannelCount[i]\n }));\n }\n const outputGainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n });\n outputGainNode.connect = connectMultipleOutputs.bind(null, outputChannelMergerNodes);\n outputGainNode.disconnect = disconnectMultipleOutputs.bind(null, outputChannelMergerNodes);\n nativeOutputNodes = [outputChannelSplitterNode, outputChannelMergerNodes, outputGainNode];\n }\n else if (!nativeAudioWorkletNodeIsOwnedByContext) {\n nativeAudioWorkletNode = new nativeAudioWorkletNodeConstructor(nativeOfflineAudioContext, name);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeOutputNodes === null ? nativeAudioWorkletNode : nativeOutputNodes[2]);\n if (nativeOutputNodes !== null) {\n if (processedBufferPromise === null) {\n if (processorConstructor === undefined) {\n throw new Error(\'Missing the processor constructor.\');\n }\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n // Bug #47: The AudioDestinationNode in Safari gets not initialized correctly.\n const numberOfInputChannels = proxy.channelCount * proxy.numberOfInputs;\n const numberOfParameters = processorConstructor.parameterDescriptors === undefined ? 0 : processorConstructor.parameterDescriptors.length;\n const numberOfChannels = numberOfInputChannels + numberOfParameters;\n const renderBuffer = async () => {\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(numberOfChannels, \n // Ceil the length to the next full render quantum.\n // Bug #17: Safari does not yet expose the length.\n Math.ceil(proxy.context.length / 128) * 128, nativeOfflineAudioContext.sampleRate);\n const gainNodes = [];\n const inputChannelSplitterNodes = [];\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes.push(createNativeGainNode(partialOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n }));\n inputChannelSplitterNodes.push(createNativeChannelSplitterNode(partialOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: options.channelCount\n }));\n }\n const constantSourceNodes = await Promise.all(Array.from(proxy.parameters.values()).map(async (audioParam) => {\n const constantSourceNode = createNativeConstantSourceNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: audioParam.value\n });\n await renderAutomation(partialOfflineAudioContext, audioParam, constantSourceNode.offset);\n return constantSourceNode;\n }));\n const inputChannelMergerNode = createNativeChannelMergerNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: Math.max(1, numberOfInputChannels + numberOfParameters)\n });\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes[i].connect(inputChannelSplitterNodes[i]);\n for (let j = 0; j < options.channelCount; j += 1) {\n inputChannelSplitterNodes[i].connect(inputChannelMergerNode, j, i * options.channelCount + j);\n }\n }\n for (const [index, constantSourceNode] of constantSourceNodes.entries()) {\n constantSourceNode.connect(inputChannelMergerNode, 0, numberOfInputChannels + index);\n constantSourceNode.start(0);\n }\n inputChannelMergerNode.connect(partialOfflineAudioContext.destination);\n await Promise.all(gainNodes.map((gainNode) => renderInputsOfAudioNode(proxy, partialOfflineAudioContext, gainNode)));\n return renderNativeOfflineAudioContext(partialOfflineAudioContext);\n };\n processedBufferPromise = processBuffer(proxy, numberOfChannels === 0 ? null : await renderBuffer(), nativeOfflineAudioContext, options, outputChannelCount, processorConstructor, exposeCurrentFrameAndCurrentTime);\n }\n const processedBuffer = await processedBufferPromise;\n const audioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const [outputChannelSplitterNode, outputChannelMergerNodes, outputGainNode] = nativeOutputNodes;\n if (processedBuffer !== null) {\n audioBufferSourceNode.buffer = processedBuffer;\n audioBufferSourceNode.start(0);\n }\n audioBufferSourceNode.connect(outputChannelSplitterNode);\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < proxy.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.connect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n return outputGainNode;\n }\n if (!nativeAudioWorkletNodeIsOwnedByContext) {\n for (const [nm, audioParam] of proxy.parameters.entries()) {\n await renderAutomation(nativeOfflineAudioContext, audioParam, \n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n nativeAudioWorkletNode.parameters.get(nm));\n }\n }\n else {\n for (const [nm, audioParam] of proxy.parameters.entries()) {\n await connectAudioParam(nativeOfflineAudioContext, audioParam, \n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n nativeAudioWorkletNode.parameters.get(nm));\n }\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioWorkletNode);\n return nativeAudioWorkletNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n deleteUnrenderedAudioWorkletNode(nativeOfflineAudioContext, proxy);\n const renderedNativeAudioWorkletNodeOrGainNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioWorkletNodeOrGainNode !== undefined) {\n return Promise.resolve(renderedNativeAudioWorkletNodeOrGainNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=audio-worklet-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/base-audio-context-constructor.js\nconst createBaseAudioContextConstructor = (addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor) => {\n return class BaseAudioContext extends minimalBaseAudioContextConstructor {\n constructor(_nativeContext, numberOfChannels) {\n super(_nativeContext, numberOfChannels);\n this._nativeContext = _nativeContext;\n this._audioWorklet =\n addAudioWorkletModule === undefined\n ? undefined\n : {\n addModule: (moduleURL, options) => {\n return addAudioWorkletModule(this, moduleURL, options);\n }\n };\n }\n get audioWorklet() {\n return this._audioWorklet;\n }\n createAnalyser() {\n return new analyserNodeConstructor(this);\n }\n createBiquadFilter() {\n return new biquadFilterNodeConstructor(this);\n }\n createBuffer(numberOfChannels, length, sampleRate) {\n return new audioBufferConstructor({ length, numberOfChannels, sampleRate });\n }\n createBufferSource() {\n return new audioBufferSourceNodeConstructor(this);\n }\n createChannelMerger(numberOfInputs = 6) {\n return new channelMergerNodeConstructor(this, { numberOfInputs });\n }\n createChannelSplitter(numberOfOutputs = 6) {\n return new channelSplitterNodeConstructor(this, { numberOfOutputs });\n }\n createConstantSource() {\n return new constantSourceNodeConstructor(this);\n }\n createConvolver() {\n return new convolverNodeConstructor(this);\n }\n createDelay(maxDelayTime = 1) {\n return new delayNodeConstructor(this, { maxDelayTime });\n }\n createDynamicsCompressor() {\n return new dynamicsCompressorNodeConstructor(this);\n }\n createGain() {\n return new gainNodeConstructor(this);\n }\n createIIRFilter(feedforward, feedback) {\n return new iIRFilterNodeConstructor(this, { feedback, feedforward });\n }\n createOscillator() {\n return new oscillatorNodeConstructor(this);\n }\n createPanner() {\n return new pannerNodeConstructor(this);\n }\n createPeriodicWave(real, imag, constraints = { disableNormalization: false }) {\n return new periodicWaveConstructor(this, { ...constraints, imag, real });\n }\n createStereoPanner() {\n return new stereoPannerNodeConstructor(this);\n }\n createWaveShaper() {\n return new waveShaperNodeConstructor(this);\n }\n decodeAudioData(audioData, successCallback, errorCallback) {\n return decodeAudioData(this._nativeContext, audioData).then((audioBuffer) => {\n if (typeof successCallback === \'function\') {\n successCallback(audioBuffer);\n }\n return audioBuffer;\n }, (err) => {\n if (typeof errorCallback === \'function\') {\n errorCallback(err);\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=base-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/biquad-filter-node-constructor.js\n\nconst biquad_filter_node_constructor_DEFAULT_OPTIONS = {\n Q: 1,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n detune: 0,\n frequency: 350,\n gain: 0,\n type: \'lowpass\'\n};\nconst createBiquadFilterNodeConstructor = (audioNodeConstructor, createAudioParam, createBiquadFilterNodeRenderer, createInvalidAccessError, createNativeBiquadFilterNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class BiquadFilterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...biquad_filter_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeBiquadFilterNode = createNativeBiquadFilterNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const biquadFilterNodeRenderer = (isOffline ? createBiquadFilterNodeRenderer() : null);\n super(context, false, nativeBiquadFilterNode, biquadFilterNodeRenderer);\n // Bug #80: Safari does not export the correct values for maxValue and minValue.\n this._Q = createAudioParam(this, isOffline, nativeBiquadFilterNode.Q, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n // Bug #78: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._detune = createAudioParam(this, isOffline, nativeBiquadFilterNode.detune, 1200 * Math.log2(MOST_POSITIVE_SINGLE_FLOAT), -1200 * Math.log2(MOST_POSITIVE_SINGLE_FLOAT));\n // Bug #77: Firefox & Safari do not export the correct value for minValue.\n this._frequency = createAudioParam(this, isOffline, nativeBiquadFilterNode.frequency, context.sampleRate / 2, 0);\n // Bug #79: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._gain = createAudioParam(this, isOffline, nativeBiquadFilterNode.gain, 40 * Math.log10(MOST_POSITIVE_SINGLE_FLOAT), MOST_NEGATIVE_SINGLE_FLOAT);\n this._nativeBiquadFilterNode = nativeBiquadFilterNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get detune() {\n return this._detune;\n }\n get frequency() {\n return this._frequency;\n }\n get gain() {\n return this._gain;\n }\n get Q() {\n return this._Q;\n }\n get type() {\n return this._nativeBiquadFilterNode.type;\n }\n set type(value) {\n this._nativeBiquadFilterNode.type = value;\n }\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n // Bug #189: Safari does throw an InvalidStateError.\n try {\n this._nativeBiquadFilterNode.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);\n }\n catch (err) {\n if (err.code === 11) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n // Bug #68: Safari does not throw an error if the parameters differ in their length.\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n }\n };\n};\n//# sourceMappingURL=biquad-filter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/biquad-filter-node-renderer-factory.js\n\nconst createBiquadFilterNodeRendererFactory = (connectAudioParam, createNativeBiquadFilterNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeBiquadFilterNodes = new WeakMap();\n const createBiquadFilterNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeBiquadFilterNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeBiquadFilterNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeBiquadFilterNodeIsOwnedByContext = isOwnedByContext(nativeBiquadFilterNode, nativeOfflineAudioContext);\n if (!nativeBiquadFilterNodeIsOwnedByContext) {\n const options = {\n Q: nativeBiquadFilterNode.Q.value,\n channelCount: nativeBiquadFilterNode.channelCount,\n channelCountMode: nativeBiquadFilterNode.channelCountMode,\n channelInterpretation: nativeBiquadFilterNode.channelInterpretation,\n detune: nativeBiquadFilterNode.detune.value,\n frequency: nativeBiquadFilterNode.frequency.value,\n gain: nativeBiquadFilterNode.gain.value,\n type: nativeBiquadFilterNode.type\n };\n nativeBiquadFilterNode = createNativeBiquadFilterNode(nativeOfflineAudioContext, options);\n }\n renderedNativeBiquadFilterNodes.set(nativeOfflineAudioContext, nativeBiquadFilterNode);\n if (!nativeBiquadFilterNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.Q, nativeBiquadFilterNode.Q);\n await renderAutomation(nativeOfflineAudioContext, proxy.detune, nativeBiquadFilterNode.detune);\n await renderAutomation(nativeOfflineAudioContext, proxy.frequency, nativeBiquadFilterNode.frequency);\n await renderAutomation(nativeOfflineAudioContext, proxy.gain, nativeBiquadFilterNode.gain);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.Q, nativeBiquadFilterNode.Q);\n await connectAudioParam(nativeOfflineAudioContext, proxy.detune, nativeBiquadFilterNode.detune);\n await connectAudioParam(nativeOfflineAudioContext, proxy.frequency, nativeBiquadFilterNode.frequency);\n await connectAudioParam(nativeOfflineAudioContext, proxy.gain, nativeBiquadFilterNode.gain);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeBiquadFilterNode);\n return nativeBiquadFilterNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeBiquadFilterNode = renderedNativeBiquadFilterNodes.get(nativeOfflineAudioContext);\n if (renderedNativeBiquadFilterNode !== undefined) {\n return Promise.resolve(renderedNativeBiquadFilterNode);\n }\n return createBiquadFilterNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=biquad-filter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/cache-test-result.js\nconst createCacheTestResult = (ongoingTests, testResults) => {\n return (tester, test) => {\n const cachedTestResult = testResults.get(tester);\n if (cachedTestResult !== undefined) {\n return cachedTestResult;\n }\n const ongoingTest = ongoingTests.get(tester);\n if (ongoingTest !== undefined) {\n return ongoingTest;\n }\n try {\n const synchronousTestResult = test();\n if (synchronousTestResult instanceof Promise) {\n ongoingTests.set(tester, synchronousTestResult);\n return synchronousTestResult\n .catch(() => false)\n .then((finalTestResult) => {\n ongoingTests.delete(tester);\n testResults.set(tester, finalTestResult);\n return finalTestResult;\n });\n }\n testResults.set(tester, synchronousTestResult);\n return synchronousTestResult;\n }\n catch {\n testResults.set(tester, false);\n return false;\n }\n };\n};\n//# sourceMappingURL=cache-test-result.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-merger-node-constructor.js\nconst channel_merger_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n};\nconst createChannelMergerNodeConstructor = (audioNodeConstructor, createChannelMergerNodeRenderer, createNativeChannelMergerNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class ChannelMergerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...channel_merger_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeChannelMergerNode = createNativeChannelMergerNode(nativeContext, mergedOptions);\n const channelMergerNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createChannelMergerNodeRenderer() : null));\n super(context, false, nativeChannelMergerNode, channelMergerNodeRenderer);\n }\n };\n};\n//# sourceMappingURL=channel-merger-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-merger-node-renderer-factory.js\n\nconst createChannelMergerNodeRendererFactory = (createNativeChannelMergerNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioNode = getNativeAudioNode(proxy);\n // If the initially used nativeAudioNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAudioNodeIsOwnedByContext = isOwnedByContext(nativeAudioNode, nativeOfflineAudioContext);\n if (!nativeAudioNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAudioNode.channelCount,\n channelCountMode: nativeAudioNode.channelCountMode,\n channelInterpretation: nativeAudioNode.channelInterpretation,\n numberOfInputs: nativeAudioNode.numberOfInputs\n };\n nativeAudioNode = createNativeChannelMergerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioNode);\n return nativeAudioNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=channel-merger-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-splitter-node-constructor.js\nconst channel_splitter_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 6,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: 6\n};\nconst createChannelSplitterNodeConstructor = (audioNodeConstructor, createChannelSplitterNodeRenderer, createNativeChannelSplitterNode, getNativeContext, isNativeOfflineAudioContext, sanitizeChannelSplitterOptions) => {\n return class ChannelSplitterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = sanitizeChannelSplitterOptions({ ...channel_splitter_node_constructor_DEFAULT_OPTIONS, ...options });\n const nativeChannelSplitterNode = createNativeChannelSplitterNode(nativeContext, mergedOptions);\n const channelSplitterNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createChannelSplitterNodeRenderer() : null));\n super(context, false, nativeChannelSplitterNode, channelSplitterNodeRenderer);\n }\n };\n};\n//# sourceMappingURL=channel-splitter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-splitter-node-renderer-factory.js\n\nconst createChannelSplitterNodeRendererFactory = (createNativeChannelSplitterNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioNode = getNativeAudioNode(proxy);\n // If the initially used nativeAudioNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAudioNodeIsOwnedByContext = isOwnedByContext(nativeAudioNode, nativeOfflineAudioContext);\n if (!nativeAudioNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAudioNode.channelCount,\n channelCountMode: nativeAudioNode.channelCountMode,\n channelInterpretation: nativeAudioNode.channelInterpretation,\n numberOfOutputs: nativeAudioNode.numberOfOutputs\n };\n nativeAudioNode = createNativeChannelSplitterNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioNode);\n return nativeAudioNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=channel-splitter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connect-audio-param.js\nconst createConnectAudioParam = (renderInputsOfAudioParam) => {\n return (nativeOfflineAudioContext, audioParam, nativeAudioParam) => {\n return renderInputsOfAudioParam(audioParam, nativeOfflineAudioContext, nativeAudioParam);\n };\n};\n//# sourceMappingURL=connect-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connect-multiple-outputs.js\n\nconst createConnectMultipleOutputs = (createIndexSizeError) => {\n return (outputAudioNodes, destination, output = 0, input = 0) => {\n const outputAudioNode = outputAudioNodes[output];\n if (outputAudioNode === undefined) {\n throw createIndexSizeError();\n }\n if (isNativeAudioNode(destination)) {\n return outputAudioNode.connect(destination, 0, input);\n }\n return outputAudioNode.connect(destination, 0);\n };\n};\n//# sourceMappingURL=connect-multiple-outputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connected-native-audio-buffer-source-node-factory.js\nconst createConnectedNativeAudioBufferSourceNodeFactory = (createNativeAudioBufferSourceNode) => {\n return (nativeContext, nativeAudioNode) => {\n const nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const nativeAudioBuffer = nativeContext.createBuffer(1, 2, 44100);\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n nativeAudioBufferSourceNode.loop = true;\n nativeAudioBufferSourceNode.connect(nativeAudioNode);\n nativeAudioBufferSourceNode.start();\n return () => {\n nativeAudioBufferSourceNode.stop();\n nativeAudioBufferSourceNode.disconnect(nativeAudioNode);\n };\n };\n};\n//# sourceMappingURL=connected-native-audio-buffer-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/constant-source-node-constructor.js\n\n\n\n\nconst constant_source_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n offset: 1\n};\nconst createConstantSourceNodeConstructor = (audioNodeConstructor, createAudioParam, createConstantSourceNodeRendererFactory, createNativeConstantSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class ConstantSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...constant_source_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeConstantSourceNode = createNativeConstantSourceNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const constantSourceNodeRenderer = ((isOffline ? createConstantSourceNodeRendererFactory() : null));\n super(context, false, nativeConstantSourceNode, constantSourceNodeRenderer);\n this._constantSourceNodeRenderer = constantSourceNodeRenderer;\n this._nativeConstantSourceNode = nativeConstantSourceNode;\n /*\n * Bug #62 & #74: Safari does not support ConstantSourceNodes and does not export the correct values for maxValue and minValue\n * for GainNodes.\n */\n this._offset = createAudioParam(this, isOffline, nativeConstantSourceNode.offset, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._onended = null;\n }\n get offset() {\n return this._offset;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeConstantSourceNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeConstantSourceNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n start(when = 0) {\n this._nativeConstantSourceNode.start(when);\n if (this._constantSourceNodeRenderer !== null) {\n this._constantSourceNodeRenderer.start = when;\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeConstantSourceNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeConstantSourceNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeConstantSourceNode.stop(when);\n if (this._constantSourceNodeRenderer !== null) {\n this._constantSourceNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=constant-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/constant-source-node-renderer-factory.js\n\nconst createConstantSourceNodeRendererFactory = (connectAudioParam, createNativeConstantSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeConstantSourceNodes = new WeakMap();\n let start = null;\n let stop = null;\n const createConstantSourceNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeConstantSourceNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeConstantSourceNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeConstantSourceNodeIsOwnedByContext = isOwnedByContext(nativeConstantSourceNode, nativeOfflineAudioContext);\n if (!nativeConstantSourceNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeConstantSourceNode.channelCount,\n channelCountMode: nativeConstantSourceNode.channelCountMode,\n channelInterpretation: nativeConstantSourceNode.channelInterpretation,\n offset: nativeConstantSourceNode.offset.value\n };\n nativeConstantSourceNode = createNativeConstantSourceNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeConstantSourceNode.start(start);\n }\n if (stop !== null) {\n nativeConstantSourceNode.stop(stop);\n }\n }\n renderedNativeConstantSourceNodes.set(nativeOfflineAudioContext, nativeConstantSourceNode);\n if (!nativeConstantSourceNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.offset, nativeConstantSourceNode.offset);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.offset, nativeConstantSourceNode.offset);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConstantSourceNode);\n return nativeConstantSourceNode;\n };\n return {\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeConstantSourceNode = renderedNativeConstantSourceNodes.get(nativeOfflineAudioContext);\n if (renderedNativeConstantSourceNode !== undefined) {\n return Promise.resolve(renderedNativeConstantSourceNode);\n }\n return createConstantSourceNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=constant-source-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convert-number-to-unsigned-long.js\nconst createConvertNumberToUnsignedLong = (unit32Array) => {\n return (value) => {\n unit32Array[0] = value;\n return unit32Array[0];\n };\n};\n//# sourceMappingURL=convert-number-to-unsigned-long.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convolver-node-constructor.js\nconst convolver_node_constructor_DEFAULT_OPTIONS = {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n disableNormalization: false\n};\nconst createConvolverNodeConstructor = (audioNodeConstructor, createConvolverNodeRenderer, createNativeConvolverNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class ConvolverNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...convolver_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeConvolverNode = createNativeConvolverNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const convolverNodeRenderer = (isOffline ? createConvolverNodeRenderer() : null);\n super(context, false, nativeConvolverNode, convolverNodeRenderer);\n this._isBufferNullified = false;\n this._nativeConvolverNode = nativeConvolverNode;\n if (mergedOptions.buffer !== null) {\n setAudioNodeTailTime(this, mergedOptions.buffer.duration);\n }\n }\n get buffer() {\n if (this._isBufferNullified) {\n return null;\n }\n return this._nativeConvolverNode.buffer;\n }\n set buffer(value) {\n this._nativeConvolverNode.buffer = value;\n // Bug #115: Safari does not allow to set the buffer to null.\n if (value === null && this._nativeConvolverNode.buffer !== null) {\n const nativeContext = this._nativeConvolverNode.context;\n this._nativeConvolverNode.buffer = nativeContext.createBuffer(1, 1, nativeContext.sampleRate);\n this._isBufferNullified = true;\n setAudioNodeTailTime(this, 0);\n }\n else {\n this._isBufferNullified = false;\n setAudioNodeTailTime(this, this._nativeConvolverNode.buffer === null ? 0 : this._nativeConvolverNode.buffer.duration);\n }\n }\n get normalize() {\n return this._nativeConvolverNode.normalize;\n }\n set normalize(value) {\n this._nativeConvolverNode.normalize = value;\n }\n };\n};\n//# sourceMappingURL=convolver-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convolver-node-renderer-factory.js\n\n\nconst createConvolverNodeRendererFactory = (createNativeConvolverNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeConvolverNodes = new WeakMap();\n const createConvolverNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeConvolverNode = getNativeAudioNode(proxy);\n // If the initially used nativeConvolverNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeConvolverNodeIsOwnedByContext = isOwnedByContext(nativeConvolverNode, nativeOfflineAudioContext);\n if (!nativeConvolverNodeIsOwnedByContext) {\n const options = {\n buffer: nativeConvolverNode.buffer,\n channelCount: nativeConvolverNode.channelCount,\n channelCountMode: nativeConvolverNode.channelCountMode,\n channelInterpretation: nativeConvolverNode.channelInterpretation,\n disableNormalization: !nativeConvolverNode.normalize\n };\n nativeConvolverNode = createNativeConvolverNode(nativeOfflineAudioContext, options);\n }\n renderedNativeConvolverNodes.set(nativeOfflineAudioContext, nativeConvolverNode);\n if (isNativeAudioNodeFaker(nativeConvolverNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConvolverNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConvolverNode);\n }\n return nativeConvolverNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeConvolverNode = renderedNativeConvolverNodes.get(nativeOfflineAudioContext);\n if (renderedNativeConvolverNode !== undefined) {\n return Promise.resolve(renderedNativeConvolverNode);\n }\n return createConvolverNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=convolver-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/create-native-offline-audio-context.js\nconst createCreateNativeOfflineAudioContext = (createNotSupportedError, nativeOfflineAudioContextConstructor) => {\n return (numberOfChannels, length, sampleRate) => {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n try {\n return new nativeOfflineAudioContextConstructor(numberOfChannels, length, sampleRate);\n }\n catch (err) {\n // Bug #143, #144 & #146: Safari throws a SyntaxError when numberOfChannels, length or sampleRate are invalid.\n if (err.name === \'SyntaxError\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n };\n};\n//# sourceMappingURL=create-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/data-clone-error.js\nconst createDataCloneError = () => new DOMException(\'\', \'DataCloneError\');\n//# sourceMappingURL=data-clone-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/detach-array-buffer.js\nconst detachArrayBuffer = (arrayBuffer) => {\n const { port1, port2 } = new MessageChannel();\n return new Promise((resolve) => {\n const closeAndResolve = () => {\n port2.onmessage = null;\n port1.close();\n port2.close();\n resolve();\n };\n port2.onmessage = () => closeAndResolve();\n try {\n port1.postMessage(arrayBuffer, [arrayBuffer]);\n }\n catch {\n // Ignore errors.\n }\n finally {\n closeAndResolve();\n }\n });\n};\n//# sourceMappingURL=detach-array-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/decode-audio-data.js\n\n\nconst createDecodeAudioData = (audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, detachedArrayBuffers, getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n return (anyContext, audioData) => {\n const nativeContext = isNativeContext(anyContext) ? anyContext : getNativeContext(anyContext);\n // Bug #43: Only Chrome and Edge do throw a DataCloneError.\n if (detachedArrayBuffers.has(audioData)) {\n const err = createDataCloneError();\n return Promise.reject(err);\n }\n // The audioData parameter maybe of a type which can\'t be added to a WeakSet.\n try {\n detachedArrayBuffers.add(audioData);\n }\n catch {\n // Ignore errors.\n }\n // Bug #21: Safari does not support promises yet.\n if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeContext))) {\n return nativeContext.decodeAudioData(audioData).then((audioBuffer) => {\n // Bug #133: Safari does neuter the ArrayBuffer.\n detachArrayBuffer(audioData).catch(() => {\n // Ignore errors.\n });\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n return audioBuffer;\n });\n }\n // Bug #21: Safari does not return a Promise yet.\n return new Promise((resolve, reject) => {\n const complete = async () => {\n // Bug #133: Safari does neuter the ArrayBuffer.\n try {\n await detachArrayBuffer(audioData);\n }\n catch {\n // Ignore errors.\n }\n };\n const fail = (err) => {\n reject(err);\n complete();\n };\n // Bug #26: Safari throws a synchronous error.\n try {\n // Bug #1: Safari requires a successCallback.\n nativeContext.decodeAudioData(audioData, (audioBuffer) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n complete().then(() => resolve(audioBuffer));\n }, (err) => {\n // Bug #4: Safari returns null instead of an error.\n if (err === null) {\n fail(createEncodingError());\n }\n else {\n fail(err);\n }\n });\n }\n catch (err) {\n fail(err);\n }\n });\n };\n};\n//# sourceMappingURL=decode-audio-data.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/decrement-cycle-counter.js\n\nconst createDecrementCycleCounter = (connectNativeAudioNodeToNativeAudioNode, cycleCounters, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, getNativeContext, isActiveAudioNode, isNativeOfflineAudioContext) => {\n return (audioNode, count) => {\n const cycleCounter = cycleCounters.get(audioNode);\n if (cycleCounter === undefined) {\n throw new Error(\'Missing the expected cycle count.\');\n }\n const nativeContext = getNativeContext(audioNode.context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (cycleCounter === count) {\n cycleCounters.delete(audioNode);\n if (!isOffline && isActiveAudioNode(audioNode)) {\n const nativeSourceAudioNode = getNativeAudioNode(audioNode);\n const { outputs } = getAudioNodeConnections(audioNode);\n for (const output of outputs) {\n if (isAudioNodeOutputConnection(output)) {\n const nativeDestinationAudioNode = getNativeAudioNode(output[0]);\n connectNativeAudioNodeToNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output[1], output[2]);\n }\n else {\n const nativeDestinationAudioParam = getNativeAudioParam(output[0]);\n nativeSourceAudioNode.connect(nativeDestinationAudioParam, output[1]);\n }\n }\n }\n }\n else {\n cycleCounters.set(audioNode, cycleCounter - count);\n }\n };\n};\n//# sourceMappingURL=decrement-cycle-counter.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delay-node-constructor.js\nconst delay_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n delayTime: 0,\n maxDelayTime: 1\n};\nconst createDelayNodeConstructor = (audioNodeConstructor, createAudioParam, createDelayNodeRenderer, createNativeDelayNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class DelayNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...delay_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeDelayNode = createNativeDelayNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const delayNodeRenderer = (isOffline ? createDelayNodeRenderer(mergedOptions.maxDelayTime) : null);\n super(context, false, nativeDelayNode, delayNodeRenderer);\n this._delayTime = createAudioParam(this, isOffline, nativeDelayNode.delayTime);\n setAudioNodeTailTime(this, mergedOptions.maxDelayTime);\n }\n get delayTime() {\n return this._delayTime;\n }\n };\n};\n//# sourceMappingURL=delay-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delay-node-renderer-factory.js\n\nconst createDelayNodeRendererFactory = (connectAudioParam, createNativeDelayNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return (maxDelayTime) => {\n const renderedNativeDelayNodes = new WeakMap();\n const createDelayNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeDelayNode = getNativeAudioNode(proxy);\n // If the initially used nativeDelayNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeDelayNodeIsOwnedByContext = isOwnedByContext(nativeDelayNode, nativeOfflineAudioContext);\n if (!nativeDelayNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeDelayNode.channelCount,\n channelCountMode: nativeDelayNode.channelCountMode,\n channelInterpretation: nativeDelayNode.channelInterpretation,\n delayTime: nativeDelayNode.delayTime.value,\n maxDelayTime\n };\n nativeDelayNode = createNativeDelayNode(nativeOfflineAudioContext, options);\n }\n renderedNativeDelayNodes.set(nativeOfflineAudioContext, nativeDelayNode);\n if (!nativeDelayNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.delayTime, nativeDelayNode.delayTime);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.delayTime, nativeDelayNode.delayTime);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeDelayNode);\n return nativeDelayNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeDelayNode = renderedNativeDelayNodes.get(nativeOfflineAudioContext);\n if (renderedNativeDelayNode !== undefined) {\n return Promise.resolve(renderedNativeDelayNode);\n }\n return createDelayNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=delay-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delete-active-input-connection-to-audio-node.js\nconst createDeleteActiveInputConnectionToAudioNode = (pickElementFromSet) => {\n return (activeInputs, source, output, input) => {\n return pickElementFromSet(activeInputs[input], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output);\n };\n};\n//# sourceMappingURL=delete-active-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delete-unrendered-audio-worklet-node.js\nconst createDeleteUnrenderedAudioWorkletNode = (getUnrenderedAudioWorkletNodes) => {\n return (nativeContext, audioWorkletNode) => {\n getUnrenderedAudioWorkletNodes(nativeContext).delete(audioWorkletNode);\n };\n};\n//# sourceMappingURL=delete-unrendered-audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/delay-node.js\nconst isDelayNode = (audioNode) => {\n return \'delayTime\' in audioNode;\n};\n//# sourceMappingURL=delay-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/detect-cycles.js\n\n\nconst createDetectCycles = (audioParamAudioNodeStore, getAudioNodeConnections, getValueForKey) => {\n return function detectCycles(chain, nextLink) {\n const audioNode = isAudioNode(nextLink) ? nextLink : getValueForKey(audioParamAudioNodeStore, nextLink);\n if (isDelayNode(audioNode)) {\n return [];\n }\n if (chain[0] === audioNode) {\n return [chain];\n }\n if (chain.includes(audioNode)) {\n return [];\n }\n const { outputs } = getAudioNodeConnections(audioNode);\n return Array.from(outputs)\n .map((outputConnection) => detectCycles([...chain, audioNode], outputConnection[0]))\n .reduce((mergedCycles, nestedCycles) => mergedCycles.concat(nestedCycles), []);\n };\n};\n//# sourceMappingURL=detect-cycles.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/disconnect-multiple-outputs.js\n\nconst getOutputAudioNodeAtIndex = (createIndexSizeError, outputAudioNodes, output) => {\n const outputAudioNode = outputAudioNodes[output];\n if (outputAudioNode === undefined) {\n throw createIndexSizeError();\n }\n return outputAudioNode;\n};\nconst createDisconnectMultipleOutputs = (createIndexSizeError) => {\n return (outputAudioNodes, destinationOrOutput = undefined, output = undefined, input = 0) => {\n if (destinationOrOutput === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect());\n }\n if (typeof destinationOrOutput === \'number\') {\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, destinationOrOutput).disconnect();\n }\n if (isNativeAudioNode(destinationOrOutput)) {\n if (output === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect(destinationOrOutput));\n }\n if (input === undefined) {\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0);\n }\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0, input);\n }\n if (output === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect(destinationOrOutput));\n }\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0);\n };\n};\n//# sourceMappingURL=disconnect-multiple-outputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/dynamics-compressor-node-constructor.js\nconst dynamics_compressor_node_constructor_DEFAULT_OPTIONS = {\n attack: 0.003,\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n knee: 30,\n ratio: 12,\n release: 0.25,\n threshold: -24\n};\nconst createDynamicsCompressorNodeConstructor = (audioNodeConstructor, createAudioParam, createDynamicsCompressorNodeRenderer, createNativeDynamicsCompressorNode, createNotSupportedError, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class DynamicsCompressorNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...dynamics_compressor_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeDynamicsCompressorNode = createNativeDynamicsCompressorNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const dynamicsCompressorNodeRenderer = (isOffline ? createDynamicsCompressorNodeRenderer() : null);\n super(context, false, nativeDynamicsCompressorNode, dynamicsCompressorNodeRenderer);\n this._attack = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.attack);\n this._knee = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.knee);\n this._nativeDynamicsCompressorNode = nativeDynamicsCompressorNode;\n this._ratio = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.ratio);\n this._release = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.release);\n this._threshold = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.threshold);\n setAudioNodeTailTime(this, 0.006);\n }\n get attack() {\n return this._attack;\n }\n // Bug #108: Safari allows a channelCount of three and above which is why the getter and setter needs to be overwritten here.\n get channelCount() {\n return this._nativeDynamicsCompressorNode.channelCount;\n }\n set channelCount(value) {\n const previousChannelCount = this._nativeDynamicsCompressorNode.channelCount;\n this._nativeDynamicsCompressorNode.channelCount = value;\n if (value > 2) {\n this._nativeDynamicsCompressorNode.channelCount = previousChannelCount;\n throw createNotSupportedError();\n }\n }\n /*\n * Bug #109: Only Chrome and Firefox disallow a channelCountMode of \'max\' yet which is why the getter and setter needs to be\n * overwritten here.\n */\n get channelCountMode() {\n return this._nativeDynamicsCompressorNode.channelCountMode;\n }\n set channelCountMode(value) {\n const previousChannelCount = this._nativeDynamicsCompressorNode.channelCountMode;\n this._nativeDynamicsCompressorNode.channelCountMode = value;\n if (value === \'max\') {\n this._nativeDynamicsCompressorNode.channelCountMode = previousChannelCount;\n throw createNotSupportedError();\n }\n }\n get knee() {\n return this._knee;\n }\n get ratio() {\n return this._ratio;\n }\n get reduction() {\n // Bug #111: Safari returns an AudioParam instead of a number.\n if (typeof this._nativeDynamicsCompressorNode.reduction.value === \'number\') {\n return this._nativeDynamicsCompressorNode.reduction.value;\n }\n return this._nativeDynamicsCompressorNode.reduction;\n }\n get release() {\n return this._release;\n }\n get threshold() {\n return this._threshold;\n }\n };\n};\n//# sourceMappingURL=dynamics-compressor-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/dynamics-compressor-node-renderer-factory.js\n\nconst createDynamicsCompressorNodeRendererFactory = (connectAudioParam, createNativeDynamicsCompressorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeDynamicsCompressorNodes = new WeakMap();\n const createDynamicsCompressorNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeDynamicsCompressorNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeDynamicsCompressorNode was not constructed on the same OfflineAudioContext it needs to be\n * created again.\n */\n const nativeDynamicsCompressorNodeIsOwnedByContext = isOwnedByContext(nativeDynamicsCompressorNode, nativeOfflineAudioContext);\n if (!nativeDynamicsCompressorNodeIsOwnedByContext) {\n const options = {\n attack: nativeDynamicsCompressorNode.attack.value,\n channelCount: nativeDynamicsCompressorNode.channelCount,\n channelCountMode: nativeDynamicsCompressorNode.channelCountMode,\n channelInterpretation: nativeDynamicsCompressorNode.channelInterpretation,\n knee: nativeDynamicsCompressorNode.knee.value,\n ratio: nativeDynamicsCompressorNode.ratio.value,\n release: nativeDynamicsCompressorNode.release.value,\n threshold: nativeDynamicsCompressorNode.threshold.value\n };\n nativeDynamicsCompressorNode = createNativeDynamicsCompressorNode(nativeOfflineAudioContext, options);\n }\n renderedNativeDynamicsCompressorNodes.set(nativeOfflineAudioContext, nativeDynamicsCompressorNode);\n if (!nativeDynamicsCompressorNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.attack, nativeDynamicsCompressorNode.attack);\n await renderAutomation(nativeOfflineAudioContext, proxy.knee, nativeDynamicsCompressorNode.knee);\n await renderAutomation(nativeOfflineAudioContext, proxy.ratio, nativeDynamicsCompressorNode.ratio);\n await renderAutomation(nativeOfflineAudioContext, proxy.release, nativeDynamicsCompressorNode.release);\n await renderAutomation(nativeOfflineAudioContext, proxy.threshold, nativeDynamicsCompressorNode.threshold);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.attack, nativeDynamicsCompressorNode.attack);\n await connectAudioParam(nativeOfflineAudioContext, proxy.knee, nativeDynamicsCompressorNode.knee);\n await connectAudioParam(nativeOfflineAudioContext, proxy.ratio, nativeDynamicsCompressorNode.ratio);\n await connectAudioParam(nativeOfflineAudioContext, proxy.release, nativeDynamicsCompressorNode.release);\n await connectAudioParam(nativeOfflineAudioContext, proxy.threshold, nativeDynamicsCompressorNode.threshold);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeDynamicsCompressorNode);\n return nativeDynamicsCompressorNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeDynamicsCompressorNode = renderedNativeDynamicsCompressorNodes.get(nativeOfflineAudioContext);\n if (renderedNativeDynamicsCompressorNode !== undefined) {\n return Promise.resolve(renderedNativeDynamicsCompressorNode);\n }\n return createDynamicsCompressorNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=dynamics-compressor-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/encoding-error.js\nconst createEncodingError = () => new DOMException(\'\', \'EncodingError\');\n//# sourceMappingURL=encoding-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/evaluate-source.js\nconst createEvaluateSource = (window) => {\n return (source) => new Promise((resolve, reject) => {\n if (window === null) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n return;\n }\n const head = window.document.head;\n if (head === null) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n }\n else {\n const script = window.document.createElement(\'script\');\n // @todo Safari doesn\'t like URLs with a type of \'application/javascript; charset=utf-8\'.\n const blob = new Blob([source], { type: \'application/javascript\' });\n const url = URL.createObjectURL(blob);\n const originalOnErrorHandler = window.onerror;\n const removeErrorEventListenerAndRevokeUrl = () => {\n window.onerror = originalOnErrorHandler;\n URL.revokeObjectURL(url);\n };\n window.onerror = (message, src, lineno, colno, error) => {\n // @todo Edge thinks the source is the one of the html document.\n if (src === url || (src === window.location.href && lineno === 1 && colno === 1)) {\n removeErrorEventListenerAndRevokeUrl();\n reject(error);\n return false;\n }\n if (originalOnErrorHandler !== null) {\n return originalOnErrorHandler(message, src, lineno, colno, error);\n }\n };\n script.onerror = () => {\n removeErrorEventListenerAndRevokeUrl();\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n };\n script.onload = () => {\n removeErrorEventListenerAndRevokeUrl();\n resolve();\n };\n script.src = url;\n script.type = \'module\';\n head.appendChild(script);\n }\n });\n};\n//# sourceMappingURL=evaluate-source.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/event-target-constructor.js\nconst createEventTargetConstructor = (wrapEventListener) => {\n return class EventTarget {\n constructor(_nativeEventTarget) {\n this._nativeEventTarget = _nativeEventTarget;\n this._listeners = new WeakMap();\n }\n addEventListener(type, listener, options) {\n if (listener !== null) {\n let wrappedEventListener = this._listeners.get(listener);\n if (wrappedEventListener === undefined) {\n wrappedEventListener = wrapEventListener(this, listener);\n if (typeof listener === \'function\') {\n this._listeners.set(listener, wrappedEventListener);\n }\n }\n this._nativeEventTarget.addEventListener(type, wrappedEventListener, options);\n }\n }\n dispatchEvent(event) {\n return this._nativeEventTarget.dispatchEvent(event);\n }\n removeEventListener(type, listener, options) {\n const wrappedEventListener = listener === null ? undefined : this._listeners.get(listener);\n this._nativeEventTarget.removeEventListener(type, wrappedEventListener === undefined ? null : wrappedEventListener, options);\n }\n };\n};\n//# sourceMappingURL=event-target-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/expose-current-frame-and-current-time.js\nconst createExposeCurrentFrameAndCurrentTime = (window) => {\n return (currentTime, sampleRate, fn) => {\n Object.defineProperties(window, {\n currentFrame: {\n configurable: true,\n get() {\n return Math.round(currentTime * sampleRate);\n }\n },\n currentTime: {\n configurable: true,\n get() {\n return currentTime;\n }\n }\n });\n try {\n return fn();\n }\n finally {\n if (window !== null) {\n delete window.currentFrame;\n delete window.currentTime;\n }\n }\n };\n};\n//# sourceMappingURL=expose-current-frame-and-current-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/fetch-source.js\nconst createFetchSource = (createAbortError) => {\n return async (url) => {\n try {\n const response = await fetch(url);\n if (response.ok) {\n return [await response.text(), response.url];\n }\n }\n catch {\n // Ignore errors.\n } // tslint:disable-line:no-empty\n throw createAbortError();\n };\n};\n//# sourceMappingURL=fetch-source.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/gain-node-constructor.js\n\nconst gain_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n gain: 1\n};\nconst createGainNodeConstructor = (audioNodeConstructor, createAudioParam, createGainNodeRenderer, createNativeGainNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class GainNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...gain_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeGainNode = createNativeGainNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const gainNodeRenderer = (isOffline ? createGainNodeRenderer() : null);\n super(context, false, nativeGainNode, gainNodeRenderer);\n // Bug #74: Safari does not export the correct values for maxValue and minValue.\n this._gain = createAudioParam(this, isOffline, nativeGainNode.gain, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n }\n get gain() {\n return this._gain;\n }\n };\n};\n//# sourceMappingURL=gain-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/gain-node-renderer-factory.js\n\nconst createGainNodeRendererFactory = (connectAudioParam, createNativeGainNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeGainNodes = new WeakMap();\n const createGainNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeGainNode = getNativeAudioNode(proxy);\n // If the initially used nativeGainNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeGainNodeIsOwnedByContext = isOwnedByContext(nativeGainNode, nativeOfflineAudioContext);\n if (!nativeGainNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeGainNode.channelCount,\n channelCountMode: nativeGainNode.channelCountMode,\n channelInterpretation: nativeGainNode.channelInterpretation,\n gain: nativeGainNode.gain.value\n };\n nativeGainNode = createNativeGainNode(nativeOfflineAudioContext, options);\n }\n renderedNativeGainNodes.set(nativeOfflineAudioContext, nativeGainNode);\n if (!nativeGainNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.gain, nativeGainNode.gain);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.gain, nativeGainNode.gain);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeGainNode);\n return nativeGainNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeGainNode = renderedNativeGainNodes.get(nativeOfflineAudioContext);\n if (renderedNativeGainNode !== undefined) {\n return Promise.resolve(renderedNativeGainNode);\n }\n return createGainNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=gain-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-active-audio-worklet-node-inputs.js\nconst createGetActiveAudioWorkletNodeInputs = (activeAudioWorkletNodeInputsStore, getValueForKey) => {\n return (nativeAudioWorkletNode) => getValueForKey(activeAudioWorkletNodeInputsStore, nativeAudioWorkletNode);\n};\n//# sourceMappingURL=get-active-audio-worklet-node-inputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-node-renderer.js\nconst createGetAudioNodeRenderer = (getAudioNodeConnections) => {\n return (audioNode) => {\n const audioNodeConnections = getAudioNodeConnections(audioNode);\n if (audioNodeConnections.renderer === null) {\n throw new Error(\'Missing the renderer of the given AudioNode in the audio graph.\');\n }\n return audioNodeConnections.renderer;\n };\n};\n//# sourceMappingURL=get-audio-node-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-node-tail-time.js\nconst createGetAudioNodeTailTime = (audioNodeTailTimeStore) => {\n return (audioNode) => { var _a; return (_a = audioNodeTailTimeStore.get(audioNode)) !== null && _a !== void 0 ? _a : 0; };\n};\n//# sourceMappingURL=get-audio-node-tail-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-param-renderer.js\nconst createGetAudioParamRenderer = (getAudioParamConnections) => {\n return (audioParam) => {\n const audioParamConnections = getAudioParamConnections(audioParam);\n if (audioParamConnections.renderer === null) {\n throw new Error(\'Missing the renderer of the given AudioParam in the audio graph.\');\n }\n return audioParamConnections.renderer;\n };\n};\n//# sourceMappingURL=get-audio-param-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-backup-offline-audio-context.js\nconst createGetBackupOfflineAudioContext = (backupOfflineAudioContextStore) => {\n return (nativeContext) => {\n return backupOfflineAudioContextStore.get(nativeContext);\n };\n};\n//# sourceMappingURL=get-backup-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/invalid-state-error.js\nconst createInvalidStateError = () => new DOMException(\'\', \'InvalidStateError\');\n//# sourceMappingURL=invalid-state-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-native-context.js\n\nconst createGetNativeContext = (contextStore) => {\n return (context) => {\n const nativeContext = contextStore.get(context);\n if (nativeContext === undefined) {\n throw createInvalidStateError();\n }\n return (nativeContext);\n };\n};\n//# sourceMappingURL=get-native-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-or-create-backup-offline-audio-context.js\nconst createGetOrCreateBackupOfflineAudioContext = (backupOfflineAudioContextStore, nativeOfflineAudioContextConstructor) => {\n return (nativeContext) => {\n let backupOfflineAudioContext = backupOfflineAudioContextStore.get(nativeContext);\n if (backupOfflineAudioContext !== undefined) {\n return backupOfflineAudioContext;\n }\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n // Bug #141: Safari does not support creating an OfflineAudioContext with less than 44100 Hz.\n backupOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n backupOfflineAudioContextStore.set(nativeContext, backupOfflineAudioContext);\n return backupOfflineAudioContext;\n };\n};\n//# sourceMappingURL=get-or-create-backup-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-unrendered-audio-worklet-nodes.js\nconst createGetUnrenderedAudioWorkletNodes = (unrenderedAudioWorkletNodeStore) => {\n return (nativeContext) => {\n const unrenderedAudioWorkletNodes = unrenderedAudioWorkletNodeStore.get(nativeContext);\n if (unrenderedAudioWorkletNodes === undefined) {\n throw new Error(\'The context has no set of AudioWorkletNodes.\');\n }\n return unrenderedAudioWorkletNodes;\n };\n};\n//# sourceMappingURL=get-unrendered-audio-worklet-nodes.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/invalid-access-error.js\nconst createInvalidAccessError = () => new DOMException(\'\', \'InvalidAccessError\');\n//# sourceMappingURL=invalid-access-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-iir-filter-node-get-frequency-response-method.js\n\nconst wrapIIRFilterNodeGetFrequencyResponseMethod = (nativeIIRFilterNode) => {\n nativeIIRFilterNode.getFrequencyResponse = ((getFrequencyResponse) => {\n return (frequencyHz, magResponse, phaseResponse) => {\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n return getFrequencyResponse.call(nativeIIRFilterNode, frequencyHz, magResponse, phaseResponse);\n };\n })(nativeIIRFilterNode.getFrequencyResponse);\n};\n//# sourceMappingURL=wrap-iir-filter-node-get-frequency-response-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/iir-filter-node-constructor.js\n\nconst iir_filter_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\'\n};\nconst createIIRFilterNodeConstructor = (audioNodeConstructor, createNativeIIRFilterNode, createIIRFilterNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class IIRFilterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const mergedOptions = { ...iir_filter_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeIIRFilterNode = createNativeIIRFilterNode(nativeContext, isOffline ? null : context.baseLatency, mergedOptions);\n const iirFilterNodeRenderer = ((isOffline ? createIIRFilterNodeRenderer(mergedOptions.feedback, mergedOptions.feedforward) : null));\n super(context, false, nativeIIRFilterNode, iirFilterNodeRenderer);\n // Bug #23 & #24: FirefoxDeveloper does not throw an InvalidAccessError.\n // @todo Write a test which allows other browsers to remain unpatched.\n wrapIIRFilterNodeGetFrequencyResponseMethod(nativeIIRFilterNode);\n this._nativeIIRFilterNode = nativeIIRFilterNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n return this._nativeIIRFilterNode.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);\n }\n };\n};\n//# sourceMappingURL=iir-filter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/filter-buffer.js\n// This implementation as shamelessly inspired by source code of\n// tslint:disable-next-line:max-line-length\n// {@link https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/platform/audio/IIRFilter.cpp|Chromium\'s IIRFilter}.\nconst filterBuffer = (feedback, feedbackLength, feedforward, feedforwardLength, minLength, xBuffer, yBuffer, bufferIndex, bufferLength, input, output) => {\n const inputLength = input.length;\n let i = bufferIndex;\n for (let j = 0; j < inputLength; j += 1) {\n let y = feedforward[0] * input[j];\n for (let k = 1; k < minLength; k += 1) {\n const x = (i - k) & (bufferLength - 1); // tslint:disable-line:no-bitwise\n y += feedforward[k] * xBuffer[x];\n y -= feedback[k] * yBuffer[x];\n }\n for (let k = minLength; k < feedforwardLength; k += 1) {\n y += feedforward[k] * xBuffer[(i - k) & (bufferLength - 1)]; // tslint:disable-line:no-bitwise\n }\n for (let k = minLength; k < feedbackLength; k += 1) {\n y -= feedback[k] * yBuffer[(i - k) & (bufferLength - 1)]; // tslint:disable-line:no-bitwise\n }\n xBuffer[i] = input[j];\n yBuffer[i] = y;\n i = (i + 1) & (bufferLength - 1); // tslint:disable-line:no-bitwise\n output[j] = y;\n }\n return i;\n};\n//# sourceMappingURL=filter-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/iir-filter-node-renderer-factory.js\n\n\nconst filterFullBuffer = (renderedBuffer, nativeOfflineAudioContext, feedback, feedforward) => {\n const convertedFeedback = feedback instanceof Float64Array ? feedback : new Float64Array(feedback);\n const convertedFeedforward = feedforward instanceof Float64Array ? feedforward : new Float64Array(feedforward);\n const feedbackLength = convertedFeedback.length;\n const feedforwardLength = convertedFeedforward.length;\n const minLength = Math.min(feedbackLength, feedforwardLength);\n if (convertedFeedback[0] !== 1) {\n for (let i = 0; i < feedbackLength; i += 1) {\n convertedFeedforward[i] /= convertedFeedback[0];\n }\n for (let i = 1; i < feedforwardLength; i += 1) {\n convertedFeedback[i] /= convertedFeedback[0];\n }\n }\n const bufferLength = 32;\n const xBuffer = new Float32Array(bufferLength);\n const yBuffer = new Float32Array(bufferLength);\n const filteredBuffer = nativeOfflineAudioContext.createBuffer(renderedBuffer.numberOfChannels, renderedBuffer.length, renderedBuffer.sampleRate);\n const numberOfChannels = renderedBuffer.numberOfChannels;\n for (let i = 0; i < numberOfChannels; i += 1) {\n const input = renderedBuffer.getChannelData(i);\n const output = filteredBuffer.getChannelData(i);\n xBuffer.fill(0);\n yBuffer.fill(0);\n filterBuffer(convertedFeedback, feedbackLength, convertedFeedforward, feedforwardLength, minLength, xBuffer, yBuffer, 0, bufferLength, input, output);\n }\n return filteredBuffer;\n};\nconst createIIRFilterNodeRendererFactory = (createNativeAudioBufferSourceNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return (feedback, feedforward) => {\n const renderedNativeAudioNodes = new WeakMap();\n let filteredBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioBufferSourceNode = null;\n let nativeIIRFilterNode = getNativeAudioNode(proxy);\n // If the initially used nativeIIRFilterNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeIIRFilterNodeIsOwnedByContext = isOwnedByContext(nativeIIRFilterNode, nativeOfflineAudioContext);\n // Bug #9: Safari does not support IIRFilterNodes.\n if (nativeOfflineAudioContext.createIIRFilter === undefined) {\n nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n }\n else if (!nativeIIRFilterNodeIsOwnedByContext) {\n // @todo TypeScript defines the parameters of createIIRFilter() as arrays of numbers.\n nativeIIRFilterNode = nativeOfflineAudioContext.createIIRFilter(feedforward, feedback);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioBufferSourceNode === null ? nativeIIRFilterNode : nativeAudioBufferSourceNode);\n if (nativeAudioBufferSourceNode !== null) {\n if (filteredBufferPromise === null) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(\n // Bug #47: The AudioDestinationNode in Safari gets not initialized correctly.\n proxy.context.destination.channelCount, \n // Bug #17: Safari does not yet expose the length.\n proxy.context.length, nativeOfflineAudioContext.sampleRate);\n filteredBufferPromise = (async () => {\n await renderInputsOfAudioNode(proxy, partialOfflineAudioContext, partialOfflineAudioContext.destination);\n const renderedBuffer = await renderNativeOfflineAudioContext(partialOfflineAudioContext);\n return filterFullBuffer(renderedBuffer, nativeOfflineAudioContext, feedback, feedforward);\n })();\n }\n const filteredBuffer = await filteredBufferPromise;\n nativeAudioBufferSourceNode.buffer = filteredBuffer;\n nativeAudioBufferSourceNode.start(0);\n return nativeAudioBufferSourceNode;\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeIIRFilterNode);\n return nativeIIRFilterNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=iir-filter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/increment-cycle-counter-factory.js\n\nconst createIncrementCycleCounterFactory = (cycleCounters, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, isActiveAudioNode) => {\n return (isOffline) => {\n return (audioNode, count) => {\n const cycleCounter = cycleCounters.get(audioNode);\n if (cycleCounter === undefined) {\n if (!isOffline && isActiveAudioNode(audioNode)) {\n const nativeSourceAudioNode = getNativeAudioNode(audioNode);\n const { outputs } = getAudioNodeConnections(audioNode);\n for (const output of outputs) {\n if (isAudioNodeOutputConnection(output)) {\n const nativeDestinationAudioNode = getNativeAudioNode(output[0]);\n disconnectNativeAudioNodeFromNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output[1], output[2]);\n }\n else {\n const nativeDestinationAudioParam = getNativeAudioParam(output[0]);\n nativeSourceAudioNode.disconnect(nativeDestinationAudioParam, output[1]);\n }\n }\n }\n cycleCounters.set(audioNode, count);\n }\n else {\n cycleCounters.set(audioNode, cycleCounter + count);\n }\n };\n };\n};\n//# sourceMappingURL=increment-cycle-counter-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-context.js\nconst createIsAnyAudioContext = (contextStore, isNativeAudioContext) => {\n return (anything) => {\n const nativeContext = contextStore.get(anything);\n return isNativeAudioContext(nativeContext) || isNativeAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-any-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-node.js\nconst createIsAnyAudioNode = (audioNodeStore, isNativeAudioNode) => {\n return (anything) => audioNodeStore.has(anything) || isNativeAudioNode(anything);\n};\n//# sourceMappingURL=is-any-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-param.js\nconst createIsAnyAudioParam = (audioParamStore, isNativeAudioParam) => {\n return (anything) => audioParamStore.has(anything) || isNativeAudioParam(anything);\n};\n//# sourceMappingURL=is-any-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-offline-audio-context.js\nconst createIsAnyOfflineAudioContext = (contextStore, isNativeOfflineAudioContext) => {\n return (anything) => {\n const nativeContext = contextStore.get(anything);\n return isNativeOfflineAudioContext(nativeContext) || isNativeOfflineAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-any-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-context.js\nconst createIsNativeAudioContext = (nativeAudioContextConstructor) => {\n return (anything) => {\n return nativeAudioContextConstructor !== null && anything instanceof nativeAudioContextConstructor;\n };\n};\n//# sourceMappingURL=is-native-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-node.js\nconst createIsNativeAudioNode = (window) => {\n return (anything) => {\n return window !== null && typeof window.AudioNode === \'function\' && anything instanceof window.AudioNode;\n };\n};\n//# sourceMappingURL=is-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-param.js\nconst createIsNativeAudioParam = (window) => {\n return (anything) => {\n return window !== null && typeof window.AudioParam === \'function\' && anything instanceof window.AudioParam;\n };\n};\n//# sourceMappingURL=is-native-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-context.js\nconst createIsNativeContext = (isNativeAudioContext, isNativeOfflineAudioContext) => {\n return (anything) => {\n return isNativeAudioContext(anything) || isNativeOfflineAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-native-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-offline-audio-context.js\nconst createIsNativeOfflineAudioContext = (nativeOfflineAudioContextConstructor) => {\n return (anything) => {\n return nativeOfflineAudioContextConstructor !== null && anything instanceof nativeOfflineAudioContextConstructor;\n };\n};\n//# sourceMappingURL=is-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-secure-context.js\nconst createIsSecureContext = (window) => window !== null && window.isSecureContext;\n//# sourceMappingURL=is-secure-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-element-audio-source-node-constructor.js\nconst createMediaElementAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaElementAudioSourceNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaElementAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaElementAudioSourceNode = createNativeMediaElementAudioSourceNode(nativeContext, options);\n // Bug #171: Safari allows to create a MediaElementAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw TypeError();\n }\n super(context, true, nativeMediaElementAudioSourceNode, null);\n this._nativeMediaElementAudioSourceNode = nativeMediaElementAudioSourceNode;\n }\n get mediaElement() {\n return this._nativeMediaElementAudioSourceNode.mediaElement;\n }\n };\n};\n//# sourceMappingURL=media-element-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-audio-destination-node-constructor.js\nconst media_stream_audio_destination_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\'\n};\nconst createMediaStreamAudioDestinationNodeConstructor = (audioNodeConstructor, createNativeMediaStreamAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaStreamAudioDestinationNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n // Bug #173: Safari allows to create a MediaStreamAudioDestinationNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw new TypeError();\n }\n const mergedOptions = { ...media_stream_audio_destination_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeMediaStreamAudioDestinationNode = createNativeMediaStreamAudioDestinationNode(nativeContext, mergedOptions);\n super(context, false, nativeMediaStreamAudioDestinationNode, null);\n this._nativeMediaStreamAudioDestinationNode = nativeMediaStreamAudioDestinationNode;\n }\n get stream() {\n return this._nativeMediaStreamAudioDestinationNode.stream;\n }\n };\n};\n//# sourceMappingURL=media-stream-audio-destination-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-audio-source-node-constructor.js\nconst createMediaStreamAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaStreamAudioSourceNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaStreamAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaStreamAudioSourceNode = createNativeMediaStreamAudioSourceNode(nativeContext, options);\n // Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw new TypeError();\n }\n super(context, true, nativeMediaStreamAudioSourceNode, null);\n this._nativeMediaStreamAudioSourceNode = nativeMediaStreamAudioSourceNode;\n }\n get mediaStream() {\n return this._nativeMediaStreamAudioSourceNode.mediaStream;\n }\n };\n};\n//# sourceMappingURL=media-stream-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-track-audio-source-node-constructor.js\nconst createMediaStreamTrackAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaStreamTrackAudioSourceNode, getNativeContext) => {\n return class MediaStreamTrackAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaStreamTrackAudioSourceNode = createNativeMediaStreamTrackAudioSourceNode(nativeContext, options);\n super(context, true, nativeMediaStreamTrackAudioSourceNode, null);\n }\n };\n};\n//# sourceMappingURL=media-stream-track-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-audio-context-constructor.js\n\n\nconst createMinimalAudioContextConstructor = (createInvalidStateError, createNotSupportedError, createUnknownError, minimalBaseAudioContextConstructor, nativeAudioContextConstructor) => {\n return class MinimalAudioContext extends minimalBaseAudioContextConstructor {\n constructor(options = {}) {\n if (nativeAudioContextConstructor === null) {\n throw new Error(\'Missing the native AudioContext constructor.\');\n }\n let nativeAudioContext;\n try {\n nativeAudioContext = new nativeAudioContextConstructor(options);\n }\n catch (err) {\n // Bug #192 Safari does throw a SyntaxError if the sampleRate is not supported.\n if (err.code === 12 && err.message === \'sampleRate is not in range\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n // Bug #131 Safari returns null when there are four other AudioContexts running already.\n if (nativeAudioContext === null) {\n throw createUnknownError();\n }\n // Bug #51 Only Chrome and Edge throw an error if the given latencyHint is invalid.\n if (!isValidLatencyHint(options.latencyHint)) {\n throw new TypeError(`The provided value \'${options.latencyHint}\' is not a valid enum value of type AudioContextLatencyCategory.`);\n }\n // Bug #150 Safari does not support setting the sampleRate.\n if (options.sampleRate !== undefined && nativeAudioContext.sampleRate !== options.sampleRate) {\n throw createNotSupportedError();\n }\n super(nativeAudioContext, 2);\n const { latencyHint } = options;\n const { sampleRate } = nativeAudioContext;\n // @todo The values for \'balanced\', \'interactive\' and \'playback\' are just copied from Chrome\'s implementation.\n this._baseLatency =\n typeof nativeAudioContext.baseLatency === \'number\'\n ? nativeAudioContext.baseLatency\n : latencyHint === \'balanced\'\n ? 512 / sampleRate\n : latencyHint === \'interactive\' || latencyHint === undefined\n ? 256 / sampleRate\n : latencyHint === \'playback\'\n ? 1024 / sampleRate\n : /*\n * @todo The min (256) and max (16384) values are taken from the allowed bufferSize values of a\n * ScriptProcessorNode.\n */\n (Math.max(2, Math.min(128, Math.round((latencyHint * sampleRate) / 128))) * 128) / sampleRate;\n this._nativeAudioContext = nativeAudioContext;\n // Bug #188: Safari will set the context\'s state to \'interrupted\' in case the user switches tabs.\n if (nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n this._nativeGainNode = nativeAudioContext.createGain();\n this._nativeOscillatorNode = nativeAudioContext.createOscillator();\n this._nativeGainNode.gain.value = 1e-37;\n this._nativeOscillatorNode.connect(this._nativeGainNode).connect(nativeAudioContext.destination);\n this._nativeOscillatorNode.start();\n }\n else {\n this._nativeGainNode = null;\n this._nativeOscillatorNode = null;\n }\n this._state = null;\n /*\n * Bug #34: Chrome and Edge pretend to be running right away, but fire an onstatechange event when the state actually changes\n * to \'running\'.\n */\n if (nativeAudioContext.state === \'running\') {\n this._state = \'suspended\';\n const revokeState = () => {\n if (this._state === \'suspended\') {\n this._state = null;\n }\n nativeAudioContext.removeEventListener(\'statechange\', revokeState);\n };\n nativeAudioContext.addEventListener(\'statechange\', revokeState);\n }\n }\n get baseLatency() {\n return this._baseLatency;\n }\n get state() {\n return this._state !== null ? this._state : this._nativeAudioContext.state;\n }\n close() {\n // Bug #35: Firefox does not throw an error if the AudioContext was closed before.\n if (this.state === \'closed\') {\n return this._nativeAudioContext.close().then(() => {\n throw createInvalidStateError();\n });\n }\n // Bug #34: If the state was set to suspended before it should be revoked now.\n if (this._state === \'suspended\') {\n this._state = null;\n }\n return this._nativeAudioContext.close().then(() => {\n if (this._nativeGainNode !== null && this._nativeOscillatorNode !== null) {\n this._nativeOscillatorNode.stop();\n this._nativeGainNode.disconnect();\n this._nativeOscillatorNode.disconnect();\n }\n deactivateAudioGraph(this);\n });\n }\n resume() {\n if (this._state === \'suspended\') {\n return new Promise((resolve, reject) => {\n const resolvePromise = () => {\n this._nativeAudioContext.removeEventListener(\'statechange\', resolvePromise);\n if (this._nativeAudioContext.state === \'running\') {\n resolve();\n }\n else {\n this.resume().then(resolve, reject);\n }\n };\n this._nativeAudioContext.addEventListener(\'statechange\', resolvePromise);\n });\n }\n return this._nativeAudioContext.resume().catch((err) => {\n // Bug #55: Chrome and Edge do throw an InvalidAccessError instead of an InvalidStateError.\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined || err.code === 15) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n suspend() {\n return this._nativeAudioContext.suspend().catch((err) => {\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=minimal-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-base-audio-context-constructor.js\n\nconst createMinimalBaseAudioContextConstructor = (audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener) => {\n return class MinimalBaseAudioContext extends eventTargetConstructor {\n constructor(_nativeContext, numberOfChannels) {\n super(_nativeContext);\n this._nativeContext = _nativeContext;\n CONTEXT_STORE.set(this, _nativeContext);\n if (isNativeOfflineAudioContext(_nativeContext)) {\n unrenderedAudioWorkletNodeStore.set(_nativeContext, new Set());\n }\n this._destination = new audioDestinationNodeConstructor(this, numberOfChannels);\n this._listener = createAudioListener(this, _nativeContext);\n this._onstatechange = null;\n }\n get currentTime() {\n return this._nativeContext.currentTime;\n }\n get destination() {\n return this._destination;\n }\n get listener() {\n return this._listener;\n }\n get onstatechange() {\n return this._onstatechange;\n }\n set onstatechange(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeContext.onstatechange = wrappedListener;\n const nativeOnStateChange = this._nativeContext.onstatechange;\n this._onstatechange = nativeOnStateChange !== null && nativeOnStateChange === wrappedListener ? value : nativeOnStateChange;\n }\n get sampleRate() {\n return this._nativeContext.sampleRate;\n }\n get state() {\n return this._nativeContext.state;\n }\n };\n};\n//# sourceMappingURL=minimal-base-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-promise-support.js\nconst testPromiseSupport = (nativeContext) => {\n // This 12 numbers represent the 48 bytes of an empty WAVE file with a single sample.\n const uint32Array = new Uint32Array([1179011410, 40, 1163280727, 544501094, 16, 131073, 44100, 176400, 1048580, 1635017060, 4, 0]);\n try {\n // Bug #1: Safari requires a successCallback.\n const promise = nativeContext.decodeAudioData(uint32Array.buffer, () => {\n // Ignore the success callback.\n });\n if (promise === undefined) {\n return false;\n }\n promise.catch(() => {\n // Ignore rejected errors.\n });\n return true;\n }\n catch {\n // Ignore errors.\n }\n return false;\n};\n//# sourceMappingURL=test-promise-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-offline-audio-context-constructor.js\n\n\nconst minimal_offline_audio_context_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createMinimalOfflineAudioContextConstructor = (cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, minimalBaseAudioContextConstructor, startRendering) => {\n return class MinimalOfflineAudioContext extends minimalBaseAudioContextConstructor {\n constructor(options) {\n const { length, numberOfChannels, sampleRate } = { ...minimal_offline_audio_context_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOfflineAudioContext = createNativeOfflineAudioContext(numberOfChannels, length, sampleRate);\n // #21 Safari does not support promises and therefore would fire the statechange event before the promise can be resolved.\n if (!cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n nativeOfflineAudioContext.addEventListener(\'statechange\', (() => {\n let i = 0;\n const delayStateChangeEvent = (event) => {\n if (this._state === \'running\') {\n if (i > 0) {\n nativeOfflineAudioContext.removeEventListener(\'statechange\', delayStateChangeEvent);\n event.stopImmediatePropagation();\n this._waitForThePromiseToSettle(event);\n }\n else {\n i += 1;\n }\n }\n };\n return delayStateChangeEvent;\n })());\n }\n super(nativeOfflineAudioContext, numberOfChannels);\n this._length = length;\n this._nativeOfflineAudioContext = nativeOfflineAudioContext;\n this._state = null;\n }\n get length() {\n // Bug #17: Safari does not yet expose the length.\n if (this._nativeOfflineAudioContext.length === undefined) {\n return this._length;\n }\n return this._nativeOfflineAudioContext.length;\n }\n get state() {\n return this._state === null ? this._nativeOfflineAudioContext.state : this._state;\n }\n startRendering() {\n /*\n * Bug #9 & #59: It is theoretically possible that startRendering() will first render a partialOfflineAudioContext. Therefore\n * the state of the nativeOfflineAudioContext might no transition to running immediately.\n */\n if (this._state === \'running\') {\n return Promise.reject(createInvalidStateError());\n }\n this._state = \'running\';\n return startRendering(this.destination, this._nativeOfflineAudioContext).finally(() => {\n this._state = null;\n deactivateAudioGraph(this);\n });\n }\n _waitForThePromiseToSettle(event) {\n if (this._state === null) {\n this._nativeOfflineAudioContext.dispatchEvent(event);\n }\n else {\n setTimeout(() => this._waitForThePromiseToSettle(event));\n }\n }\n };\n};\n//# sourceMappingURL=minimal-offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/monitor-connections.js\nconst createMonitorConnections = (insertElementInSet, isNativeAudioNode) => {\n return (nativeAudioNode, whenConnected, whenDisconnected) => {\n const connections = new Set();\n nativeAudioNode.connect = ((connect) => {\n // tslint:disable-next-line:invalid-void no-inferrable-types\n return (destination, output = 0, input = 0) => {\n const wasDisconnected = connections.size === 0;\n if (isNativeAudioNode(destination)) {\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n connect.call(nativeAudioNode, destination, output, input);\n insertElementInSet(connections, [destination, output, input], (connection) => connection[0] === destination && connection[1] === output && connection[2] === input, true);\n if (wasDisconnected) {\n whenConnected();\n }\n return destination;\n }\n connect.call(nativeAudioNode, destination, output);\n insertElementInSet(connections, [destination, output], (connection) => connection[0] === destination && connection[1] === output, true);\n if (wasDisconnected) {\n whenConnected();\n }\n return;\n };\n })(nativeAudioNode.connect);\n nativeAudioNode.disconnect = ((disconnect) => {\n return (destinationOrOutput, output, input) => {\n const wasConnected = connections.size > 0;\n if (destinationOrOutput === undefined) {\n disconnect.apply(nativeAudioNode);\n connections.clear();\n }\n else if (typeof destinationOrOutput === \'number\') {\n // @todo TypeScript cannot infer the overloaded signature with 1 argument yet.\n disconnect.call(nativeAudioNode, destinationOrOutput);\n for (const connection of connections) {\n if (connection[1] === destinationOrOutput) {\n connections.delete(connection);\n }\n }\n }\n else {\n if (isNativeAudioNode(destinationOrOutput)) {\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n disconnect.call(nativeAudioNode, destinationOrOutput, output, input);\n }\n else {\n // @todo TypeScript cannot infer the overloaded signature with 2 arguments yet.\n disconnect.call(nativeAudioNode, destinationOrOutput, output);\n }\n for (const connection of connections) {\n if (connection[0] === destinationOrOutput &&\n (output === undefined || connection[1] === output) &&\n (input === undefined || connection[2] === input)) {\n connections.delete(connection);\n }\n }\n }\n const isDisconnected = connections.size === 0;\n if (wasConnected && isDisconnected) {\n whenDisconnected();\n }\n };\n })(nativeAudioNode.disconnect);\n return nativeAudioNode;\n };\n};\n//# sourceMappingURL=monitor-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-option.js\nconst assignNativeAudioNodeOption = (nativeAudioNode, options, option) => {\n const value = options[option];\n if (value !== undefined && value !== nativeAudioNode[option]) {\n nativeAudioNode[option] = value;\n }\n};\n//# sourceMappingURL=assign-native-audio-node-option.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-options.js\n\nconst assignNativeAudioNodeOptions = (nativeAudioNode, options) => {\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelCount\');\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelCountMode\');\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelInterpretation\');\n};\n//# sourceMappingURL=assign-native-audio-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-analyser-node-get-float-time-domain-data-method-support.js\nconst testAnalyserNodeGetFloatTimeDomainDataMethodSupport = (nativeAnalyserNode) => {\n return typeof nativeAnalyserNode.getFloatTimeDomainData === \'function\';\n};\n//# sourceMappingURL=test-analyser-node-get-float-time-domain-data-method-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-analyser-node-get-float-time-domain-data-method.js\nconst wrapAnalyserNodeGetFloatTimeDomainDataMethod = (nativeAnalyserNode) => {\n nativeAnalyserNode.getFloatTimeDomainData = (array) => {\n const byteTimeDomainData = new Uint8Array(array.length);\n nativeAnalyserNode.getByteTimeDomainData(byteTimeDomainData);\n const length = Math.max(byteTimeDomainData.length, nativeAnalyserNode.fftSize);\n for (let i = 0; i < length; i += 1) {\n array[i] = (byteTimeDomainData[i] - 128) * 0.0078125;\n }\n return array;\n };\n};\n//# sourceMappingURL=wrap-analyser-node-get-float-time-domain-data-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-analyser-node-factory.js\n\n\n\n\nconst createNativeAnalyserNodeFactory = (cacheTestResult, createIndexSizeError) => {\n return (nativeContext, options) => {\n const nativeAnalyserNode = nativeContext.createAnalyser();\n // Bug #37: Firefox does not create an AnalyserNode with the default properties.\n assignNativeAudioNodeOptions(nativeAnalyserNode, options);\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n if (!(options.maxDecibels > options.minDecibels)) {\n throw createIndexSizeError();\n }\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'fftSize\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'maxDecibels\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'minDecibels\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'smoothingTimeConstant\');\n // Bug #36: Safari does not support getFloatTimeDomainData() yet.\n if (!cacheTestResult(testAnalyserNodeGetFloatTimeDomainDataMethodSupport, () => testAnalyserNodeGetFloatTimeDomainDataMethodSupport(nativeAnalyserNode))) {\n wrapAnalyserNodeGetFloatTimeDomainDataMethod(nativeAnalyserNode);\n }\n return nativeAnalyserNode;\n };\n};\n//# sourceMappingURL=native-analyser-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-buffer-constructor.js\nconst createNativeAudioBufferConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'AudioBuffer\')) {\n return window.AudioBuffer;\n }\n return null;\n};\n//# sourceMappingURL=native-audio-buffer-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-audio-param-value.js\nconst assignNativeAudioNodeAudioParamValue = (nativeAudioNode, options, audioParam) => {\n const value = options[audioParam];\n if (value !== undefined && value !== nativeAudioNode[audioParam].value) {\n nativeAudioNode[audioParam].value = value;\n }\n};\n//# sourceMappingURL=assign-native-audio-node-audio-param-value.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-source-node-start-method-consecutive-calls.js\n\nconst wrapAudioBufferSourceNodeStartMethodConsecutiveCalls = (nativeAudioBufferSourceNode) => {\n nativeAudioBufferSourceNode.start = ((start) => {\n let isScheduled = false;\n return (when = 0, offset = 0, duration) => {\n if (isScheduled) {\n throw createInvalidStateError();\n }\n start.call(nativeAudioBufferSourceNode, when, offset, duration);\n isScheduled = true;\n };\n })(nativeAudioBufferSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-start-method-consecutive-calls.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-start-method-negative-parameters.js\nconst wrapAudioScheduledSourceNodeStartMethodNegativeParameters = (nativeAudioScheduledSourceNode) => {\n nativeAudioScheduledSourceNode.start = ((start) => {\n return (when = 0, offset = 0, duration) => {\n if ((typeof duration === \'number\' && duration < 0) || offset < 0 || when < 0) {\n throw new RangeError("The parameters can\'t be negative.");\n }\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n start.call(nativeAudioScheduledSourceNode, when, offset, duration);\n };\n })(nativeAudioScheduledSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-start-method-negative-parameters.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-stop-method-negative-parameters.js\nconst wrapAudioScheduledSourceNodeStopMethodNegativeParameters = (nativeAudioScheduledSourceNode) => {\n nativeAudioScheduledSourceNode.stop = ((stop) => {\n return (when = 0) => {\n if (when < 0) {\n throw new RangeError("The parameter can\'t be negative.");\n }\n stop.call(nativeAudioScheduledSourceNode, when);\n };\n })(nativeAudioScheduledSourceNode.stop);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-stop-method-negative-parameters.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-buffer-source-node-factory.js\n\n\n\n\n\n\nconst createNativeAudioBufferSourceNodeFactory = (addSilentConnection, cacheTestResult, testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, testAudioBufferSourceNodeStartMethodOffsetClampingSupport, testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioBufferSourceNodeStartMethodOffsetClampling, wrapAudioBufferSourceNodeStopMethodNullifiedBuffer, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls) => {\n return (nativeContext, options) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n assignNativeAudioNodeOptions(nativeAudioBufferSourceNode, options);\n assignNativeAudioNodeAudioParamValue(nativeAudioBufferSourceNode, options, \'playbackRate\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'buffer\');\n // Bug #149: Safari does not yet support the detune AudioParam.\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loop\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loopEnd\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loopStart\');\n // Bug #69: Safari does allow calls to start() of an already scheduled AudioBufferSourceNode.\n if (!cacheTestResult(testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, () => testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStartMethodConsecutiveCalls(nativeAudioBufferSourceNode);\n }\n // Bug #154 & #155: Safari does not handle offsets which are equal to or greater than the duration of the buffer.\n if (!cacheTestResult(testAudioBufferSourceNodeStartMethodOffsetClampingSupport, () => testAudioBufferSourceNodeStartMethodOffsetClampingSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStartMethodOffsetClampling(nativeAudioBufferSourceNode);\n }\n // Bug #162: Safari does throw an error when stop() is called on an AudioBufferSourceNode which has no buffer assigned to it.\n if (!cacheTestResult(testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, () => testAudioBufferSourceNodeStopMethodNullifiedBufferSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStopMethodNullifiedBuffer(nativeAudioBufferSourceNode, nativeContext);\n }\n // Bug #44: Safari does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeAudioBufferSourceNode);\n }\n // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeAudioBufferSourceNode, nativeContext);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeAudioBufferSourceNode);\n }\n // Bug #175: Safari will not fire an ended event if the AudioBufferSourceNode is unconnected.\n addSilentConnection(nativeContext, nativeAudioBufferSourceNode);\n return nativeAudioBufferSourceNode;\n };\n};\n//# sourceMappingURL=native-audio-buffer-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-context-constructor.js\nconst createNativeAudioContextConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'AudioContext\')) {\n return window.AudioContext;\n }\n return window.hasOwnProperty(\'webkitAudioContext\') ? window.webkitAudioContext : null;\n};\n//# sourceMappingURL=native-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-destination-node.js\nconst createNativeAudioDestinationNodeFactory = (createNativeGainNode, overwriteAccessors) => {\n return (nativeContext, channelCount, isNodeOfNativeOfflineAudioContext) => {\n const nativeAudioDestinationNode = nativeContext.destination;\n // Bug #132: Safari does not have the correct channelCount.\n if (nativeAudioDestinationNode.channelCount !== channelCount) {\n try {\n nativeAudioDestinationNode.channelCount = channelCount;\n }\n catch {\n // Bug #169: Safari throws an error on each attempt to change the channelCount.\n }\n }\n // Bug #83: Safari does not have the correct channelCountMode.\n if (isNodeOfNativeOfflineAudioContext && nativeAudioDestinationNode.channelCountMode !== \'explicit\') {\n nativeAudioDestinationNode.channelCountMode = \'explicit\';\n }\n // Bug #47: The AudioDestinationNode in Safari does not initialize the maxChannelCount property correctly.\n if (nativeAudioDestinationNode.maxChannelCount === 0) {\n Object.defineProperty(nativeAudioDestinationNode, \'maxChannelCount\', {\n value: channelCount\n });\n }\n // Bug #168: No browser does yet have an AudioDestinationNode with an output.\n const gainNode = createNativeGainNode(nativeContext, {\n channelCount,\n channelCountMode: nativeAudioDestinationNode.channelCountMode,\n channelInterpretation: nativeAudioDestinationNode.channelInterpretation,\n gain: 1\n });\n overwriteAccessors(gainNode, \'channelCount\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n try {\n nativeAudioDestinationNode.channelCount = value;\n }\n catch (err) {\n // Bug #169: Safari throws an error on each attempt to change the channelCount.\n if (value > nativeAudioDestinationNode.maxChannelCount) {\n throw err;\n }\n }\n });\n overwriteAccessors(gainNode, \'channelCountMode\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n nativeAudioDestinationNode.channelCountMode = value;\n });\n overwriteAccessors(gainNode, \'channelInterpretation\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n nativeAudioDestinationNode.channelInterpretation = value;\n });\n Object.defineProperty(gainNode, \'maxChannelCount\', {\n get: () => nativeAudioDestinationNode.maxChannelCount\n });\n // @todo This should be disconnected when the context is closed.\n gainNode.connect(nativeAudioDestinationNode);\n return gainNode;\n };\n};\n//# sourceMappingURL=native-audio-destination-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-constructor.js\nconst createNativeAudioWorkletNodeConstructor = (window) => {\n if (window === null) {\n return null;\n }\n return window.hasOwnProperty(\'AudioWorkletNode\') ? window.AudioWorkletNode : null;\n};\n//# sourceMappingURL=native-audio-worklet-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-clonability-of-audio-worklet-node-options.js\nconst testClonabilityOfAudioWorkletNodeOptions = (audioWorkletNodeOptions) => {\n const { port1 } = new MessageChannel();\n try {\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port1.postMessage(audioWorkletNodeOptions);\n }\n finally {\n port1.close();\n }\n};\n//# sourceMappingURL=test-clonability-of-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-factory.js\n\nconst createNativeAudioWorkletNodeFactory = (createInvalidStateError, createNativeAudioWorkletNodeFaker, createNativeGainNode, createNotSupportedError, monitorConnections) => {\n return (nativeContext, baseLatency, nativeAudioWorkletNodeConstructor, name, processorConstructor, options) => {\n if (nativeAudioWorkletNodeConstructor !== null) {\n try {\n const nativeAudioWorkletNode = new nativeAudioWorkletNodeConstructor(nativeContext, name, options);\n const patchedEventListeners = new Map();\n let onprocessorerror = null;\n Object.defineProperties(nativeAudioWorkletNode, {\n /*\n * Bug #61: Overwriting the property accessors for channelCount and channelCountMode is necessary as long as some\n * browsers have no native implementation to achieve a consistent behavior.\n */\n channelCount: {\n get: () => options.channelCount,\n set: () => {\n throw createInvalidStateError();\n }\n },\n channelCountMode: {\n get: () => \'explicit\',\n set: () => {\n throw createInvalidStateError();\n }\n },\n // Bug #156: Chrome and Edge do not yet fire an ErrorEvent.\n onprocessorerror: {\n get: () => onprocessorerror,\n set: (value) => {\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNode.removeEventListener(\'processorerror\', onprocessorerror);\n }\n onprocessorerror = typeof value === \'function\' ? value : null;\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNode.addEventListener(\'processorerror\', onprocessorerror);\n }\n }\n }\n });\n nativeAudioWorkletNode.addEventListener = ((addEventListener) => {\n return (...args) => {\n if (args[0] === \'processorerror\') {\n const unpatchedEventListener = typeof args[1] === \'function\'\n ? args[1]\n : typeof args[1] === \'object\' && args[1] !== null && typeof args[1].handleEvent === \'function\'\n ? args[1].handleEvent\n : null;\n if (unpatchedEventListener !== null) {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n args[1] = patchedEventListener;\n }\n else {\n args[1] = (event) => {\n // Bug #178: Chrome and Edge do fire an event of type error.\n if (event.type === \'error\') {\n Object.defineProperties(event, {\n type: { value: \'processorerror\' }\n });\n unpatchedEventListener(event);\n }\n else {\n unpatchedEventListener(new ErrorEvent(args[0], { ...event }));\n }\n };\n patchedEventListeners.set(unpatchedEventListener, args[1]);\n }\n }\n }\n // Bug #178: Chrome and Edge do fire an event of type error.\n addEventListener.call(nativeAudioWorkletNode, \'error\', args[1], args[2]);\n return addEventListener.call(nativeAudioWorkletNode, ...args);\n };\n })(nativeAudioWorkletNode.addEventListener);\n nativeAudioWorkletNode.removeEventListener = ((removeEventListener) => {\n return (...args) => {\n if (args[0] === \'processorerror\') {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n patchedEventListeners.delete(args[1]);\n args[1] = patchedEventListener;\n }\n }\n // Bug #178: Chrome and Edge do fire an event of type error.\n removeEventListener.call(nativeAudioWorkletNode, \'error\', args[1], args[2]);\n return removeEventListener.call(nativeAudioWorkletNode, args[0], args[1], args[2]);\n };\n })(nativeAudioWorkletNode.removeEventListener);\n /*\n * Bug #86: Chrome and Edge do not invoke the process() function if the corresponding AudioWorkletNode is unconnected but\n * has an output.\n */\n if (options.numberOfOutputs !== 0) {\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeAudioWorkletNode.connect(nativeGainNode).connect(nativeContext.destination);\n const whenConnected = () => nativeGainNode.disconnect();\n const whenDisconnected = () => nativeGainNode.connect(nativeContext.destination);\n // @todo Disconnect the connection when the process() function of the AudioWorkletNode returns false.\n return monitorConnections(nativeAudioWorkletNode, whenConnected, whenDisconnected);\n }\n return nativeAudioWorkletNode;\n }\n catch (err) {\n // Bug #60: Chrome & Edge throw an InvalidStateError instead of a NotSupportedError.\n if (err.code === 11) {\n throw createNotSupportedError();\n }\n throw err;\n }\n }\n // Bug #61: Only Chrome & Edge have an implementation of the AudioWorkletNode yet.\n if (processorConstructor === undefined) {\n throw createNotSupportedError();\n }\n testClonabilityOfAudioWorkletNodeOptions(options);\n return createNativeAudioWorkletNodeFaker(nativeContext, baseLatency, processorConstructor, options);\n };\n};\n//# sourceMappingURL=native-audio-worklet-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/compute-buffer-size.js\nconst computeBufferSize = (baseLatency, sampleRate) => {\n if (baseLatency === null) {\n return 512;\n }\n return Math.max(512, Math.min(16384, Math.pow(2, Math.round(Math.log2(baseLatency * sampleRate)))));\n};\n//# sourceMappingURL=compute-buffer-size.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/clone-audio-worklet-node-options.js\nconst cloneAudioWorkletNodeOptions = (audioWorkletNodeOptions) => {\n return new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n port1.onmessage = ({ data }) => {\n port1.close();\n port2.close();\n resolve(data);\n };\n port1.onmessageerror = ({ data }) => {\n port1.close();\n port2.close();\n reject(data);\n };\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port2.postMessage(audioWorkletNodeOptions);\n });\n};\n//# sourceMappingURL=clone-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-audio-worklet-processor-promise.js\n\nconst createAudioWorkletProcessorPromise = async (processorConstructor, audioWorkletNodeOptions) => {\n const clonedAudioWorkletNodeOptions = await cloneAudioWorkletNodeOptions(audioWorkletNodeOptions);\n return new processorConstructor(clonedAudioWorkletNodeOptions);\n};\n//# sourceMappingURL=create-audio-worklet-processor-promise.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-audio-worklet-processor.js\n\n\nconst createAudioWorkletProcessor = (nativeContext, nativeAudioWorkletNode, processorConstructor, audioWorkletNodeOptions) => {\n let nodeToProcessorMap = NODE_TO_PROCESSOR_MAPS.get(nativeContext);\n if (nodeToProcessorMap === undefined) {\n nodeToProcessorMap = new WeakMap();\n NODE_TO_PROCESSOR_MAPS.set(nativeContext, nodeToProcessorMap);\n }\n const audioWorkletProcessorPromise = createAudioWorkletProcessorPromise(processorConstructor, audioWorkletNodeOptions);\n nodeToProcessorMap.set(nativeAudioWorkletNode, audioWorkletProcessorPromise);\n return audioWorkletProcessorPromise;\n};\n//# sourceMappingURL=create-audio-worklet-processor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-faker-factory.js\n\n\n\n\n\n\n\nconst createNativeAudioWorkletNodeFakerFactory = (connectMultipleOutputs, createIndexSizeError, createInvalidStateError, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, createNativeScriptProcessorNode, createNotSupportedError, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getActiveAudioWorkletNodeInputs, monitorConnections) => {\n return (nativeContext, baseLatency, processorConstructor, options) => {\n if (options.numberOfInputs === 0 && options.numberOfOutputs === 0) {\n throw createNotSupportedError();\n }\n const outputChannelCount = Array.isArray(options.outputChannelCount)\n ? options.outputChannelCount\n : Array.from(options.outputChannelCount);\n // @todo Check if any of the channelCount values is greater than the implementation\'s maximum number of channels.\n if (outputChannelCount.some((channelCount) => channelCount < 1)) {\n throw createNotSupportedError();\n }\n if (outputChannelCount.length !== options.numberOfOutputs) {\n throw createIndexSizeError();\n }\n // Bug #61: This is not part of the standard but required for the faker to work.\n if (options.channelCountMode !== \'explicit\') {\n throw createNotSupportedError();\n }\n const numberOfInputChannels = options.channelCount * options.numberOfInputs;\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const numberOfParameters = processorConstructor.parameterDescriptors === undefined ? 0 : processorConstructor.parameterDescriptors.length;\n // Bug #61: This is not part of the standard but required for the faker to work.\n if (numberOfInputChannels + numberOfParameters > 6 || numberOfOutputChannels > 6) {\n throw createNotSupportedError();\n }\n const messageChannel = new MessageChannel();\n const gainNodes = [];\n const inputChannelSplitterNodes = [];\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes.push(createNativeGainNode(nativeContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n }));\n inputChannelSplitterNodes.push(createNativeChannelSplitterNode(nativeContext, {\n channelCount: options.channelCount,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: options.channelCount\n }));\n }\n const constantSourceNodes = [];\n if (processorConstructor.parameterDescriptors !== undefined) {\n for (const { defaultValue, maxValue, minValue, name } of processorConstructor.parameterDescriptors) {\n const constantSourceNode = createNativeConstantSourceNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: options.parameterData[name] !== undefined\n ? options.parameterData[name]\n : defaultValue === undefined\n ? 0\n : defaultValue\n });\n Object.defineProperties(constantSourceNode.offset, {\n defaultValue: {\n get: () => (defaultValue === undefined ? 0 : defaultValue)\n },\n maxValue: {\n get: () => (maxValue === undefined ? MOST_POSITIVE_SINGLE_FLOAT : maxValue)\n },\n minValue: {\n get: () => (minValue === undefined ? MOST_NEGATIVE_SINGLE_FLOAT : minValue)\n }\n });\n constantSourceNodes.push(constantSourceNode);\n }\n }\n const inputChannelMergerNode = createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: Math.max(1, numberOfInputChannels + numberOfParameters)\n });\n const bufferSize = computeBufferSize(baseLatency, nativeContext.sampleRate);\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, bufferSize, numberOfInputChannels + numberOfParameters, \n // Bug #87: Only Firefox will fire an AudioProcessingEvent if there is no connected output.\n Math.max(1, numberOfOutputChannels));\n const outputChannelSplitterNode = createNativeChannelSplitterNode(nativeContext, {\n channelCount: Math.max(1, numberOfOutputChannels),\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: Math.max(1, numberOfOutputChannels)\n });\n const outputChannelMergerNodes = [];\n for (let i = 0; i < options.numberOfOutputs; i += 1) {\n outputChannelMergerNodes.push(createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: outputChannelCount[i]\n }));\n }\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes[i].connect(inputChannelSplitterNodes[i]);\n for (let j = 0; j < options.channelCount; j += 1) {\n inputChannelSplitterNodes[i].connect(inputChannelMergerNode, j, i * options.channelCount + j);\n }\n }\n const parameterMap = new ReadOnlyMap(processorConstructor.parameterDescriptors === undefined\n ? []\n : processorConstructor.parameterDescriptors.map(({ name }, index) => {\n const constantSourceNode = constantSourceNodes[index];\n constantSourceNode.connect(inputChannelMergerNode, 0, numberOfInputChannels + index);\n constantSourceNode.start(0);\n return [name, constantSourceNode.offset];\n }));\n inputChannelMergerNode.connect(scriptProcessorNode);\n let channelInterpretation = options.channelInterpretation;\n let onprocessorerror = null;\n // Bug #87: Expose at least one output to make this node connectable.\n const outputAudioNodes = options.numberOfOutputs === 0 ? [scriptProcessorNode] : outputChannelMergerNodes;\n const nativeAudioWorkletNodeFaker = {\n get bufferSize() {\n return bufferSize;\n },\n get channelCount() {\n return options.channelCount;\n },\n set channelCount(_) {\n // Bug #61: This is not part of the standard but required for the faker to work.\n throw createInvalidStateError();\n },\n get channelCountMode() {\n return options.channelCountMode;\n },\n set channelCountMode(_) {\n // Bug #61: This is not part of the standard but required for the faker to work.\n throw createInvalidStateError();\n },\n get channelInterpretation() {\n return channelInterpretation;\n },\n set channelInterpretation(value) {\n for (const gainNode of gainNodes) {\n gainNode.channelInterpretation = value;\n }\n channelInterpretation = value;\n },\n get context() {\n return scriptProcessorNode.context;\n },\n get inputs() {\n return gainNodes;\n },\n get numberOfInputs() {\n return options.numberOfInputs;\n },\n get numberOfOutputs() {\n return options.numberOfOutputs;\n },\n get onprocessorerror() {\n return onprocessorerror;\n },\n set onprocessorerror(value) {\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNodeFaker.removeEventListener(\'processorerror\', onprocessorerror);\n }\n onprocessorerror = typeof value === \'function\' ? value : null;\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNodeFaker.addEventListener(\'processorerror\', onprocessorerror);\n }\n },\n get parameters() {\n return parameterMap;\n },\n get port() {\n return messageChannel.port2;\n },\n addEventListener(...args) {\n return scriptProcessorNode.addEventListener(args[0], args[1], args[2]);\n },\n connect: connectMultipleOutputs.bind(null, outputAudioNodes),\n disconnect: disconnectMultipleOutputs.bind(null, outputAudioNodes),\n dispatchEvent(...args) {\n return scriptProcessorNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return scriptProcessorNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n const patchedEventListeners = new Map();\n messageChannel.port1.addEventListener = ((addEventListener) => {\n return (...args) => {\n if (args[0] === \'message\') {\n const unpatchedEventListener = typeof args[1] === \'function\'\n ? args[1]\n : typeof args[1] === \'object\' && args[1] !== null && typeof args[1].handleEvent === \'function\'\n ? args[1].handleEvent\n : null;\n if (unpatchedEventListener !== null) {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n args[1] = patchedEventListener;\n }\n else {\n args[1] = (event) => {\n exposeCurrentFrameAndCurrentTime(nativeContext.currentTime, nativeContext.sampleRate, () => unpatchedEventListener(event));\n };\n patchedEventListeners.set(unpatchedEventListener, args[1]);\n }\n }\n }\n return addEventListener.call(messageChannel.port1, args[0], args[1], args[2]);\n };\n })(messageChannel.port1.addEventListener);\n messageChannel.port1.removeEventListener = ((removeEventListener) => {\n return (...args) => {\n if (args[0] === \'message\') {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n patchedEventListeners.delete(args[1]);\n args[1] = patchedEventListener;\n }\n }\n return removeEventListener.call(messageChannel.port1, args[0], args[1], args[2]);\n };\n })(messageChannel.port1.removeEventListener);\n let onmessage = null;\n Object.defineProperty(messageChannel.port1, \'onmessage\', {\n get: () => onmessage,\n set: (value) => {\n if (typeof onmessage === \'function\') {\n messageChannel.port1.removeEventListener(\'message\', onmessage);\n }\n onmessage = typeof value === \'function\' ? value : null;\n if (typeof onmessage === \'function\') {\n messageChannel.port1.addEventListener(\'message\', onmessage);\n messageChannel.port1.start();\n }\n }\n });\n processorConstructor.prototype.port = messageChannel.port1;\n let audioWorkletProcessor = null;\n const audioWorkletProcessorPromise = createAudioWorkletProcessor(nativeContext, nativeAudioWorkletNodeFaker, processorConstructor, options);\n audioWorkletProcessorPromise.then((dWrkltPrcssr) => (audioWorkletProcessor = dWrkltPrcssr));\n const inputs = createNestedArrays(options.numberOfInputs, options.channelCount);\n const outputs = createNestedArrays(options.numberOfOutputs, outputChannelCount);\n const parameters = processorConstructor.parameterDescriptors === undefined\n ? []\n : processorConstructor.parameterDescriptors.reduce((prmtrs, { name }) => ({ ...prmtrs, [name]: new Float32Array(128) }), {});\n let isActive = true;\n const disconnectOutputsGraph = () => {\n if (options.numberOfOutputs > 0) {\n scriptProcessorNode.disconnect(outputChannelSplitterNode);\n }\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < options.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.disconnect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n };\n const activeInputIndexes = new Map();\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer, outputBuffer }) => {\n if (audioWorkletProcessor !== null) {\n const activeInputs = getActiveAudioWorkletNodeInputs(nativeAudioWorkletNodeFaker);\n for (let i = 0; i < bufferSize; i += 128) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < options.channelCount; k += 1) {\n copyFromChannel(inputBuffer, inputs[j], k, k, i);\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined) {\n processorConstructor.parameterDescriptors.forEach(({ name }, index) => {\n copyFromChannel(inputBuffer, parameters, name, numberOfInputChannels + index, i);\n });\n }\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (outputs[j][k].byteLength === 0) {\n outputs[j][k] = new Float32Array(128);\n }\n }\n }\n try {\n const potentiallyEmptyInputs = inputs.map((input, index) => {\n const activeInput = activeInputs[index];\n if (activeInput.size > 0) {\n activeInputIndexes.set(index, bufferSize / 128);\n return input;\n }\n const count = activeInputIndexes.get(index);\n if (count === undefined) {\n return [];\n }\n if (input.every((channelData) => channelData.every((sample) => sample === 0))) {\n if (count === 1) {\n activeInputIndexes.delete(index);\n }\n else {\n activeInputIndexes.set(index, count - 1);\n }\n }\n return input;\n });\n const activeSourceFlag = exposeCurrentFrameAndCurrentTime(nativeContext.currentTime + i / nativeContext.sampleRate, nativeContext.sampleRate, () => audioWorkletProcessor.process(potentiallyEmptyInputs, outputs, parameters));\n isActive = activeSourceFlag;\n for (let j = 0, outputChannelSplitterNodeOutput = 0; j < options.numberOfOutputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n copyToChannel(outputBuffer, outputs[j], k, outputChannelSplitterNodeOutput + k, i);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[j];\n }\n }\n catch (error) {\n isActive = false;\n nativeAudioWorkletNodeFaker.dispatchEvent(new ErrorEvent(\'processorerror\', {\n colno: error.colno,\n filename: error.filename,\n lineno: error.lineno,\n message: error.message\n }));\n }\n if (!isActive) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n gainNodes[j].disconnect(inputChannelSplitterNodes[j]);\n for (let k = 0; k < options.channelCount; k += 1) {\n inputChannelSplitterNodes[i].disconnect(inputChannelMergerNode, k, j * options.channelCount + k);\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined) {\n const length = processorConstructor.parameterDescriptors.length;\n for (let j = 0; j < length; j += 1) {\n const constantSourceNode = constantSourceNodes[j];\n constantSourceNode.disconnect(inputChannelMergerNode, 0, numberOfInputChannels + j);\n constantSourceNode.stop();\n }\n }\n inputChannelMergerNode.disconnect(scriptProcessorNode);\n scriptProcessorNode.onaudioprocess = null; // tslint:disable-line:deprecation\n if (isConnected) {\n disconnectOutputsGraph();\n }\n else {\n disconnectFakeGraph();\n }\n break;\n }\n }\n }\n };\n let isConnected = false;\n // Bug #87: Only Firefox will fire an AudioProcessingEvent if there is no connected output.\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n const connectFakeGraph = () => scriptProcessorNode.connect(nativeGainNode).connect(nativeContext.destination);\n const disconnectFakeGraph = () => {\n scriptProcessorNode.disconnect(nativeGainNode);\n nativeGainNode.disconnect();\n };\n const whenConnected = () => {\n if (isActive) {\n disconnectFakeGraph();\n if (options.numberOfOutputs > 0) {\n scriptProcessorNode.connect(outputChannelSplitterNode);\n }\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < options.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.connect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n }\n isConnected = true;\n };\n const whenDisconnected = () => {\n if (isActive) {\n connectFakeGraph();\n disconnectOutputsGraph();\n }\n isConnected = false;\n };\n connectFakeGraph();\n return monitorConnections(nativeAudioWorkletNodeFaker, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-audio-worklet-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-biquad-filter-node.js\n\n\n\nconst createNativeBiquadFilterNode = (nativeContext, options) => {\n const nativeBiquadFilterNode = nativeContext.createBiquadFilter();\n assignNativeAudioNodeOptions(nativeBiquadFilterNode, options);\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'Q\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'detune\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'frequency\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'gain\');\n assignNativeAudioNodeOption(nativeBiquadFilterNode, options, \'type\');\n return nativeBiquadFilterNode;\n};\n//# sourceMappingURL=native-biquad-filter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-channel-merger-node-factory.js\n\nconst createNativeChannelMergerNodeFactory = (nativeAudioContextConstructor, wrapChannelMergerNode) => {\n return (nativeContext, options) => {\n const nativeChannelMergerNode = nativeContext.createChannelMerger(options.numberOfInputs);\n /*\n * Bug #20: Safari requires a connection of any kind to treat the input signal correctly.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the existence of\n * the webkitAudioContext is used as a workaround here.\n */\n if (nativeAudioContextConstructor !== null && nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n wrapChannelMergerNode(nativeContext, nativeChannelMergerNode);\n }\n assignNativeAudioNodeOptions(nativeChannelMergerNode, options);\n return nativeChannelMergerNode;\n };\n};\n//# sourceMappingURL=native-channel-merger-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-channel-splitter-node.js\n\nconst wrapChannelSplitterNode = (channelSplitterNode) => {\n const channelCount = channelSplitterNode.numberOfOutputs;\n // Bug #97: Safari does not throw an error when attempting to change the channelCount to something other than its initial value.\n Object.defineProperty(channelSplitterNode, \'channelCount\', {\n get: () => channelCount,\n set: (value) => {\n if (value !== channelCount) {\n throw createInvalidStateError();\n }\n }\n });\n // Bug #30: Safari does not throw an error when attempting to change the channelCountMode to something other than explicit.\n Object.defineProperty(channelSplitterNode, \'channelCountMode\', {\n get: () => \'explicit\',\n set: (value) => {\n if (value !== \'explicit\') {\n throw createInvalidStateError();\n }\n }\n });\n // Bug #32: Safari does not throw an error when attempting to change the channelInterpretation to something other than discrete.\n Object.defineProperty(channelSplitterNode, \'channelInterpretation\', {\n get: () => \'discrete\',\n set: (value) => {\n if (value !== \'discrete\') {\n throw createInvalidStateError();\n }\n }\n });\n};\n//# sourceMappingURL=wrap-channel-splitter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-channel-splitter-node.js\n\n\nconst createNativeChannelSplitterNode = (nativeContext, options) => {\n const nativeChannelSplitterNode = nativeContext.createChannelSplitter(options.numberOfOutputs);\n // Bug #96: Safari does not have the correct channelCount.\n // Bug #29: Safari does not have the correct channelCountMode.\n // Bug #31: Safari does not have the correct channelInterpretation.\n assignNativeAudioNodeOptions(nativeChannelSplitterNode, options);\n // Bug #29, #30, #31, #32, #96 & #97: Only Chrome, Edge & Firefox partially support the spec yet.\n wrapChannelSplitterNode(nativeChannelSplitterNode);\n return nativeChannelSplitterNode;\n};\n//# sourceMappingURL=native-channel-splitter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-constant-source-node-factory.js\n\n\n\n\nconst createNativeConstantSourceNodeFactory = (addSilentConnection, cacheTestResult, createNativeConstantSourceNodeFaker, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport) => {\n return (nativeContext, options) => {\n // Bug #62: Safari does not support ConstantSourceNodes.\n if (nativeContext.createConstantSource === undefined) {\n return createNativeConstantSourceNodeFaker(nativeContext, options);\n }\n const nativeConstantSourceNode = nativeContext.createConstantSource();\n assignNativeAudioNodeOptions(nativeConstantSourceNode, options);\n assignNativeAudioNodeAudioParamValue(nativeConstantSourceNode, options, \'offset\');\n // Bug #44: Safari does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeConstantSourceNode);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeConstantSourceNode);\n }\n // Bug #175: Safari will not fire an ended event if the ConstantSourceNode is unconnected.\n addSilentConnection(nativeContext, nativeConstantSourceNode);\n return nativeConstantSourceNode;\n };\n};\n//# sourceMappingURL=native-constant-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/intercept-connections.js\nconst interceptConnections = (original, interceptor) => {\n original.connect = interceptor.connect.bind(interceptor);\n original.disconnect = interceptor.disconnect.bind(interceptor);\n return original;\n};\n//# sourceMappingURL=intercept-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-constant-source-node-faker-factory.js\n\nconst createNativeConstantSourceNodeFakerFactory = (addSilentConnection, createNativeAudioBufferSourceNode, createNativeGainNode, monitorConnections) => {\n return (nativeContext, { offset, ...audioNodeOptions }) => {\n const audioBuffer = nativeContext.createBuffer(1, 2, 44100);\n const audioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const gainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: offset });\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n const channelData = audioBuffer.getChannelData(0);\n // Bug #95: Safari does not play or loop one sample buffers.\n channelData[0] = 1;\n channelData[1] = 1;\n audioBufferSourceNode.buffer = audioBuffer;\n audioBufferSourceNode.loop = true;\n const nativeConstantSourceNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return gainNode.channelCount;\n },\n set channelCount(value) {\n gainNode.channelCount = value;\n },\n get channelCountMode() {\n return gainNode.channelCountMode;\n },\n set channelCountMode(value) {\n gainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return gainNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n gainNode.channelInterpretation = value;\n },\n get context() {\n return gainNode.context;\n },\n get inputs() {\n return [];\n },\n get numberOfInputs() {\n return audioBufferSourceNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return gainNode.numberOfOutputs;\n },\n get offset() {\n return gainNode.gain;\n },\n get onended() {\n return audioBufferSourceNode.onended;\n },\n set onended(value) {\n audioBufferSourceNode.onended = value;\n },\n addEventListener(...args) {\n return audioBufferSourceNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return audioBufferSourceNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return audioBufferSourceNode.removeEventListener(args[0], args[1], args[2]);\n },\n start(when = 0) {\n audioBufferSourceNode.start.call(audioBufferSourceNode, when);\n },\n stop(when = 0) {\n audioBufferSourceNode.stop.call(audioBufferSourceNode, when);\n }\n };\n const whenConnected = () => audioBufferSourceNode.connect(gainNode);\n const whenDisconnected = () => audioBufferSourceNode.disconnect(gainNode);\n // Bug #175: Safari will not fire an ended event if the AudioBufferSourceNode is unconnected.\n addSilentConnection(nativeContext, audioBufferSourceNode);\n return monitorConnections(interceptConnections(nativeConstantSourceNodeFaker, gainNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-constant-source-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-convolver-node-factory.js\n\n\nconst createNativeConvolverNodeFactory = (createNotSupportedError, overwriteAccessors) => {\n return (nativeContext, options) => {\n const nativeConvolverNode = nativeContext.createConvolver();\n assignNativeAudioNodeOptions(nativeConvolverNode, options);\n // The normalize property needs to be set before setting the buffer.\n if (options.disableNormalization === nativeConvolverNode.normalize) {\n nativeConvolverNode.normalize = !options.disableNormalization;\n }\n assignNativeAudioNodeOption(nativeConvolverNode, options, \'buffer\');\n // Bug #113: Safari does allow to set the channelCount to a value larger than 2.\n if (options.channelCount > 2) {\n throw createNotSupportedError();\n }\n overwriteAccessors(nativeConvolverNode, \'channelCount\', (get) => () => get.call(nativeConvolverNode), (set) => (value) => {\n if (value > 2) {\n throw createNotSupportedError();\n }\n return set.call(nativeConvolverNode, value);\n });\n // Bug #114: Safari allows to set the channelCountMode to \'max\'.\n if (options.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n overwriteAccessors(nativeConvolverNode, \'channelCountMode\', (get) => () => get.call(nativeConvolverNode), (set) => (value) => {\n if (value === \'max\') {\n throw createNotSupportedError();\n }\n return set.call(nativeConvolverNode, value);\n });\n return nativeConvolverNode;\n };\n};\n//# sourceMappingURL=native-convolver-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-delay-node.js\n\n\nconst createNativeDelayNode = (nativeContext, options) => {\n const nativeDelayNode = nativeContext.createDelay(options.maxDelayTime);\n assignNativeAudioNodeOptions(nativeDelayNode, options);\n assignNativeAudioNodeAudioParamValue(nativeDelayNode, options, \'delayTime\');\n return nativeDelayNode;\n};\n//# sourceMappingURL=native-delay-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-dynamics-compressor-node-factory.js\n\n\nconst createNativeDynamicsCompressorNodeFactory = (createNotSupportedError) => {\n return (nativeContext, options) => {\n const nativeDynamicsCompressorNode = nativeContext.createDynamicsCompressor();\n assignNativeAudioNodeOptions(nativeDynamicsCompressorNode, options);\n // Bug #108: Safari allows a channelCount of three and above.\n if (options.channelCount > 2) {\n throw createNotSupportedError();\n }\n // Bug #109: Only Chrome and Firefox disallow a channelCountMode of \'max\'.\n if (options.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'attack\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'knee\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'ratio\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'release\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'threshold\');\n return nativeDynamicsCompressorNode;\n };\n};\n//# sourceMappingURL=native-dynamics-compressor-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-gain-node.js\n\n\nconst createNativeGainNode = (nativeContext, options) => {\n const nativeGainNode = nativeContext.createGain();\n assignNativeAudioNodeOptions(nativeGainNode, options);\n assignNativeAudioNodeAudioParamValue(nativeGainNode, options, \'gain\');\n return nativeGainNode;\n};\n//# sourceMappingURL=native-gain-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-iir-filter-node-factory.js\n\nconst createNativeIIRFilterNodeFactory = (createNativeIIRFilterNodeFaker) => {\n return (nativeContext, baseLatency, options) => {\n // Bug #9: Safari does not support IIRFilterNodes.\n if (nativeContext.createIIRFilter === undefined) {\n return createNativeIIRFilterNodeFaker(nativeContext, baseLatency, options);\n }\n // @todo TypeScript defines the parameters of createIIRFilter() as arrays of numbers.\n const nativeIIRFilterNode = nativeContext.createIIRFilter(options.feedforward, options.feedback);\n assignNativeAudioNodeOptions(nativeIIRFilterNode, options);\n return nativeIIRFilterNode;\n };\n};\n//# sourceMappingURL=native-iir-filter-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-iir-filter-node-faker-factory.js\n\n\n\nfunction divide(a, b) {\n const denominator = b[0] * b[0] + b[1] * b[1];\n return [(a[0] * b[0] + a[1] * b[1]) / denominator, (a[1] * b[0] - a[0] * b[1]) / denominator];\n}\nfunction multiply(a, b) {\n return [a[0] * b[0] - a[1] * b[1], a[0] * b[1] + a[1] * b[0]];\n}\nfunction evaluatePolynomial(coefficient, z) {\n let result = [0, 0];\n for (let i = coefficient.length - 1; i >= 0; i -= 1) {\n result = multiply(result, z);\n result[0] += coefficient[i];\n }\n return result;\n}\nconst createNativeIIRFilterNodeFakerFactory = (createInvalidAccessError, createInvalidStateError, createNativeScriptProcessorNode, createNotSupportedError) => {\n return (nativeContext, baseLatency, { channelCount, channelCountMode, channelInterpretation, feedback, feedforward }) => {\n const bufferSize = computeBufferSize(baseLatency, nativeContext.sampleRate);\n const convertedFeedback = feedback instanceof Float64Array ? feedback : new Float64Array(feedback);\n const convertedFeedforward = feedforward instanceof Float64Array ? feedforward : new Float64Array(feedforward);\n const feedbackLength = convertedFeedback.length;\n const feedforwardLength = convertedFeedforward.length;\n const minLength = Math.min(feedbackLength, feedforwardLength);\n if (feedbackLength === 0 || feedbackLength > 20) {\n throw createNotSupportedError();\n }\n if (convertedFeedback[0] === 0) {\n throw createInvalidStateError();\n }\n if (feedforwardLength === 0 || feedforwardLength > 20) {\n throw createNotSupportedError();\n }\n if (convertedFeedforward[0] === 0) {\n throw createInvalidStateError();\n }\n if (convertedFeedback[0] !== 1) {\n for (let i = 0; i < feedforwardLength; i += 1) {\n convertedFeedforward[i] /= convertedFeedback[0];\n }\n for (let i = 1; i < feedbackLength; i += 1) {\n convertedFeedback[i] /= convertedFeedback[0];\n }\n }\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, bufferSize, channelCount, channelCount);\n scriptProcessorNode.channelCount = channelCount;\n scriptProcessorNode.channelCountMode = channelCountMode;\n scriptProcessorNode.channelInterpretation = channelInterpretation;\n const bufferLength = 32;\n const bufferIndexes = [];\n const xBuffers = [];\n const yBuffers = [];\n for (let i = 0; i < channelCount; i += 1) {\n bufferIndexes.push(0);\n const xBuffer = new Float32Array(bufferLength);\n const yBuffer = new Float32Array(bufferLength);\n xBuffer.fill(0);\n yBuffer.fill(0);\n xBuffers.push(xBuffer);\n yBuffers.push(yBuffer);\n }\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = (event) => {\n const inputBuffer = event.inputBuffer;\n const outputBuffer = event.outputBuffer;\n const numberOfChannels = inputBuffer.numberOfChannels;\n for (let i = 0; i < numberOfChannels; i += 1) {\n const input = inputBuffer.getChannelData(i);\n const output = outputBuffer.getChannelData(i);\n bufferIndexes[i] = filterBuffer(convertedFeedback, feedbackLength, convertedFeedforward, feedforwardLength, minLength, xBuffers[i], yBuffers[i], bufferIndexes[i], bufferLength, input, output);\n }\n };\n const nyquist = nativeContext.sampleRate / 2;\n const nativeIIRFilterNodeFaker = {\n get bufferSize() {\n return bufferSize;\n },\n get channelCount() {\n return scriptProcessorNode.channelCount;\n },\n set channelCount(value) {\n scriptProcessorNode.channelCount = value;\n },\n get channelCountMode() {\n return scriptProcessorNode.channelCountMode;\n },\n set channelCountMode(value) {\n scriptProcessorNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return scriptProcessorNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n scriptProcessorNode.channelInterpretation = value;\n },\n get context() {\n return scriptProcessorNode.context;\n },\n get inputs() {\n return [scriptProcessorNode];\n },\n get numberOfInputs() {\n return scriptProcessorNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return scriptProcessorNode.numberOfOutputs;\n },\n addEventListener(...args) {\n // @todo Dissallow adding an audioprocess listener.\n return scriptProcessorNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return scriptProcessorNode.dispatchEvent(args[0]);\n },\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n const length = frequencyHz.length;\n for (let i = 0; i < length; i += 1) {\n const omega = -Math.PI * (frequencyHz[i] / nyquist);\n const z = [Math.cos(omega), Math.sin(omega)];\n const numerator = evaluatePolynomial(convertedFeedforward, z);\n const denominator = evaluatePolynomial(convertedFeedback, z);\n const response = divide(numerator, denominator);\n magResponse[i] = Math.sqrt(response[0] * response[0] + response[1] * response[1]);\n phaseResponse[i] = Math.atan2(response[1], response[0]);\n }\n },\n removeEventListener(...args) {\n return scriptProcessorNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n return interceptConnections(nativeIIRFilterNodeFaker, scriptProcessorNode);\n };\n};\n//# sourceMappingURL=native-iir-filter-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-element-audio-source-node.js\nconst createNativeMediaElementAudioSourceNode = (nativeAudioContext, options) => {\n return nativeAudioContext.createMediaElementSource(options.mediaElement);\n};\n//# sourceMappingURL=native-media-element-audio-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-audio-destination-node.js\n\nconst createNativeMediaStreamAudioDestinationNode = (nativeAudioContext, options) => {\n const nativeMediaStreamAudioDestinationNode = nativeAudioContext.createMediaStreamDestination();\n assignNativeAudioNodeOptions(nativeMediaStreamAudioDestinationNode, options);\n // Bug #174: Safari does expose a wrong numberOfOutputs.\n if (nativeMediaStreamAudioDestinationNode.numberOfOutputs === 1) {\n Object.defineProperty(nativeMediaStreamAudioDestinationNode, \'numberOfOutputs\', { get: () => 0 });\n }\n return nativeMediaStreamAudioDestinationNode;\n};\n//# sourceMappingURL=native-media-stream-audio-destination-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-audio-source-node.js\nconst createNativeMediaStreamAudioSourceNode = (nativeAudioContext, { mediaStream }) => {\n const audioStreamTracks = mediaStream.getAudioTracks();\n /*\n * Bug #151: Safari does not use the audio track as input anymore if it gets removed from the mediaStream after construction.\n * Bug #159: Safari picks the first audio track if the MediaStream has more than one audio track.\n */\n audioStreamTracks.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));\n const filteredAudioStreamTracks = audioStreamTracks.slice(0, 1);\n const nativeMediaStreamAudioSourceNode = nativeAudioContext.createMediaStreamSource(new MediaStream(filteredAudioStreamTracks));\n /*\n * Bug #151 & #159: The given mediaStream gets reconstructed before it gets passed to the native node which is why the accessor needs\n * to be overwritten as it would otherwise expose the reconstructed version.\n */\n Object.defineProperty(nativeMediaStreamAudioSourceNode, \'mediaStream\', { value: mediaStream });\n return nativeMediaStreamAudioSourceNode;\n};\n//# sourceMappingURL=native-media-stream-audio-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-track-audio-source-node-factory.js\nconst createNativeMediaStreamTrackAudioSourceNodeFactory = (createInvalidStateError, isNativeOfflineAudioContext) => {\n return (nativeAudioContext, { mediaStreamTrack }) => {\n // Bug #121: Only Firefox does yet support the MediaStreamTrackAudioSourceNode.\n if (typeof nativeAudioContext.createMediaStreamTrackSource === \'function\') {\n return nativeAudioContext.createMediaStreamTrackSource(mediaStreamTrack);\n }\n const mediaStream = new MediaStream([mediaStreamTrack]);\n const nativeMediaStreamAudioSourceNode = nativeAudioContext.createMediaStreamSource(mediaStream);\n // Bug #120: Firefox does not throw an error if the mediaStream has no audio track.\n if (mediaStreamTrack.kind !== \'audio\') {\n throw createInvalidStateError();\n }\n // Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeAudioContext)) {\n throw new TypeError();\n }\n return nativeMediaStreamAudioSourceNode;\n };\n};\n//# sourceMappingURL=native-media-stream-track-audio-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-offline-audio-context-constructor.js\nconst createNativeOfflineAudioContextConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'OfflineAudioContext\')) {\n return window.OfflineAudioContext;\n }\n return window.hasOwnProperty(\'webkitOfflineAudioContext\') ? window.webkitOfflineAudioContext : null;\n};\n//# sourceMappingURL=native-offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-oscillator-node-factory.js\n\n\n\n\n\nconst createNativeOscillatorNodeFactory = (addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls) => {\n return (nativeContext, options) => {\n const nativeOscillatorNode = nativeContext.createOscillator();\n assignNativeAudioNodeOptions(nativeOscillatorNode, options);\n assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, \'detune\');\n assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, \'frequency\');\n if (options.periodicWave !== undefined) {\n nativeOscillatorNode.setPeriodicWave(options.periodicWave);\n }\n else {\n assignNativeAudioNodeOption(nativeOscillatorNode, options, \'type\');\n }\n // Bug #44: Only Chrome & Edge throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeOscillatorNode);\n }\n // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeOscillatorNode, nativeContext);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeOscillatorNode);\n }\n // Bug #175: Safari will not fire an ended event if the OscillatorNode is unconnected.\n addSilentConnection(nativeContext, nativeOscillatorNode);\n return nativeOscillatorNode;\n };\n};\n//# sourceMappingURL=native-oscillator-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-panner-node-factory.js\n\n\n\nconst createNativePannerNodeFactory = (createNativePannerNodeFaker) => {\n return (nativeContext, options) => {\n const nativePannerNode = nativeContext.createPanner();\n // Bug #124: Safari does not support modifying the orientation and the position with AudioParams.\n if (nativePannerNode.orientationX === undefined) {\n return createNativePannerNodeFaker(nativeContext, options);\n }\n assignNativeAudioNodeOptions(nativePannerNode, options);\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationX\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationY\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationZ\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionX\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionY\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionZ\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneInnerAngle\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneOuterAngle\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneOuterGain\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'distanceModel\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'maxDistance\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'panningModel\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'refDistance\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'rolloffFactor\');\n return nativePannerNode;\n };\n};\n//# sourceMappingURL=native-panner-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-panner-node-faker-factory.js\n\n\nconst createNativePannerNodeFakerFactory = (connectNativeAudioNodeToNativeAudioNode, createInvalidStateError, createNativeChannelMergerNode, createNativeGainNode, createNativeScriptProcessorNode, createNativeWaveShaperNode, createNotSupportedError, disconnectNativeAudioNodeFromNativeAudioNode, getFirstSample, monitorConnections) => {\n return (nativeContext, { coneInnerAngle, coneOuterAngle, coneOuterGain, distanceModel, maxDistance, orientationX, orientationY, orientationZ, panningModel, positionX, positionY, positionZ, refDistance, rolloffFactor, ...audioNodeOptions }) => {\n const pannerNode = nativeContext.createPanner();\n // Bug #125: Safari does not throw an error yet.\n if (audioNodeOptions.channelCount > 2) {\n throw createNotSupportedError();\n }\n // Bug #126: Safari does not throw an error yet.\n if (audioNodeOptions.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n assignNativeAudioNodeOptions(pannerNode, audioNodeOptions);\n const SINGLE_CHANNEL_OPTIONS = {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\'\n };\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n ...SINGLE_CHANNEL_OPTIONS,\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n });\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const orientationXGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 1 });\n const orientationYGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const orientationZGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionXGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionYGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionZGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, 256, 6, 1);\n const waveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_OPTIONS,\n curve: new Float32Array([1, 1]),\n oversample: \'none\'\n });\n let lastOrientation = [orientationX, orientationY, orientationZ];\n let lastPosition = [positionX, positionY, positionZ];\n const buffer = new Float32Array(1);\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer }) => {\n const orientation = [\n getFirstSample(inputBuffer, buffer, 0),\n getFirstSample(inputBuffer, buffer, 1),\n getFirstSample(inputBuffer, buffer, 2)\n ];\n if (orientation.some((value, index) => value !== lastOrientation[index])) {\n pannerNode.setOrientation(...orientation); // tslint:disable-line:deprecation\n lastOrientation = orientation;\n }\n const positon = [\n getFirstSample(inputBuffer, buffer, 3),\n getFirstSample(inputBuffer, buffer, 4),\n getFirstSample(inputBuffer, buffer, 5)\n ];\n if (positon.some((value, index) => value !== lastPosition[index])) {\n pannerNode.setPosition(...positon); // tslint:disable-line:deprecation\n lastPosition = positon;\n }\n };\n Object.defineProperty(orientationYGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(orientationZGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionXGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionYGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionZGainNode.gain, \'defaultValue\', { get: () => 0 });\n const nativePannerNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return pannerNode.channelCount;\n },\n set channelCount(value) {\n // Bug #125: Safari does not throw an error yet.\n if (value > 2) {\n throw createNotSupportedError();\n }\n inputGainNode.channelCount = value;\n pannerNode.channelCount = value;\n },\n get channelCountMode() {\n return pannerNode.channelCountMode;\n },\n set channelCountMode(value) {\n // Bug #126: Safari does not throw an error yet.\n if (value === \'max\') {\n throw createNotSupportedError();\n }\n inputGainNode.channelCountMode = value;\n pannerNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return pannerNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n pannerNode.channelInterpretation = value;\n },\n get coneInnerAngle() {\n return pannerNode.coneInnerAngle;\n },\n set coneInnerAngle(value) {\n pannerNode.coneInnerAngle = value;\n },\n get coneOuterAngle() {\n return pannerNode.coneOuterAngle;\n },\n set coneOuterAngle(value) {\n pannerNode.coneOuterAngle = value;\n },\n get coneOuterGain() {\n return pannerNode.coneOuterGain;\n },\n set coneOuterGain(value) {\n // Bug #127: Safari does not throw an InvalidStateError yet.\n if (value < 0 || value > 1) {\n throw createInvalidStateError();\n }\n pannerNode.coneOuterGain = value;\n },\n get context() {\n return pannerNode.context;\n },\n get distanceModel() {\n return pannerNode.distanceModel;\n },\n set distanceModel(value) {\n pannerNode.distanceModel = value;\n },\n get inputs() {\n return [inputGainNode];\n },\n get maxDistance() {\n return pannerNode.maxDistance;\n },\n set maxDistance(value) {\n // Bug #128: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.maxDistance = value;\n },\n get numberOfInputs() {\n return pannerNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return pannerNode.numberOfOutputs;\n },\n get orientationX() {\n return orientationXGainNode.gain;\n },\n get orientationY() {\n return orientationYGainNode.gain;\n },\n get orientationZ() {\n return orientationZGainNode.gain;\n },\n get panningModel() {\n return pannerNode.panningModel;\n },\n set panningModel(value) {\n pannerNode.panningModel = value;\n },\n get positionX() {\n return positionXGainNode.gain;\n },\n get positionY() {\n return positionYGainNode.gain;\n },\n get positionZ() {\n return positionZGainNode.gain;\n },\n get refDistance() {\n return pannerNode.refDistance;\n },\n set refDistance(value) {\n // Bug #129: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.refDistance = value;\n },\n get rolloffFactor() {\n return pannerNode.rolloffFactor;\n },\n set rolloffFactor(value) {\n // Bug #130: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.rolloffFactor = value;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n if (coneInnerAngle !== nativePannerNodeFaker.coneInnerAngle) {\n nativePannerNodeFaker.coneInnerAngle = coneInnerAngle;\n }\n if (coneOuterAngle !== nativePannerNodeFaker.coneOuterAngle) {\n nativePannerNodeFaker.coneOuterAngle = coneOuterAngle;\n }\n if (coneOuterGain !== nativePannerNodeFaker.coneOuterGain) {\n nativePannerNodeFaker.coneOuterGain = coneOuterGain;\n }\n if (distanceModel !== nativePannerNodeFaker.distanceModel) {\n nativePannerNodeFaker.distanceModel = distanceModel;\n }\n if (maxDistance !== nativePannerNodeFaker.maxDistance) {\n nativePannerNodeFaker.maxDistance = maxDistance;\n }\n if (orientationX !== nativePannerNodeFaker.orientationX.value) {\n nativePannerNodeFaker.orientationX.value = orientationX;\n }\n if (orientationY !== nativePannerNodeFaker.orientationY.value) {\n nativePannerNodeFaker.orientationY.value = orientationY;\n }\n if (orientationZ !== nativePannerNodeFaker.orientationZ.value) {\n nativePannerNodeFaker.orientationZ.value = orientationZ;\n }\n if (panningModel !== nativePannerNodeFaker.panningModel) {\n nativePannerNodeFaker.panningModel = panningModel;\n }\n if (positionX !== nativePannerNodeFaker.positionX.value) {\n nativePannerNodeFaker.positionX.value = positionX;\n }\n if (positionY !== nativePannerNodeFaker.positionY.value) {\n nativePannerNodeFaker.positionY.value = positionY;\n }\n if (positionZ !== nativePannerNodeFaker.positionZ.value) {\n nativePannerNodeFaker.positionZ.value = positionZ;\n }\n if (refDistance !== nativePannerNodeFaker.refDistance) {\n nativePannerNodeFaker.refDistance = refDistance;\n }\n if (rolloffFactor !== nativePannerNodeFaker.rolloffFactor) {\n nativePannerNodeFaker.rolloffFactor = rolloffFactor;\n }\n if (lastOrientation[0] !== 1 || lastOrientation[1] !== 0 || lastOrientation[2] !== 0) {\n pannerNode.setOrientation(...lastOrientation); // tslint:disable-line:deprecation\n }\n if (lastPosition[0] !== 0 || lastPosition[1] !== 0 || lastPosition[2] !== 0) {\n pannerNode.setPosition(...lastPosition); // tslint:disable-line:deprecation\n }\n const whenConnected = () => {\n inputGainNode.connect(pannerNode);\n // Bug #119: Safari does not fully support the WaveShaperNode.\n connectNativeAudioNodeToNativeAudioNode(inputGainNode, waveShaperNode, 0, 0);\n waveShaperNode.connect(orientationXGainNode).connect(channelMergerNode, 0, 0);\n waveShaperNode.connect(orientationYGainNode).connect(channelMergerNode, 0, 1);\n waveShaperNode.connect(orientationZGainNode).connect(channelMergerNode, 0, 2);\n waveShaperNode.connect(positionXGainNode).connect(channelMergerNode, 0, 3);\n waveShaperNode.connect(positionYGainNode).connect(channelMergerNode, 0, 4);\n waveShaperNode.connect(positionZGainNode).connect(channelMergerNode, 0, 5);\n channelMergerNode.connect(scriptProcessorNode).connect(nativeContext.destination);\n };\n const whenDisconnected = () => {\n inputGainNode.disconnect(pannerNode);\n // Bug #119: Safari does not fully support the WaveShaperNode.\n disconnectNativeAudioNodeFromNativeAudioNode(inputGainNode, waveShaperNode, 0, 0);\n waveShaperNode.disconnect(orientationXGainNode);\n orientationXGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(orientationYGainNode);\n orientationYGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(orientationZGainNode);\n orientationZGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionXGainNode);\n positionXGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionYGainNode);\n positionYGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionZGainNode);\n positionZGainNode.disconnect(channelMergerNode);\n channelMergerNode.disconnect(scriptProcessorNode);\n scriptProcessorNode.disconnect(nativeContext.destination);\n };\n return monitorConnections(interceptConnections(nativePannerNodeFaker, pannerNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-panner-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-periodic-wave-factory.js\nconst createNativePeriodicWaveFactory = (createIndexSizeError) => {\n return (nativeContext, { disableNormalization, imag, real }) => {\n // Bug #180: Safari does not allow to use ordinary arrays.\n const convertedImag = imag instanceof Float32Array ? imag : new Float32Array(imag);\n const convertedReal = real instanceof Float32Array ? real : new Float32Array(real);\n const nativePeriodicWave = nativeContext.createPeriodicWave(convertedReal, convertedImag, { disableNormalization });\n // Bug #181: Safari does not throw an IndexSizeError so far if the given arrays have less than two values.\n if (Array.from(imag).length < 2) {\n throw createIndexSizeError();\n }\n return nativePeriodicWave;\n };\n};\n//# sourceMappingURL=native-periodic-wave-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-script-processor-node.js\nconst createNativeScriptProcessorNode = (nativeContext, bufferSize, numberOfInputChannels, numberOfOutputChannels) => {\n return nativeContext.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels); // tslint:disable-line deprecation\n};\n//# sourceMappingURL=native-script-processor-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-stereo-panner-node-factory.js\n\n\nconst createNativeStereoPannerNodeFactory = (createNativeStereoPannerNodeFaker, createNotSupportedError) => {\n return (nativeContext, options) => {\n const channelCountMode = options.channelCountMode;\n /*\n * Bug #105: The channelCountMode of \'clamped-max\' should be supported. However it is not possible to write a polyfill for Safari\n * which supports it and therefore it can\'t be supported at all.\n */\n if (channelCountMode === \'clamped-max\') {\n throw createNotSupportedError();\n }\n // Bug #105: Safari does not support the StereoPannerNode.\n if (nativeContext.createStereoPanner === undefined) {\n return createNativeStereoPannerNodeFaker(nativeContext, options);\n }\n const nativeStereoPannerNode = nativeContext.createStereoPanner();\n assignNativeAudioNodeOptions(nativeStereoPannerNode, options);\n assignNativeAudioNodeAudioParamValue(nativeStereoPannerNode, options, \'pan\');\n /*\n * Bug #105: The channelCountMode of \'clamped-max\' should be supported. However it is not possible to write a polyfill for Safari\n * which supports it and therefore it can\'t be supported at all.\n */\n Object.defineProperty(nativeStereoPannerNode, \'channelCountMode\', {\n get: () => channelCountMode,\n set: (value) => {\n if (value !== channelCountMode) {\n throw createNotSupportedError();\n }\n }\n });\n return nativeStereoPannerNode;\n };\n};\n//# sourceMappingURL=native-stereo-panner-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-stereo-panner-node-faker-factory.js\n\nconst createNativeStereoPannerNodeFakerFactory = (createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeGainNode, createNativeWaveShaperNode, createNotSupportedError, monitorConnections) => {\n // The curve has a size of 14bit plus 1 value to have an exact representation for zero. This value has been determined experimentally.\n const CURVE_SIZE = 16385;\n const DC_CURVE = new Float32Array([1, 1]);\n const HALF_PI = Math.PI / 2;\n const SINGLE_CHANNEL_OPTIONS = { channelCount: 1, channelCountMode: \'explicit\', channelInterpretation: \'discrete\' };\n const SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS = { ...SINGLE_CHANNEL_OPTIONS, oversample: \'none\' };\n const buildInternalGraphForMono = (nativeContext, inputGainNode, panGainNode, channelMergerNode) => {\n const leftWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightWaveShaperCurve = new Float32Array(CURVE_SIZE);\n for (let i = 0; i < CURVE_SIZE; i += 1) {\n const x = (i / (CURVE_SIZE - 1)) * HALF_PI;\n leftWaveShaperCurve[i] = Math.cos(x);\n rightWaveShaperCurve[i] = Math.sin(x);\n }\n const leftGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: leftWaveShaperCurve }));\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const panWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: DC_CURVE }));\n const rightGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: rightWaveShaperCurve }));\n return {\n connectGraph() {\n inputGainNode.connect(leftGainNode);\n inputGainNode.connect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n inputGainNode.connect(rightGainNode);\n panWaveShaperNode.connect(panGainNode);\n panGainNode.connect(leftWaveShaperNode.inputs === undefined ? leftWaveShaperNode : leftWaveShaperNode.inputs[0]);\n panGainNode.connect(rightWaveShaperNode.inputs === undefined ? rightWaveShaperNode : rightWaveShaperNode.inputs[0]);\n leftWaveShaperNode.connect(leftGainNode.gain);\n rightWaveShaperNode.connect(rightGainNode.gain);\n leftGainNode.connect(channelMergerNode, 0, 0);\n rightGainNode.connect(channelMergerNode, 0, 1);\n },\n disconnectGraph() {\n inputGainNode.disconnect(leftGainNode);\n inputGainNode.disconnect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n inputGainNode.disconnect(rightGainNode);\n panWaveShaperNode.disconnect(panGainNode);\n panGainNode.disconnect(leftWaveShaperNode.inputs === undefined ? leftWaveShaperNode : leftWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightWaveShaperNode.inputs === undefined ? rightWaveShaperNode : rightWaveShaperNode.inputs[0]);\n leftWaveShaperNode.disconnect(leftGainNode.gain);\n rightWaveShaperNode.disconnect(rightGainNode.gain);\n leftGainNode.disconnect(channelMergerNode, 0, 0);\n rightGainNode.disconnect(channelMergerNode, 0, 1);\n }\n };\n };\n const buildInternalGraphForStereo = (nativeContext, inputGainNode, panGainNode, channelMergerNode) => {\n const leftInputForLeftOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const leftInputForRightOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightInputForLeftOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightInputForRightOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const centerIndex = Math.floor(CURVE_SIZE / 2);\n for (let i = 0; i < CURVE_SIZE; i += 1) {\n if (i > centerIndex) {\n const x = ((i - centerIndex) / (CURVE_SIZE - 1 - centerIndex)) * HALF_PI;\n leftInputForLeftOutputWaveShaperCurve[i] = Math.cos(x);\n leftInputForRightOutputWaveShaperCurve[i] = Math.sin(x);\n rightInputForLeftOutputWaveShaperCurve[i] = 0;\n rightInputForRightOutputWaveShaperCurve[i] = 1;\n }\n else {\n const x = (i / (CURVE_SIZE - 1 - centerIndex)) * HALF_PI;\n leftInputForLeftOutputWaveShaperCurve[i] = 1;\n leftInputForRightOutputWaveShaperCurve[i] = 0;\n rightInputForLeftOutputWaveShaperCurve[i] = Math.cos(x);\n rightInputForRightOutputWaveShaperCurve[i] = Math.sin(x);\n }\n }\n const channelSplitterNode = createNativeChannelSplitterNode(nativeContext, {\n channelCount: 2,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: 2\n });\n const leftInputForLeftOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftInputForLeftOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: leftInputForLeftOutputWaveShaperCurve\n });\n const leftInputForRightOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftInputForRightOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: leftInputForRightOutputWaveShaperCurve\n });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const panWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: DC_CURVE }));\n const rightInputForLeftOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightInputForLeftOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: rightInputForLeftOutputWaveShaperCurve\n });\n const rightInputForRightOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightInputForRightOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: rightInputForRightOutputWaveShaperCurve\n });\n return {\n connectGraph() {\n inputGainNode.connect(channelSplitterNode);\n inputGainNode.connect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n channelSplitterNode.connect(leftInputForLeftOutputGainNode, 0);\n channelSplitterNode.connect(leftInputForRightOutputGainNode, 0);\n channelSplitterNode.connect(rightInputForLeftOutputGainNode, 1);\n channelSplitterNode.connect(rightInputForRightOutputGainNode, 1);\n panWaveShaperNode.connect(panGainNode);\n panGainNode.connect(leftInputForLeftOutputWaveShaperNode.inputs === undefined\n ? leftInputForLeftOutputWaveShaperNode\n : leftInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(leftInputForRightOutputWaveShaperNode.inputs === undefined\n ? leftInputForRightOutputWaveShaperNode\n : leftInputForRightOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(rightInputForLeftOutputWaveShaperNode.inputs === undefined\n ? rightInputForLeftOutputWaveShaperNode\n : rightInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(rightInputForRightOutputWaveShaperNode.inputs === undefined\n ? rightInputForRightOutputWaveShaperNode\n : rightInputForRightOutputWaveShaperNode.inputs[0]);\n leftInputForLeftOutputWaveShaperNode.connect(leftInputForLeftOutputGainNode.gain);\n leftInputForRightOutputWaveShaperNode.connect(leftInputForRightOutputGainNode.gain);\n rightInputForLeftOutputWaveShaperNode.connect(rightInputForLeftOutputGainNode.gain);\n rightInputForRightOutputWaveShaperNode.connect(rightInputForRightOutputGainNode.gain);\n leftInputForLeftOutputGainNode.connect(channelMergerNode, 0, 0);\n rightInputForLeftOutputGainNode.connect(channelMergerNode, 0, 0);\n leftInputForRightOutputGainNode.connect(channelMergerNode, 0, 1);\n rightInputForRightOutputGainNode.connect(channelMergerNode, 0, 1);\n },\n disconnectGraph() {\n inputGainNode.disconnect(channelSplitterNode);\n inputGainNode.disconnect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n channelSplitterNode.disconnect(leftInputForLeftOutputGainNode, 0);\n channelSplitterNode.disconnect(leftInputForRightOutputGainNode, 0);\n channelSplitterNode.disconnect(rightInputForLeftOutputGainNode, 1);\n channelSplitterNode.disconnect(rightInputForRightOutputGainNode, 1);\n panWaveShaperNode.disconnect(panGainNode);\n panGainNode.disconnect(leftInputForLeftOutputWaveShaperNode.inputs === undefined\n ? leftInputForLeftOutputWaveShaperNode\n : leftInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(leftInputForRightOutputWaveShaperNode.inputs === undefined\n ? leftInputForRightOutputWaveShaperNode\n : leftInputForRightOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightInputForLeftOutputWaveShaperNode.inputs === undefined\n ? rightInputForLeftOutputWaveShaperNode\n : rightInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightInputForRightOutputWaveShaperNode.inputs === undefined\n ? rightInputForRightOutputWaveShaperNode\n : rightInputForRightOutputWaveShaperNode.inputs[0]);\n leftInputForLeftOutputWaveShaperNode.disconnect(leftInputForLeftOutputGainNode.gain);\n leftInputForRightOutputWaveShaperNode.disconnect(leftInputForRightOutputGainNode.gain);\n rightInputForLeftOutputWaveShaperNode.disconnect(rightInputForLeftOutputGainNode.gain);\n rightInputForRightOutputWaveShaperNode.disconnect(rightInputForRightOutputGainNode.gain);\n leftInputForLeftOutputGainNode.disconnect(channelMergerNode, 0, 0);\n rightInputForLeftOutputGainNode.disconnect(channelMergerNode, 0, 0);\n leftInputForRightOutputGainNode.disconnect(channelMergerNode, 0, 1);\n rightInputForRightOutputGainNode.disconnect(channelMergerNode, 0, 1);\n }\n };\n };\n const buildInternalGraph = (nativeContext, channelCount, inputGainNode, panGainNode, channelMergerNode) => {\n if (channelCount === 1) {\n return buildInternalGraphForMono(nativeContext, inputGainNode, panGainNode, channelMergerNode);\n }\n if (channelCount === 2) {\n return buildInternalGraphForStereo(nativeContext, inputGainNode, panGainNode, channelMergerNode);\n }\n throw createNotSupportedError();\n };\n return (nativeContext, { channelCount, channelCountMode, pan, ...audioNodeOptions }) => {\n if (channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n ...audioNodeOptions,\n channelCount: 1,\n channelCountMode,\n numberOfInputs: 2\n });\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, channelCount, channelCountMode, gain: 1 });\n const panGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: pan\n });\n let { connectGraph, disconnectGraph } = buildInternalGraph(nativeContext, channelCount, inputGainNode, panGainNode, channelMergerNode);\n Object.defineProperty(panGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(panGainNode.gain, \'maxValue\', { get: () => 1 });\n Object.defineProperty(panGainNode.gain, \'minValue\', { get: () => -1 });\n const nativeStereoPannerNodeFakerFactory = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return inputGainNode.channelCount;\n },\n set channelCount(value) {\n if (inputGainNode.channelCount !== value) {\n if (isConnected) {\n disconnectGraph();\n }\n ({ connectGraph, disconnectGraph } = buildInternalGraph(nativeContext, value, inputGainNode, panGainNode, channelMergerNode));\n if (isConnected) {\n connectGraph();\n }\n }\n inputGainNode.channelCount = value;\n },\n get channelCountMode() {\n return inputGainNode.channelCountMode;\n },\n set channelCountMode(value) {\n if (value === \'clamped-max\' || value === \'max\') {\n throw createNotSupportedError();\n }\n inputGainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return inputGainNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n },\n get context() {\n return inputGainNode.context;\n },\n get inputs() {\n return [inputGainNode];\n },\n get numberOfInputs() {\n return inputGainNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return inputGainNode.numberOfOutputs;\n },\n get pan() {\n return panGainNode.gain;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n let isConnected = false;\n const whenConnected = () => {\n connectGraph();\n isConnected = true;\n };\n const whenDisconnected = () => {\n disconnectGraph();\n isConnected = false;\n };\n return monitorConnections(interceptConnections(nativeStereoPannerNodeFakerFactory, channelMergerNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-stereo-panner-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-wave-shaper-node-factory.js\n\n\nconst createNativeWaveShaperNodeFactory = (createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeWaveShaperNodeFaker, isDCCurve, monitorConnections, nativeAudioContextConstructor, overwriteAccessors) => {\n return (nativeContext, options) => {\n const nativeWaveShaperNode = nativeContext.createWaveShaper();\n /*\n * Bug #119: Safari does not correctly map the values.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the existence of\n * the webkitAudioContext is used as a workaround here. Testing for the automationRate property is necessary because this workaround\n * isn\'t necessary anymore since v14.0.2 of Safari.\n */\n if (nativeAudioContextConstructor !== null &&\n nativeAudioContextConstructor.name === \'webkitAudioContext\' &&\n nativeContext.createGain().gain.automationRate === undefined) {\n return createNativeWaveShaperNodeFaker(nativeContext, options);\n }\n assignNativeAudioNodeOptions(nativeWaveShaperNode, options);\n const curve = options.curve === null || options.curve instanceof Float32Array ? options.curve : new Float32Array(options.curve);\n // Bug #104: Chrome and Edge will throw an InvalidAccessError when the curve has less than two samples.\n if (curve !== null && curve.length < 2) {\n throw createInvalidStateError();\n }\n // Only values of type Float32Array can be assigned to the curve property.\n assignNativeAudioNodeOption(nativeWaveShaperNode, { curve }, \'curve\');\n assignNativeAudioNodeOption(nativeWaveShaperNode, options, \'oversample\');\n let disconnectNativeAudioBufferSourceNode = null;\n let isConnected = false;\n overwriteAccessors(nativeWaveShaperNode, \'curve\', (get) => () => get.call(nativeWaveShaperNode), (set) => (value) => {\n set.call(nativeWaveShaperNode, value);\n if (isConnected) {\n if (isDCCurve(value) && disconnectNativeAudioBufferSourceNode === null) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, nativeWaveShaperNode);\n }\n else if (!isDCCurve(value) && disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n }\n return value;\n });\n const whenConnected = () => {\n isConnected = true;\n if (isDCCurve(nativeWaveShaperNode.curve)) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, nativeWaveShaperNode);\n }\n };\n const whenDisconnected = () => {\n isConnected = false;\n if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n };\n return monitorConnections(nativeWaveShaperNode, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-wave-shaper-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-wave-shaper-node-faker-factory.js\n\n\nconst createNativeWaveShaperNodeFakerFactory = (createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeGainNode, isDCCurve, monitorConnections) => {\n return (nativeContext, { curve, oversample, ...audioNodeOptions }) => {\n const negativeWaveShaperNode = nativeContext.createWaveShaper();\n const positiveWaveShaperNode = nativeContext.createWaveShaper();\n assignNativeAudioNodeOptions(negativeWaveShaperNode, audioNodeOptions);\n assignNativeAudioNodeOptions(positiveWaveShaperNode, audioNodeOptions);\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const invertGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: -1 });\n const outputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const revertGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: -1 });\n let disconnectNativeAudioBufferSourceNode = null;\n let isConnected = false;\n let unmodifiedCurve = null;\n const nativeWaveShaperNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return negativeWaveShaperNode.channelCount;\n },\n set channelCount(value) {\n inputGainNode.channelCount = value;\n invertGainNode.channelCount = value;\n negativeWaveShaperNode.channelCount = value;\n outputGainNode.channelCount = value;\n positiveWaveShaperNode.channelCount = value;\n revertGainNode.channelCount = value;\n },\n get channelCountMode() {\n return negativeWaveShaperNode.channelCountMode;\n },\n set channelCountMode(value) {\n inputGainNode.channelCountMode = value;\n invertGainNode.channelCountMode = value;\n negativeWaveShaperNode.channelCountMode = value;\n outputGainNode.channelCountMode = value;\n positiveWaveShaperNode.channelCountMode = value;\n revertGainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return negativeWaveShaperNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n invertGainNode.channelInterpretation = value;\n negativeWaveShaperNode.channelInterpretation = value;\n outputGainNode.channelInterpretation = value;\n positiveWaveShaperNode.channelInterpretation = value;\n revertGainNode.channelInterpretation = value;\n },\n get context() {\n return negativeWaveShaperNode.context;\n },\n get curve() {\n return unmodifiedCurve;\n },\n set curve(value) {\n // Bug #102: Safari does not throw an InvalidStateError when the curve has less than two samples.\n if (value !== null && value.length < 2) {\n throw createInvalidStateError();\n }\n if (value === null) {\n negativeWaveShaperNode.curve = value;\n positiveWaveShaperNode.curve = value;\n }\n else {\n const curveLength = value.length;\n const negativeCurve = new Float32Array(curveLength + 2 - (curveLength % 2));\n const positiveCurve = new Float32Array(curveLength + 2 - (curveLength % 2));\n negativeCurve[0] = value[0];\n positiveCurve[0] = -value[curveLength - 1];\n const length = Math.ceil((curveLength + 1) / 2);\n const centerIndex = (curveLength + 1) / 2 - 1;\n for (let i = 1; i < length; i += 1) {\n const theoreticIndex = (i / length) * centerIndex;\n const lowerIndex = Math.floor(theoreticIndex);\n const upperIndex = Math.ceil(theoreticIndex);\n negativeCurve[i] =\n lowerIndex === upperIndex\n ? value[lowerIndex]\n : (1 - (theoreticIndex - lowerIndex)) * value[lowerIndex] +\n (1 - (upperIndex - theoreticIndex)) * value[upperIndex];\n positiveCurve[i] =\n lowerIndex === upperIndex\n ? -value[curveLength - 1 - lowerIndex]\n : -((1 - (theoreticIndex - lowerIndex)) * value[curveLength - 1 - lowerIndex]) -\n (1 - (upperIndex - theoreticIndex)) * value[curveLength - 1 - upperIndex];\n }\n negativeCurve[length] = curveLength % 2 === 1 ? value[length - 1] : (value[length - 2] + value[length - 1]) / 2;\n negativeWaveShaperNode.curve = negativeCurve;\n positiveWaveShaperNode.curve = positiveCurve;\n }\n unmodifiedCurve = value;\n if (isConnected) {\n if (isDCCurve(unmodifiedCurve) && disconnectNativeAudioBufferSourceNode === null) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, inputGainNode);\n }\n else if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n }\n },\n get inputs() {\n return [inputGainNode];\n },\n get numberOfInputs() {\n return negativeWaveShaperNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return negativeWaveShaperNode.numberOfOutputs;\n },\n get oversample() {\n return negativeWaveShaperNode.oversample;\n },\n set oversample(value) {\n negativeWaveShaperNode.oversample = value;\n positiveWaveShaperNode.oversample = value;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n if (curve !== null) {\n // Only values of type Float32Array can be assigned to the curve property.\n nativeWaveShaperNodeFaker.curve = curve instanceof Float32Array ? curve : new Float32Array(curve);\n }\n if (oversample !== nativeWaveShaperNodeFaker.oversample) {\n nativeWaveShaperNodeFaker.oversample = oversample;\n }\n const whenConnected = () => {\n inputGainNode.connect(negativeWaveShaperNode).connect(outputGainNode);\n inputGainNode.connect(invertGainNode).connect(positiveWaveShaperNode).connect(revertGainNode).connect(outputGainNode);\n isConnected = true;\n if (isDCCurve(unmodifiedCurve)) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, inputGainNode);\n }\n };\n const whenDisconnected = () => {\n inputGainNode.disconnect(negativeWaveShaperNode);\n negativeWaveShaperNode.disconnect(outputGainNode);\n inputGainNode.disconnect(invertGainNode);\n invertGainNode.disconnect(positiveWaveShaperNode);\n positiveWaveShaperNode.disconnect(revertGainNode);\n revertGainNode.disconnect(outputGainNode);\n isConnected = false;\n if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n };\n return monitorConnections(interceptConnections(nativeWaveShaperNodeFaker, outputGainNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-wave-shaper-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/not-supported-error.js\nconst createNotSupportedError = () => new DOMException(\'\', \'NotSupportedError\');\n//# sourceMappingURL=not-supported-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/offline-audio-context-constructor.js\n\n\nconst offline_audio_context_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createOfflineAudioContextConstructor = (baseAudioContextConstructor, cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, startRendering) => {\n return class OfflineAudioContext extends baseAudioContextConstructor {\n constructor(a, b, c) {\n let options;\n if (typeof a === \'number\' && b !== undefined && c !== undefined) {\n options = { length: b, numberOfChannels: a, sampleRate: c };\n }\n else if (typeof a === \'object\') {\n options = a;\n }\n else {\n throw new Error(\'The given parameters are not valid.\');\n }\n const { length, numberOfChannels, sampleRate } = { ...offline_audio_context_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOfflineAudioContext = createNativeOfflineAudioContext(numberOfChannels, length, sampleRate);\n // #21 Safari does not support promises and therefore would fire the statechange event before the promise can be resolved.\n if (!cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n nativeOfflineAudioContext.addEventListener(\'statechange\', (() => {\n let i = 0;\n const delayStateChangeEvent = (event) => {\n if (this._state === \'running\') {\n if (i > 0) {\n nativeOfflineAudioContext.removeEventListener(\'statechange\', delayStateChangeEvent);\n event.stopImmediatePropagation();\n this._waitForThePromiseToSettle(event);\n }\n else {\n i += 1;\n }\n }\n };\n return delayStateChangeEvent;\n })());\n }\n super(nativeOfflineAudioContext, numberOfChannels);\n this._length = length;\n this._nativeOfflineAudioContext = nativeOfflineAudioContext;\n this._state = null;\n }\n get length() {\n // Bug #17: Safari does not yet expose the length.\n if (this._nativeOfflineAudioContext.length === undefined) {\n return this._length;\n }\n return this._nativeOfflineAudioContext.length;\n }\n get state() {\n return this._state === null ? this._nativeOfflineAudioContext.state : this._state;\n }\n startRendering() {\n /*\n * Bug #9 & #59: It is theoretically possible that startRendering() will first render a partialOfflineAudioContext. Therefore\n * the state of the nativeOfflineAudioContext might no transition to running immediately.\n */\n if (this._state === \'running\') {\n return Promise.reject(createInvalidStateError());\n }\n this._state = \'running\';\n return startRendering(this.destination, this._nativeOfflineAudioContext).finally(() => {\n this._state = null;\n deactivateAudioGraph(this);\n });\n }\n _waitForThePromiseToSettle(event) {\n if (this._state === null) {\n this._nativeOfflineAudioContext.dispatchEvent(event);\n }\n else {\n setTimeout(() => this._waitForThePromiseToSettle(event));\n }\n }\n };\n};\n//# sourceMappingURL=offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/oscillator-node-constructor.js\n\n\n\nconst oscillator_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n detune: 0,\n frequency: 440,\n periodicWave: undefined,\n type: \'sine\'\n};\nconst createOscillatorNodeConstructor = (audioNodeConstructor, createAudioParam, createNativeOscillatorNode, createOscillatorNodeRenderer, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class OscillatorNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...oscillator_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOscillatorNode = createNativeOscillatorNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const oscillatorNodeRenderer = (isOffline ? createOscillatorNodeRenderer() : null);\n const nyquist = context.sampleRate / 2;\n super(context, false, nativeOscillatorNode, oscillatorNodeRenderer);\n // Bug #81: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._detune = createAudioParam(this, isOffline, nativeOscillatorNode.detune, 153600, -153600);\n // Bug #76: Safari does not export the correct values for maxValue and minValue.\n this._frequency = createAudioParam(this, isOffline, nativeOscillatorNode.frequency, nyquist, -nyquist);\n this._nativeOscillatorNode = nativeOscillatorNode;\n this._onended = null;\n this._oscillatorNodeRenderer = oscillatorNodeRenderer;\n if (this._oscillatorNodeRenderer !== null && mergedOptions.periodicWave !== undefined) {\n this._oscillatorNodeRenderer.periodicWave =\n mergedOptions.periodicWave;\n }\n }\n get detune() {\n return this._detune;\n }\n get frequency() {\n return this._frequency;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeOscillatorNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeOscillatorNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n get type() {\n return this._nativeOscillatorNode.type;\n }\n set type(value) {\n this._nativeOscillatorNode.type = value;\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.periodicWave = null;\n }\n }\n setPeriodicWave(periodicWave) {\n this._nativeOscillatorNode.setPeriodicWave(periodicWave);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.periodicWave = periodicWave;\n }\n }\n start(when = 0) {\n this._nativeOscillatorNode.start(when);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.start = when;\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeOscillatorNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeOscillatorNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeOscillatorNode.stop(when);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=oscillator-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/oscillator-node-renderer-factory.js\n\nconst createOscillatorNodeRendererFactory = (connectAudioParam, createNativeOscillatorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeOscillatorNodes = new WeakMap();\n let periodicWave = null;\n let start = null;\n let stop = null;\n const createOscillatorNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeOscillatorNode = getNativeAudioNode(proxy);\n // If the initially used nativeOscillatorNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeOscillatorNodeIsOwnedByContext = isOwnedByContext(nativeOscillatorNode, nativeOfflineAudioContext);\n if (!nativeOscillatorNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeOscillatorNode.channelCount,\n channelCountMode: nativeOscillatorNode.channelCountMode,\n channelInterpretation: nativeOscillatorNode.channelInterpretation,\n detune: nativeOscillatorNode.detune.value,\n frequency: nativeOscillatorNode.frequency.value,\n periodicWave: periodicWave === null ? undefined : periodicWave,\n type: nativeOscillatorNode.type\n };\n nativeOscillatorNode = createNativeOscillatorNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeOscillatorNode.start(start);\n }\n if (stop !== null) {\n nativeOscillatorNode.stop(stop);\n }\n }\n renderedNativeOscillatorNodes.set(nativeOfflineAudioContext, nativeOscillatorNode);\n if (!nativeOscillatorNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.detune, nativeOscillatorNode.detune);\n await renderAutomation(nativeOfflineAudioContext, proxy.frequency, nativeOscillatorNode.frequency);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.detune, nativeOscillatorNode.detune);\n await connectAudioParam(nativeOfflineAudioContext, proxy.frequency, nativeOscillatorNode.frequency);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeOscillatorNode);\n return nativeOscillatorNode;\n };\n return {\n set periodicWave(value) {\n periodicWave = value;\n },\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeOscillatorNode = renderedNativeOscillatorNodes.get(nativeOfflineAudioContext);\n if (renderedNativeOscillatorNode !== undefined) {\n return Promise.resolve(renderedNativeOscillatorNode);\n }\n return createOscillatorNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=oscillator-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/panner-node-constructor.js\n\nconst panner_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: \'inverse\',\n maxDistance: 10000,\n orientationX: 1,\n orientationY: 0,\n orientationZ: 0,\n panningModel: \'equalpower\',\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n refDistance: 1,\n rolloffFactor: 1\n};\nconst createPannerNodeConstructor = (audioNodeConstructor, createAudioParam, createNativePannerNode, createPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class PannerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...panner_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativePannerNode = createNativePannerNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const pannerNodeRenderer = (isOffline ? createPannerNodeRenderer() : null);\n super(context, false, nativePannerNode, pannerNodeRenderer);\n this._nativePannerNode = nativePannerNode;\n // Bug #74: Safari does not export the correct values for maxValue and minValue.\n this._orientationX = createAudioParam(this, isOffline, nativePannerNode.orientationX, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._orientationY = createAudioParam(this, isOffline, nativePannerNode.orientationY, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._orientationZ = createAudioParam(this, isOffline, nativePannerNode.orientationZ, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionX = createAudioParam(this, isOffline, nativePannerNode.positionX, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionY = createAudioParam(this, isOffline, nativePannerNode.positionY, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionZ = createAudioParam(this, isOffline, nativePannerNode.positionZ, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get coneInnerAngle() {\n return this._nativePannerNode.coneInnerAngle;\n }\n set coneInnerAngle(value) {\n this._nativePannerNode.coneInnerAngle = value;\n }\n get coneOuterAngle() {\n return this._nativePannerNode.coneOuterAngle;\n }\n set coneOuterAngle(value) {\n this._nativePannerNode.coneOuterAngle = value;\n }\n get coneOuterGain() {\n return this._nativePannerNode.coneOuterGain;\n }\n set coneOuterGain(value) {\n this._nativePannerNode.coneOuterGain = value;\n }\n get distanceModel() {\n return this._nativePannerNode.distanceModel;\n }\n set distanceModel(value) {\n this._nativePannerNode.distanceModel = value;\n }\n get maxDistance() {\n return this._nativePannerNode.maxDistance;\n }\n set maxDistance(value) {\n this._nativePannerNode.maxDistance = value;\n }\n get orientationX() {\n return this._orientationX;\n }\n get orientationY() {\n return this._orientationY;\n }\n get orientationZ() {\n return this._orientationZ;\n }\n get panningModel() {\n return this._nativePannerNode.panningModel;\n }\n set panningModel(value) {\n this._nativePannerNode.panningModel = value;\n }\n get positionX() {\n return this._positionX;\n }\n get positionY() {\n return this._positionY;\n }\n get positionZ() {\n return this._positionZ;\n }\n get refDistance() {\n return this._nativePannerNode.refDistance;\n }\n set refDistance(value) {\n this._nativePannerNode.refDistance = value;\n }\n get rolloffFactor() {\n return this._nativePannerNode.rolloffFactor;\n }\n set rolloffFactor(value) {\n this._nativePannerNode.rolloffFactor = value;\n }\n };\n};\n//# sourceMappingURL=panner-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/panner-node-renderer-factory.js\n\n\nconst createPannerNodeRendererFactory = (connectAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeGainNode, createNativePannerNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n let renderedBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeGainNode = null;\n let nativePannerNode = getNativeAudioNode(proxy);\n const commonAudioNodeOptions = {\n channelCount: nativePannerNode.channelCount,\n channelCountMode: nativePannerNode.channelCountMode,\n channelInterpretation: nativePannerNode.channelInterpretation\n };\n const commonNativePannerNodeOptions = {\n ...commonAudioNodeOptions,\n coneInnerAngle: nativePannerNode.coneInnerAngle,\n coneOuterAngle: nativePannerNode.coneOuterAngle,\n coneOuterGain: nativePannerNode.coneOuterGain,\n distanceModel: nativePannerNode.distanceModel,\n maxDistance: nativePannerNode.maxDistance,\n panningModel: nativePannerNode.panningModel,\n refDistance: nativePannerNode.refDistance,\n rolloffFactor: nativePannerNode.rolloffFactor\n };\n // If the initially used nativePannerNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativePannerNodeIsOwnedByContext = isOwnedByContext(nativePannerNode, nativeOfflineAudioContext);\n // Bug #124: Safari does not support modifying the orientation and the position with AudioParams.\n if (\'bufferSize\' in nativePannerNode) {\n nativeGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n }\n else if (!nativePannerNodeIsOwnedByContext) {\n const options = {\n ...commonNativePannerNodeOptions,\n orientationX: nativePannerNode.orientationX.value,\n orientationY: nativePannerNode.orientationY.value,\n orientationZ: nativePannerNode.orientationZ.value,\n positionX: nativePannerNode.positionX.value,\n positionY: nativePannerNode.positionY.value,\n positionZ: nativePannerNode.positionZ.value\n };\n nativePannerNode = createNativePannerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeGainNode === null ? nativePannerNode : nativeGainNode);\n if (nativeGainNode !== null) {\n if (renderedBufferPromise === null) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(6, \n // Bug #17: Safari does not yet expose the length.\n proxy.context.length, nativeOfflineAudioContext.sampleRate);\n const nativeChannelMergerNode = createNativeChannelMergerNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n });\n nativeChannelMergerNode.connect(partialOfflineAudioContext.destination);\n renderedBufferPromise = (async () => {\n const nativeConstantSourceNodes = await Promise.all([\n proxy.orientationX,\n proxy.orientationY,\n proxy.orientationZ,\n proxy.positionX,\n proxy.positionY,\n proxy.positionZ\n ].map(async (audioParam, index) => {\n const nativeConstantSourceNode = createNativeConstantSourceNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: index === 0 ? 1 : 0\n });\n await renderAutomation(partialOfflineAudioContext, audioParam, nativeConstantSourceNode.offset);\n return nativeConstantSourceNode;\n }));\n for (let i = 0; i < 6; i += 1) {\n nativeConstantSourceNodes[i].connect(nativeChannelMergerNode, 0, i);\n nativeConstantSourceNodes[i].start(0);\n }\n return renderNativeOfflineAudioContext(partialOfflineAudioContext);\n })();\n }\n const renderedBuffer = await renderedBufferPromise;\n const inputGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, inputGainNode);\n const channelDatas = [];\n for (let i = 0; i < renderedBuffer.numberOfChannels; i += 1) {\n channelDatas.push(renderedBuffer.getChannelData(i));\n }\n let lastOrientation = [channelDatas[0][0], channelDatas[1][0], channelDatas[2][0]];\n let lastPosition = [channelDatas[3][0], channelDatas[4][0], channelDatas[5][0]];\n let gateGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n let partialPannerNode = createNativePannerNode(nativeOfflineAudioContext, {\n ...commonNativePannerNodeOptions,\n orientationX: lastOrientation[0],\n orientationY: lastOrientation[1],\n orientationZ: lastOrientation[2],\n positionX: lastPosition[0],\n positionY: lastPosition[1],\n positionZ: lastPosition[2]\n });\n inputGainNode.connect(gateGainNode).connect(partialPannerNode.inputs[0]);\n partialPannerNode.connect(nativeGainNode);\n for (let i = 128; i < renderedBuffer.length; i += 128) {\n const orientation = [channelDatas[0][i], channelDatas[1][i], channelDatas[2][i]];\n const positon = [channelDatas[3][i], channelDatas[4][i], channelDatas[5][i]];\n if (orientation.some((value, index) => value !== lastOrientation[index]) ||\n positon.some((value, index) => value !== lastPosition[index])) {\n lastOrientation = orientation;\n lastPosition = positon;\n const currentTime = i / nativeOfflineAudioContext.sampleRate;\n gateGainNode.gain.setValueAtTime(0, currentTime);\n gateGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 0 });\n partialPannerNode = createNativePannerNode(nativeOfflineAudioContext, {\n ...commonNativePannerNodeOptions,\n orientationX: lastOrientation[0],\n orientationY: lastOrientation[1],\n orientationZ: lastOrientation[2],\n positionX: lastPosition[0],\n positionY: lastPosition[1],\n positionZ: lastPosition[2]\n });\n gateGainNode.gain.setValueAtTime(1, currentTime);\n inputGainNode.connect(gateGainNode).connect(partialPannerNode.inputs[0]);\n partialPannerNode.connect(nativeGainNode);\n }\n }\n return nativeGainNode;\n }\n if (!nativePannerNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationX, nativePannerNode.orientationX);\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationY, nativePannerNode.orientationY);\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationZ, nativePannerNode.orientationZ);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionX, nativePannerNode.positionX);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionY, nativePannerNode.positionY);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionZ, nativePannerNode.positionZ);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationX, nativePannerNode.orientationX);\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationY, nativePannerNode.orientationY);\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationZ, nativePannerNode.orientationZ);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionX, nativePannerNode.positionX);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionY, nativePannerNode.positionY);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionZ, nativePannerNode.positionZ);\n }\n if (isNativeAudioNodeFaker(nativePannerNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativePannerNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativePannerNode);\n }\n return nativePannerNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeGainNodeOrNativePannerNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeGainNodeOrNativePannerNode !== undefined) {\n return Promise.resolve(renderedNativeGainNodeOrNativePannerNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=panner-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/periodic-wave-constructor.js\nconst periodic_wave_constructor_DEFAULT_OPTIONS = {\n disableNormalization: false\n};\nconst createPeriodicWaveConstructor = (createNativePeriodicWave, getNativeContext, periodicWaveStore, sanitizePeriodicWaveOptions) => {\n return class PeriodicWave {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = sanitizePeriodicWaveOptions({ ...periodic_wave_constructor_DEFAULT_OPTIONS, ...options });\n const periodicWave = createNativePeriodicWave(nativeContext, mergedOptions);\n periodicWaveStore.add(periodicWave);\n // This does violate all good pratices but it is used here to simplify the handling of periodic waves.\n return periodicWave;\n }\n static [Symbol.hasInstance](instance) {\n return ((instance !== null && typeof instance === \'object\' && Object.getPrototypeOf(instance) === PeriodicWave.prototype) ||\n periodicWaveStore.has(instance));\n }\n };\n};\n//# sourceMappingURL=periodic-wave-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-automation.js\nconst createRenderAutomation = (getAudioParamRenderer, renderInputsOfAudioParam) => {\n return (nativeOfflineAudioContext, audioParam, nativeAudioParam) => {\n const audioParamRenderer = getAudioParamRenderer(audioParam);\n audioParamRenderer.replay(nativeAudioParam);\n return renderInputsOfAudioParam(audioParam, nativeOfflineAudioContext, nativeAudioParam);\n };\n};\n//# sourceMappingURL=render-automation.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-inputs-of-audio-node.js\nconst createRenderInputsOfAudioNode = (getAudioNodeConnections, getAudioNodeRenderer, isPartOfACycle) => {\n return async (audioNode, nativeOfflineAudioContext, nativeAudioNode) => {\n const audioNodeConnections = getAudioNodeConnections(audioNode);\n await Promise.all(audioNodeConnections.activeInputs\n .map((connections, input) => Array.from(connections).map(async ([source, output]) => {\n const audioNodeRenderer = getAudioNodeRenderer(source);\n const renderedNativeAudioNode = await audioNodeRenderer.render(source, nativeOfflineAudioContext);\n const destination = audioNode.context.destination;\n if (!isPartOfACycle(source) && (audioNode !== destination || !isPartOfACycle(audioNode))) {\n renderedNativeAudioNode.connect(nativeAudioNode, output, input);\n }\n }))\n .reduce((allRenderingPromises, renderingPromises) => [...allRenderingPromises, ...renderingPromises], []));\n };\n};\n//# sourceMappingURL=render-inputs-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-inputs-of-audio-param.js\nconst createRenderInputsOfAudioParam = (getAudioNodeRenderer, getAudioParamConnections, isPartOfACycle) => {\n return async (audioParam, nativeOfflineAudioContext, nativeAudioParam) => {\n const audioParamConnections = getAudioParamConnections(audioParam);\n await Promise.all(Array.from(audioParamConnections.activeInputs).map(async ([source, output]) => {\n const audioNodeRenderer = getAudioNodeRenderer(source);\n const renderedNativeAudioNode = await audioNodeRenderer.render(source, nativeOfflineAudioContext);\n if (!isPartOfACycle(source)) {\n renderedNativeAudioNode.connect(nativeAudioParam, output);\n }\n }));\n };\n};\n//# sourceMappingURL=render-inputs-of-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-native-offline-audio-context.js\n\nconst createRenderNativeOfflineAudioContext = (cacheTestResult, createNativeGainNode, createNativeScriptProcessorNode, testOfflineAudioContextCurrentTimeSupport) => {\n return (nativeOfflineAudioContext) => {\n // Bug #21: Safari does not support promises yet.\n if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n // Bug #158: Chrome and Edge do not advance currentTime if it is not accessed while rendering the audio.\n return Promise.resolve(cacheTestResult(testOfflineAudioContextCurrentTimeSupport, testOfflineAudioContextCurrentTimeSupport)).then((isOfflineAudioContextCurrentTimeSupported) => {\n if (!isOfflineAudioContextCurrentTimeSupported) {\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeOfflineAudioContext, 512, 0, 1);\n nativeOfflineAudioContext.oncomplete = () => {\n scriptProcessorNode.onaudioprocess = null; // tslint:disable-line:deprecation\n scriptProcessorNode.disconnect();\n };\n scriptProcessorNode.onaudioprocess = () => nativeOfflineAudioContext.currentTime; // tslint:disable-line:deprecation\n scriptProcessorNode.connect(nativeOfflineAudioContext.destination);\n }\n return nativeOfflineAudioContext.startRendering();\n });\n }\n return new Promise((resolve) => {\n // Bug #48: Safari does not render an OfflineAudioContext without any connected node.\n const gainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeOfflineAudioContext.oncomplete = (event) => {\n gainNode.disconnect();\n resolve(event.renderedBuffer);\n };\n gainNode.connect(nativeOfflineAudioContext.destination);\n nativeOfflineAudioContext.startRendering();\n });\n };\n};\n//# sourceMappingURL=render-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/set-active-audio-worklet-node-inputs.js\nconst createSetActiveAudioWorkletNodeInputs = (activeAudioWorkletNodeInputsStore) => {\n return (nativeAudioWorkletNode, activeInputs) => {\n activeAudioWorkletNodeInputsStore.set(nativeAudioWorkletNode, activeInputs);\n };\n};\n//# sourceMappingURL=set-active-audio-worklet-node-inputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/set-audio-node-tail-time.js\nconst createSetAudioNodeTailTime = (audioNodeTailTimeStore) => {\n return (audioNode, tailTime) => audioNodeTailTimeStore.set(audioNode, tailTime);\n};\n//# sourceMappingURL=set-audio-node-tail-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/start-rendering.js\n\nconst createStartRendering = (audioBufferStore, cacheTestResult, getAudioNodeRenderer, getUnrenderedAudioWorkletNodes, renderNativeOfflineAudioContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n return (destination, nativeOfflineAudioContext) => getAudioNodeRenderer(destination)\n .render(destination, nativeOfflineAudioContext)\n /*\n * Bug #86 & #87: Invoking the renderer of an AudioWorkletNode might be necessary if it has no direct or indirect connection to the\n * destination.\n */\n .then(() => Promise.all(Array.from(getUnrenderedAudioWorkletNodes(nativeOfflineAudioContext)).map((audioWorkletNode) => getAudioNodeRenderer(audioWorkletNode).render(audioWorkletNode, nativeOfflineAudioContext))))\n .then(() => renderNativeOfflineAudioContext(nativeOfflineAudioContext))\n .then((audioBuffer) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n }\n else if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n return audioBuffer;\n });\n};\n//# sourceMappingURL=start-rendering.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/stereo-panner-node-constructor.js\nconst stereo_panner_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n /*\n * Bug #105: The channelCountMode should be \'clamped-max\' according to the spec but is set to \'explicit\' to achieve consistent\n * behavior.\n */\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n pan: 0\n};\nconst createStereoPannerNodeConstructor = (audioNodeConstructor, createAudioParam, createNativeStereoPannerNode, createStereoPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext) => {\n return class StereoPannerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...stereo_panner_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeStereoPannerNode = createNativeStereoPannerNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const stereoPannerNodeRenderer = (isOffline ? createStereoPannerNodeRenderer() : null);\n super(context, false, nativeStereoPannerNode, stereoPannerNodeRenderer);\n this._pan = createAudioParam(this, isOffline, nativeStereoPannerNode.pan);\n }\n get pan() {\n return this._pan;\n }\n };\n};\n//# sourceMappingURL=stereo-panner-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/stereo-panner-node-renderer-factory.js\n\n\nconst createStereoPannerNodeRendererFactory = (connectAudioParam, createNativeStereoPannerNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeStereoPannerNodes = new WeakMap();\n const createStereoPannerNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeStereoPannerNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeStereoPannerNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeStereoPannerNodeIsOwnedByContext = isOwnedByContext(nativeStereoPannerNode, nativeOfflineAudioContext);\n if (!nativeStereoPannerNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeStereoPannerNode.channelCount,\n channelCountMode: nativeStereoPannerNode.channelCountMode,\n channelInterpretation: nativeStereoPannerNode.channelInterpretation,\n pan: nativeStereoPannerNode.pan.value\n };\n nativeStereoPannerNode = createNativeStereoPannerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeStereoPannerNodes.set(nativeOfflineAudioContext, nativeStereoPannerNode);\n if (!nativeStereoPannerNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.pan, nativeStereoPannerNode.pan);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.pan, nativeStereoPannerNode.pan);\n }\n if (isNativeAudioNodeFaker(nativeStereoPannerNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeStereoPannerNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeStereoPannerNode);\n }\n return nativeStereoPannerNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeStereoPannerNode = renderedNativeStereoPannerNodes.get(nativeOfflineAudioContext);\n if (renderedNativeStereoPannerNode !== undefined) {\n return Promise.resolve(renderedNativeStereoPannerNode);\n }\n return createStereoPannerNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=stereo-panner-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-audio-buffer-constructor-support.js\n// Bug #33: Safari exposes an AudioBuffer but it can\'t be used as a constructor.\nconst createTestAudioBufferConstructorSupport = (nativeAudioBufferConstructor) => {\n return () => {\n if (nativeAudioBufferConstructor === null) {\n return false;\n }\n try {\n new nativeAudioBufferConstructor({ length: 1, sampleRate: 44100 }); // tslint:disable-line:no-unused-expression\n }\n catch {\n return false;\n }\n return true;\n };\n};\n//# sourceMappingURL=test-audio-buffer-constructor-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-audio-worklet-processor-post-message-support.js\n// Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\nconst createTestAudioWorkletProcessorPostMessageSupport = (nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor) => {\n return async () => {\n // Bug #61: If there is no native AudioWorkletNode it gets faked and therefore it is no problem if the it doesn\'t exist.\n if (nativeAudioWorkletNodeConstructor === null) {\n return true;\n }\n if (nativeOfflineAudioContextConstructor === null) {\n return false;\n }\n const blob = new Blob([\'class A extends AudioWorkletProcessor{process(i){this.port.postMessage(i,[i[0][0].buffer])}}registerProcessor("a",A)\'], {\n type: \'application/javascript; charset=utf-8\'\n });\n // Bug #141: Safari does not support creating an OfflineAudioContext with less than 44100 Hz.\n const offlineAudioContext = new nativeOfflineAudioContextConstructor(1, 128, 44100);\n const url = URL.createObjectURL(blob);\n let isEmittingMessageEvents = false;\n let isEmittingProcessorErrorEvents = false;\n try {\n await offlineAudioContext.audioWorklet.addModule(url);\n const audioWorkletNode = new nativeAudioWorkletNodeConstructor(offlineAudioContext, \'a\', { numberOfOutputs: 0 });\n const oscillator = offlineAudioContext.createOscillator();\n audioWorkletNode.port.onmessage = () => (isEmittingMessageEvents = true);\n audioWorkletNode.onprocessorerror = () => (isEmittingProcessorErrorEvents = true);\n oscillator.connect(audioWorkletNode);\n oscillator.start(0);\n await offlineAudioContext.startRendering();\n }\n catch {\n // Ignore errors.\n }\n finally {\n URL.revokeObjectURL(url);\n }\n return isEmittingMessageEvents && !isEmittingProcessorErrorEvents;\n };\n};\n//# sourceMappingURL=test-audio-worklet-processor-post-message-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-offline-audio-context-current-time-support.js\nconst createTestOfflineAudioContextCurrentTimeSupport = (createNativeGainNode, nativeOfflineAudioContextConstructor) => {\n return () => {\n if (nativeOfflineAudioContextConstructor === null) {\n return Promise.resolve(false);\n }\n const nativeOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n // Bug #48: Safari does not render an OfflineAudioContext without any connected node.\n const gainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n // Bug #21: Safari does not support promises yet.\n return new Promise((resolve) => {\n nativeOfflineAudioContext.oncomplete = () => {\n gainNode.disconnect();\n resolve(nativeOfflineAudioContext.currentTime !== 0);\n };\n nativeOfflineAudioContext.startRendering();\n });\n };\n};\n//# sourceMappingURL=test-offline-audio-context-current-time-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/unknown-error.js\nconst createUnknownError = () => new DOMException(\'\', \'UnknownError\');\n//# sourceMappingURL=unknown-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wave-shaper-node-constructor.js\nconst wave_shaper_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n curve: null,\n oversample: \'none\'\n};\nconst createWaveShaperNodeConstructor = (audioNodeConstructor, createInvalidStateError, createNativeWaveShaperNode, createWaveShaperNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class WaveShaperNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...wave_shaper_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeWaveShaperNode = createNativeWaveShaperNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const waveShaperNodeRenderer = (isOffline ? createWaveShaperNodeRenderer() : null);\n // @todo Add a mechanism to only switch a WaveShaperNode to active while it is connected.\n super(context, true, nativeWaveShaperNode, waveShaperNodeRenderer);\n this._isCurveNullified = false;\n this._nativeWaveShaperNode = nativeWaveShaperNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get curve() {\n if (this._isCurveNullified) {\n return null;\n }\n return this._nativeWaveShaperNode.curve;\n }\n set curve(value) {\n // Bug #103: Safari does not allow to set the curve to null.\n if (value === null) {\n this._isCurveNullified = true;\n this._nativeWaveShaperNode.curve = new Float32Array([0, 0]);\n }\n else {\n // Bug #102: Safari does not throw an InvalidStateError when the curve has less than two samples.\n // Bug #104: Chrome and Edge will throw an InvalidAccessError when the curve has less than two samples.\n if (value.length < 2) {\n throw createInvalidStateError();\n }\n this._isCurveNullified = false;\n this._nativeWaveShaperNode.curve = value;\n }\n }\n get oversample() {\n return this._nativeWaveShaperNode.oversample;\n }\n set oversample(value) {\n this._nativeWaveShaperNode.oversample = value;\n }\n };\n};\n//# sourceMappingURL=wave-shaper-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wave-shaper-node-renderer-factory.js\n\n\nconst createWaveShaperNodeRendererFactory = (createNativeWaveShaperNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeWaveShaperNodes = new WeakMap();\n const createWaveShaperNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeWaveShaperNode = getNativeAudioNode(proxy);\n // If the initially used nativeWaveShaperNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeWaveShaperNodeIsOwnedByContext = isOwnedByContext(nativeWaveShaperNode, nativeOfflineAudioContext);\n if (!nativeWaveShaperNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeWaveShaperNode.channelCount,\n channelCountMode: nativeWaveShaperNode.channelCountMode,\n channelInterpretation: nativeWaveShaperNode.channelInterpretation,\n curve: nativeWaveShaperNode.curve,\n oversample: nativeWaveShaperNode.oversample\n };\n nativeWaveShaperNode = createNativeWaveShaperNode(nativeOfflineAudioContext, options);\n }\n renderedNativeWaveShaperNodes.set(nativeOfflineAudioContext, nativeWaveShaperNode);\n if (isNativeAudioNodeFaker(nativeWaveShaperNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeWaveShaperNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeWaveShaperNode);\n }\n return nativeWaveShaperNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeWaveShaperNode = renderedNativeWaveShaperNodes.get(nativeOfflineAudioContext);\n if (renderedNativeWaveShaperNode !== undefined) {\n return Promise.resolve(renderedNativeWaveShaperNode);\n }\n return createWaveShaperNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=wave-shaper-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/window.js\nconst createWindow = () => (typeof window === \'undefined\' ? null : window);\n//# sourceMappingURL=window.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-copy-channel-methods.js\nconst createWrapAudioBufferCopyChannelMethods = (convertNumberToUnsignedLong, createIndexSizeError) => {\n return (audioBuffer) => {\n audioBuffer.copyFromChannel = (destination, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (channelNumber >= audioBuffer.numberOfChannels) {\n throw createIndexSizeError();\n }\n const audioBufferLength = audioBuffer.length;\n const channelData = audioBuffer.getChannelData(channelNumber);\n const destinationLength = destination.length;\n for (let i = bufferOffset < 0 ? -bufferOffset : 0; i + bufferOffset < audioBufferLength && i < destinationLength; i += 1) {\n destination[i] = channelData[i + bufferOffset];\n }\n };\n audioBuffer.copyToChannel = (source, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (channelNumber >= audioBuffer.numberOfChannels) {\n throw createIndexSizeError();\n }\n const audioBufferLength = audioBuffer.length;\n const channelData = audioBuffer.getChannelData(channelNumber);\n const sourceLength = source.length;\n for (let i = bufferOffset < 0 ? -bufferOffset : 0; i + bufferOffset < audioBufferLength && i < sourceLength; i += 1) {\n channelData[i + bufferOffset] = source[i];\n }\n };\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-copy-channel-methods.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-copy-channel-methods-out-of-bounds.js\nconst createWrapAudioBufferCopyChannelMethodsOutOfBounds = (convertNumberToUnsignedLong) => {\n return (audioBuffer) => {\n audioBuffer.copyFromChannel = ((copyFromChannel) => {\n return (destination, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (bufferOffset < audioBuffer.length) {\n return copyFromChannel.call(audioBuffer, destination, channelNumber, bufferOffset);\n }\n };\n })(audioBuffer.copyFromChannel);\n audioBuffer.copyToChannel = ((copyToChannel) => {\n return (source, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (bufferOffset < audioBuffer.length) {\n return copyToChannel.call(audioBuffer, source, channelNumber, bufferOffset);\n }\n };\n })(audioBuffer.copyToChannel);\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-copy-channel-methods-out-of-bounds.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-source-node-stop-method-nullified-buffer.js\nconst createWrapAudioBufferSourceNodeStopMethodNullifiedBuffer = (overwriteAccessors) => {\n return (nativeAudioBufferSourceNode, nativeContext) => {\n const nullifiedBuffer = nativeContext.createBuffer(1, 1, 44100);\n if (nativeAudioBufferSourceNode.buffer === null) {\n nativeAudioBufferSourceNode.buffer = nullifiedBuffer;\n }\n overwriteAccessors(nativeAudioBufferSourceNode, \'buffer\', (get) => () => {\n const value = get.call(nativeAudioBufferSourceNode);\n return value === nullifiedBuffer ? null : value;\n }, (set) => (value) => {\n return set.call(nativeAudioBufferSourceNode, value === null ? nullifiedBuffer : value);\n });\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-stop-method-nullified-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-channel-merger-node.js\nconst createWrapChannelMergerNode = (createInvalidStateError, monitorConnections) => {\n return (nativeContext, channelMergerNode) => {\n // Bug #15: Safari does not return the default properties.\n channelMergerNode.channelCount = 1;\n channelMergerNode.channelCountMode = \'explicit\';\n // Bug #16: Safari does not throw an error when setting a different channelCount or channelCountMode.\n Object.defineProperty(channelMergerNode, \'channelCount\', {\n get: () => 1,\n set: () => {\n throw createInvalidStateError();\n }\n });\n Object.defineProperty(channelMergerNode, \'channelCountMode\', {\n get: () => \'explicit\',\n set: () => {\n throw createInvalidStateError();\n }\n });\n // Bug #20: Safari requires a connection of any kind to treat the input signal correctly.\n const audioBufferSourceNode = nativeContext.createBufferSource();\n const whenConnected = () => {\n const length = channelMergerNode.numberOfInputs;\n for (let i = 0; i < length; i += 1) {\n audioBufferSourceNode.connect(channelMergerNode, 0, i);\n }\n };\n const whenDisconnected = () => audioBufferSourceNode.disconnect(channelMergerNode);\n monitorConnections(channelMergerNode, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=wrap-channel-merger-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-first-sample.js\nconst getFirstSample = (audioBuffer, buffer, channelNumber) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n if (audioBuffer.copyFromChannel === undefined) {\n return audioBuffer.getChannelData(channelNumber)[0];\n }\n audioBuffer.copyFromChannel(buffer, channelNumber);\n return buffer[0];\n};\n//# sourceMappingURL=get-first-sample.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-dc-curve.js\nconst isDCCurve = (curve) => {\n if (curve === null) {\n return false;\n }\n const length = curve.length;\n if (length % 2 !== 0) {\n return curve[Math.floor(length / 2)] !== 0;\n }\n return curve[length / 2 - 1] + curve[length / 2] !== 0;\n};\n//# sourceMappingURL=is-dc-curve.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/overwrite-accessors.js\nconst overwriteAccessors = (object, property, createGetter, createSetter) => {\n let prototype = object;\n while (!prototype.hasOwnProperty(property)) {\n prototype = Object.getPrototypeOf(prototype);\n }\n const { get, set } = Object.getOwnPropertyDescriptor(prototype, property);\n Object.defineProperty(object, property, { get: createGetter(get), set: createSetter(set) });\n};\n//# sourceMappingURL=overwrite-accessors.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-audio-worklet-node-options.js\nconst sanitizeAudioWorkletNodeOptions = (options) => {\n return {\n ...options,\n outputChannelCount: options.outputChannelCount !== undefined\n ? options.outputChannelCount\n : options.numberOfInputs === 1 && options.numberOfOutputs === 1\n ? /*\n * Bug #61: This should be the computedNumberOfChannels, but unfortunately that is almost impossible to fake. That\'s why\n * the channelCountMode is required to be \'explicit\' as long as there is not a native implementation in every browser. That\n * makes sure the computedNumberOfChannels is equivilant to the channelCount which makes it much easier to compute.\n */\n [options.channelCount]\n : Array.from({ length: options.numberOfOutputs }, () => 1)\n };\n};\n//# sourceMappingURL=sanitize-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-channel-splitter-options.js\nconst sanitizeChannelSplitterOptions = (options) => {\n return { ...options, channelCount: options.numberOfOutputs };\n};\n//# sourceMappingURL=sanitize-channel-splitter-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-periodic-wave-options.js\nconst sanitizePeriodicWaveOptions = (options) => {\n const { imag, real } = options;\n if (imag === undefined) {\n if (real === undefined) {\n return { ...options, imag: [0, 0], real: [0, 0] };\n }\n return { ...options, imag: Array.from(real, () => 0), real };\n }\n if (real === undefined) {\n return { ...options, imag, real: Array.from(imag, () => 0) };\n }\n return { ...options, imag, real };\n};\n//# sourceMappingURL=sanitize-periodic-wave-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-value-at-time-until-possible.js\nconst setValueAtTimeUntilPossible = (audioParam, value, startTime) => {\n try {\n audioParam.setValueAtTime(value, startTime);\n }\n catch (err) {\n if (err.code !== 9) {\n throw err;\n }\n setValueAtTimeUntilPossible(audioParam, value, startTime + 1e-7);\n }\n};\n//# sourceMappingURL=set-value-at-time-until-possible.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-start-method-consecutive-calls-support.js\nconst testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.start();\n try {\n nativeAudioBufferSourceNode.start();\n }\n catch {\n return true;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-start-method-consecutive-calls-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-start-method-offset-clamping-support.js\nconst testAudioBufferSourceNodeStartMethodOffsetClampingSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n const nativeAudioBuffer = nativeContext.createBuffer(1, 1, 44100);\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n try {\n nativeAudioBufferSourceNode.start(0, 1);\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-start-method-offset-clamping-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-stop-method-nullified-buffer-support.js\nconst testAudioBufferSourceNodeStopMethodNullifiedBufferSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.start();\n try {\n nativeAudioBufferSourceNode.stop();\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-stop-method-nullified-buffer-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-start-method-negative-parameters-support.js\nconst testAudioScheduledSourceNodeStartMethodNegativeParametersSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createOscillator();\n try {\n nativeAudioBufferSourceNode.start(-1);\n }\n catch (err) {\n return err instanceof RangeError;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-start-method-negative-parameters-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-stop-method-consecutive-calls-support.js\nconst testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport = (nativeContext) => {\n const nativeAudioBuffer = nativeContext.createBuffer(1, 1, 44100);\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n nativeAudioBufferSourceNode.start();\n nativeAudioBufferSourceNode.stop();\n try {\n nativeAudioBufferSourceNode.stop();\n return true;\n }\n catch {\n return false;\n }\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-stop-method-consecutive-calls-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-stop-method-negative-parameters-support.js\nconst testAudioScheduledSourceNodeStopMethodNegativeParametersSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createOscillator();\n try {\n nativeAudioBufferSourceNode.stop(-1);\n }\n catch (err) {\n return err instanceof RangeError;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-stop-method-negative-parameters-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-worklet-node-options-clonability.js\nconst testAudioWorkletNodeOptionsClonability = (audioWorkletNodeOptions) => {\n const { port1, port2 } = new MessageChannel();\n try {\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port1.postMessage(audioWorkletNodeOptions);\n }\n finally {\n port1.close();\n port2.close();\n }\n};\n//# sourceMappingURL=test-audio-worklet-node-options-clonability.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-source-node-start-method-offset-clamping.js\nconst wrapAudioBufferSourceNodeStartMethodOffsetClamping = (nativeAudioBufferSourceNode) => {\n nativeAudioBufferSourceNode.start = ((start) => {\n return (when = 0, offset = 0, duration) => {\n const buffer = nativeAudioBufferSourceNode.buffer;\n // Bug #154: Safari does not clamp the offset if it is equal to or greater than the duration of the buffer.\n const clampedOffset = buffer === null ? offset : Math.min(buffer.duration, offset);\n // Bug #155: Safari does not handle the offset correctly if it would cause the buffer to be not be played at all.\n if (buffer !== null && clampedOffset > buffer.duration - 0.5 / nativeAudioBufferSourceNode.context.sampleRate) {\n start.call(nativeAudioBufferSourceNode, when, 0, 0);\n }\n else {\n start.call(nativeAudioBufferSourceNode, when, clampedOffset, duration);\n }\n };\n })(nativeAudioBufferSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-start-method-offset-clamping.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-stop-method-consecutive-calls.js\n\nconst wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls = (nativeAudioScheduledSourceNode, nativeContext) => {\n const nativeGainNode = nativeContext.createGain();\n nativeAudioScheduledSourceNode.connect(nativeGainNode);\n const disconnectGainNode = ((disconnect) => {\n return () => {\n // @todo TypeScript cannot infer the overloaded signature with 1 argument yet.\n disconnect.call(nativeAudioScheduledSourceNode, nativeGainNode);\n nativeAudioScheduledSourceNode.removeEventListener(\'ended\', disconnectGainNode);\n };\n })(nativeAudioScheduledSourceNode.disconnect);\n nativeAudioScheduledSourceNode.addEventListener(\'ended\', disconnectGainNode);\n interceptConnections(nativeAudioScheduledSourceNode, nativeGainNode);\n nativeAudioScheduledSourceNode.stop = ((stop) => {\n let isStopped = false;\n return (when = 0) => {\n if (isStopped) {\n try {\n stop.call(nativeAudioScheduledSourceNode, when);\n }\n catch {\n nativeGainNode.gain.setValueAtTime(0, when);\n }\n }\n else {\n stop.call(nativeAudioScheduledSourceNode, when);\n isStopped = true;\n }\n };\n })(nativeAudioScheduledSourceNode.stop);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-stop-method-consecutive-calls.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-event-listener.js\nconst wrapEventListener = (target, eventListener) => {\n return (event) => {\n const descriptor = { value: target };\n Object.defineProperties(event, {\n currentTarget: descriptor,\n target: descriptor\n });\n if (typeof eventListener === \'function\') {\n return eventListener.call(target, event);\n }\n return eventListener.handleEvent.call(target, event);\n };\n};\n//# sourceMappingURL=wrap-event-listener.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/module.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/*\n * @todo Explicitly referencing the barrel file seems to be necessary when enabling the\n * isolatedModules compiler option.\n */\n\n\nconst addActiveInputConnectionToAudioNode = createAddActiveInputConnectionToAudioNode(insertElementInSet);\nconst addPassiveInputConnectionToAudioNode = createAddPassiveInputConnectionToAudioNode(insertElementInSet);\nconst deleteActiveInputConnectionToAudioNode = createDeleteActiveInputConnectionToAudioNode(pickElementFromSet);\nconst audioNodeTailTimeStore = new WeakMap();\nconst getAudioNodeTailTime = createGetAudioNodeTailTime(audioNodeTailTimeStore);\nconst cacheTestResult = createCacheTestResult(new Map(), new WeakMap());\nconst module_window = createWindow();\nconst createNativeAnalyserNode = createNativeAnalyserNodeFactory(cacheTestResult, createIndexSizeError);\nconst getAudioNodeRenderer = createGetAudioNodeRenderer(getAudioNodeConnections);\nconst renderInputsOfAudioNode = createRenderInputsOfAudioNode(getAudioNodeConnections, getAudioNodeRenderer, isPartOfACycle);\nconst createAnalyserNodeRenderer = createAnalyserNodeRendererFactory(createNativeAnalyserNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst getNativeContext = createGetNativeContext(CONTEXT_STORE);\nconst nativeOfflineAudioContextConstructor = createNativeOfflineAudioContextConstructor(module_window);\nconst isNativeOfflineAudioContext = createIsNativeOfflineAudioContext(nativeOfflineAudioContextConstructor);\nconst audioParamAudioNodeStore = new WeakMap();\nconst eventTargetConstructor = createEventTargetConstructor(wrapEventListener);\nconst nativeAudioContextConstructor = createNativeAudioContextConstructor(module_window);\nconst isNativeAudioContext = createIsNativeAudioContext(nativeAudioContextConstructor);\nconst module_isNativeAudioNode = createIsNativeAudioNode(module_window);\nconst isNativeAudioParam = createIsNativeAudioParam(module_window);\nconst nativeAudioWorkletNodeConstructor = createNativeAudioWorkletNodeConstructor(module_window);\nconst audioNodeConstructor = createAudioNodeConstructor(createAddAudioNodeConnections(AUDIO_NODE_CONNECTIONS_STORE), createAddConnectionToAudioNode(addActiveInputConnectionToAudioNode, addPassiveInputConnectionToAudioNode, connectNativeAudioNodeToNativeAudioNode, deleteActiveInputConnectionToAudioNode, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getAudioNodeTailTime, getEventListenersOfAudioNode, getNativeAudioNode, insertElementInSet, isActiveAudioNode, isPartOfACycle, isPassiveAudioNode), cacheTestResult, createIncrementCycleCounterFactory(CYCLE_COUNTERS, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, isActiveAudioNode), createIndexSizeError, createInvalidAccessError, createNotSupportedError, createDecrementCycleCounter(connectNativeAudioNodeToNativeAudioNode, CYCLE_COUNTERS, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, getNativeContext, isActiveAudioNode, isNativeOfflineAudioContext), createDetectCycles(audioParamAudioNodeStore, getAudioNodeConnections, getValueForKey), eventTargetConstructor, getNativeContext, isNativeAudioContext, module_isNativeAudioNode, isNativeAudioParam, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor);\nconst analyserNodeConstructor = createAnalyserNodeConstructor(audioNodeConstructor, createAnalyserNodeRenderer, createIndexSizeError, createNativeAnalyserNode, getNativeContext, isNativeOfflineAudioContext);\n\nconst audioBufferStore = new WeakSet();\nconst nativeAudioBufferConstructor = createNativeAudioBufferConstructor(module_window);\nconst convertNumberToUnsignedLong = createConvertNumberToUnsignedLong(new Uint32Array(1));\nconst wrapAudioBufferCopyChannelMethods = createWrapAudioBufferCopyChannelMethods(convertNumberToUnsignedLong, createIndexSizeError);\nconst wrapAudioBufferCopyChannelMethodsOutOfBounds = createWrapAudioBufferCopyChannelMethodsOutOfBounds(convertNumberToUnsignedLong);\nconst audioBufferConstructor = createAudioBufferConstructor(audioBufferStore, cacheTestResult, createNotSupportedError, nativeAudioBufferConstructor, nativeOfflineAudioContextConstructor, createTestAudioBufferConstructorSupport(nativeAudioBufferConstructor), wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\n\nconst addSilentConnection = createAddSilentConnection(createNativeGainNode);\nconst renderInputsOfAudioParam = createRenderInputsOfAudioParam(getAudioNodeRenderer, getAudioParamConnections, isPartOfACycle);\nconst connectAudioParam = createConnectAudioParam(renderInputsOfAudioParam);\nconst createNativeAudioBufferSourceNode = createNativeAudioBufferSourceNodeFactory(addSilentConnection, cacheTestResult, testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, testAudioBufferSourceNodeStartMethodOffsetClampingSupport, testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioBufferSourceNodeStartMethodOffsetClamping, createWrapAudioBufferSourceNodeStopMethodNullifiedBuffer(overwriteAccessors), wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls);\nconst renderAutomation = createRenderAutomation(createGetAudioParamRenderer(getAudioParamConnections), renderInputsOfAudioParam);\nconst createAudioBufferSourceNodeRenderer = createAudioBufferSourceNodeRendererFactory(connectAudioParam, createNativeAudioBufferSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst createAudioParam = createAudioParamFactory(createAddAudioParamConnections(AUDIO_PARAM_CONNECTIONS_STORE), audioParamAudioNodeStore, AUDIO_PARAM_STORE, createAudioParamRenderer, bundle.createCancelAndHoldAutomationEvent, bundle.createCancelScheduledValuesAutomationEvent, bundle.createExponentialRampToValueAutomationEvent, bundle.createLinearRampToValueAutomationEvent, bundle.createSetTargetAutomationEvent, bundle.createSetValueAutomationEvent, bundle.createSetValueCurveAutomationEvent, nativeAudioContextConstructor, setValueAtTimeUntilPossible);\nconst audioBufferSourceNodeConstructor = createAudioBufferSourceNodeConstructor(audioNodeConstructor, createAudioBufferSourceNodeRenderer, createAudioParam, createInvalidStateError, createNativeAudioBufferSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\n\nconst audioDestinationNodeConstructor = createAudioDestinationNodeConstructor(audioNodeConstructor, createAudioDestinationNodeRenderer, createIndexSizeError, createInvalidStateError, createNativeAudioDestinationNodeFactory(createNativeGainNode, overwriteAccessors), getNativeContext, isNativeOfflineAudioContext, renderInputsOfAudioNode);\nconst createBiquadFilterNodeRenderer = createBiquadFilterNodeRendererFactory(connectAudioParam, createNativeBiquadFilterNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst setAudioNodeTailTime = createSetAudioNodeTailTime(audioNodeTailTimeStore);\nconst biquadFilterNodeConstructor = createBiquadFilterNodeConstructor(audioNodeConstructor, createAudioParam, createBiquadFilterNodeRenderer, createInvalidAccessError, createNativeBiquadFilterNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst monitorConnections = createMonitorConnections(insertElementInSet, module_isNativeAudioNode);\nconst wrapChannelMergerNode = createWrapChannelMergerNode(createInvalidStateError, monitorConnections);\nconst createNativeChannelMergerNode = createNativeChannelMergerNodeFactory(nativeAudioContextConstructor, wrapChannelMergerNode);\nconst createChannelMergerNodeRenderer = createChannelMergerNodeRendererFactory(createNativeChannelMergerNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst channelMergerNodeConstructor = createChannelMergerNodeConstructor(audioNodeConstructor, createChannelMergerNodeRenderer, createNativeChannelMergerNode, getNativeContext, isNativeOfflineAudioContext);\nconst createChannelSplitterNodeRenderer = createChannelSplitterNodeRendererFactory(createNativeChannelSplitterNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst channelSplitterNodeConstructor = createChannelSplitterNodeConstructor(audioNodeConstructor, createChannelSplitterNodeRenderer, createNativeChannelSplitterNode, getNativeContext, isNativeOfflineAudioContext, sanitizeChannelSplitterOptions);\nconst createNativeConstantSourceNodeFaker = createNativeConstantSourceNodeFakerFactory(addSilentConnection, createNativeAudioBufferSourceNode, createNativeGainNode, monitorConnections);\nconst createNativeConstantSourceNode = createNativeConstantSourceNodeFactory(addSilentConnection, cacheTestResult, createNativeConstantSourceNodeFaker, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport);\nconst createConstantSourceNodeRenderer = createConstantSourceNodeRendererFactory(connectAudioParam, createNativeConstantSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst constantSourceNodeConstructor = createConstantSourceNodeConstructor(audioNodeConstructor, createAudioParam, createConstantSourceNodeRenderer, createNativeConstantSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\nconst createNativeConvolverNode = createNativeConvolverNodeFactory(createNotSupportedError, overwriteAccessors);\nconst createConvolverNodeRenderer = createConvolverNodeRendererFactory(createNativeConvolverNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst convolverNodeConstructor = createConvolverNodeConstructor(audioNodeConstructor, createConvolverNodeRenderer, createNativeConvolverNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createDelayNodeRenderer = createDelayNodeRendererFactory(connectAudioParam, createNativeDelayNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst delayNodeConstructor = createDelayNodeConstructor(audioNodeConstructor, createAudioParam, createDelayNodeRenderer, createNativeDelayNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createNativeDynamicsCompressorNode = createNativeDynamicsCompressorNodeFactory(createNotSupportedError);\nconst createDynamicsCompressorNodeRenderer = createDynamicsCompressorNodeRendererFactory(connectAudioParam, createNativeDynamicsCompressorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst dynamicsCompressorNodeConstructor = createDynamicsCompressorNodeConstructor(audioNodeConstructor, createAudioParam, createDynamicsCompressorNodeRenderer, createNativeDynamicsCompressorNode, createNotSupportedError, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createGainNodeRenderer = createGainNodeRendererFactory(connectAudioParam, createNativeGainNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst gainNodeConstructor = createGainNodeConstructor(audioNodeConstructor, createAudioParam, createGainNodeRenderer, createNativeGainNode, getNativeContext, isNativeOfflineAudioContext);\nconst createNativeIIRFilterNodeFaker = createNativeIIRFilterNodeFakerFactory(createInvalidAccessError, createInvalidStateError, createNativeScriptProcessorNode, createNotSupportedError);\nconst renderNativeOfflineAudioContext = createRenderNativeOfflineAudioContext(cacheTestResult, createNativeGainNode, createNativeScriptProcessorNode, createTestOfflineAudioContextCurrentTimeSupport(createNativeGainNode, nativeOfflineAudioContextConstructor));\nconst createIIRFilterNodeRenderer = createIIRFilterNodeRendererFactory(createNativeAudioBufferSourceNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst createNativeIIRFilterNode = createNativeIIRFilterNodeFactory(createNativeIIRFilterNodeFaker);\nconst iIRFilterNodeConstructor = createIIRFilterNodeConstructor(audioNodeConstructor, createNativeIIRFilterNode, createIIRFilterNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createAudioListener = createAudioListenerFactory(createAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeScriptProcessorNode, createNotSupportedError, getFirstSample, isNativeOfflineAudioContext, overwriteAccessors);\nconst unrenderedAudioWorkletNodeStore = new WeakMap();\nconst minimalBaseAudioContextConstructor = createMinimalBaseAudioContextConstructor(audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener);\nconst createNativeOscillatorNode = createNativeOscillatorNodeFactory(addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls);\nconst createOscillatorNodeRenderer = createOscillatorNodeRendererFactory(connectAudioParam, createNativeOscillatorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst oscillatorNodeConstructor = createOscillatorNodeConstructor(audioNodeConstructor, createAudioParam, createNativeOscillatorNode, createOscillatorNodeRenderer, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\nconst createConnectedNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNodeFactory(createNativeAudioBufferSourceNode);\nconst createNativeWaveShaperNodeFaker = createNativeWaveShaperNodeFakerFactory(createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeGainNode, isDCCurve, monitorConnections);\nconst createNativeWaveShaperNode = createNativeWaveShaperNodeFactory(createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeWaveShaperNodeFaker, isDCCurve, monitorConnections, nativeAudioContextConstructor, overwriteAccessors);\nconst createNativePannerNodeFaker = createNativePannerNodeFakerFactory(connectNativeAudioNodeToNativeAudioNode, createInvalidStateError, createNativeChannelMergerNode, createNativeGainNode, createNativeScriptProcessorNode, createNativeWaveShaperNode, createNotSupportedError, disconnectNativeAudioNodeFromNativeAudioNode, getFirstSample, monitorConnections);\nconst createNativePannerNode = createNativePannerNodeFactory(createNativePannerNodeFaker);\nconst createPannerNodeRenderer = createPannerNodeRendererFactory(connectAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeGainNode, createNativePannerNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst pannerNodeConstructor = createPannerNodeConstructor(audioNodeConstructor, createAudioParam, createNativePannerNode, createPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createNativePeriodicWave = createNativePeriodicWaveFactory(createIndexSizeError);\nconst periodicWaveConstructor = createPeriodicWaveConstructor(createNativePeriodicWave, getNativeContext, new WeakSet(), sanitizePeriodicWaveOptions);\nconst nativeStereoPannerNodeFakerFactory = createNativeStereoPannerNodeFakerFactory(createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeGainNode, createNativeWaveShaperNode, createNotSupportedError, monitorConnections);\nconst createNativeStereoPannerNode = createNativeStereoPannerNodeFactory(nativeStereoPannerNodeFakerFactory, createNotSupportedError);\nconst createStereoPannerNodeRenderer = createStereoPannerNodeRendererFactory(connectAudioParam, createNativeStereoPannerNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst stereoPannerNodeConstructor = createStereoPannerNodeConstructor(audioNodeConstructor, createAudioParam, createNativeStereoPannerNode, createStereoPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext);\nconst createWaveShaperNodeRenderer = createWaveShaperNodeRendererFactory(createNativeWaveShaperNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst waveShaperNodeConstructor = createWaveShaperNodeConstructor(audioNodeConstructor, createInvalidStateError, createNativeWaveShaperNode, createWaveShaperNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst isSecureContext = createIsSecureContext(module_window);\nconst exposeCurrentFrameAndCurrentTime = createExposeCurrentFrameAndCurrentTime(module_window);\nconst backupOfflineAudioContextStore = new WeakMap();\nconst getOrCreateBackupOfflineAudioContext = createGetOrCreateBackupOfflineAudioContext(backupOfflineAudioContextStore, nativeOfflineAudioContextConstructor);\n// The addAudioWorkletModule() function is only available in a SecureContext.\nconst addAudioWorkletModule = isSecureContext\n ? createAddAudioWorkletModule(cacheTestResult, createNotSupportedError, createEvaluateSource(module_window), exposeCurrentFrameAndCurrentTime, createFetchSource(createAbortError), getNativeContext, getOrCreateBackupOfflineAudioContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, new WeakMap(), new WeakMap(), createTestAudioWorkletProcessorPostMessageSupport(nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor), \n // @todo window is guaranteed to be defined because isSecureContext checks that as well.\n module_window)\n : undefined;\nconst isNativeContext = createIsNativeContext(isNativeAudioContext, isNativeOfflineAudioContext);\nconst decodeAudioData = createDecodeAudioData(audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, new WeakSet(), getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\nconst baseAudioContextConstructor = createBaseAudioContextConstructor(addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor);\nconst mediaElementAudioSourceNodeConstructor = createMediaElementAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaElementAudioSourceNode, getNativeContext, isNativeOfflineAudioContext);\nconst mediaStreamAudioDestinationNodeConstructor = createMediaStreamAudioDestinationNodeConstructor(audioNodeConstructor, createNativeMediaStreamAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext);\nconst mediaStreamAudioSourceNodeConstructor = createMediaStreamAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaStreamAudioSourceNode, getNativeContext, isNativeOfflineAudioContext);\nconst createNativeMediaStreamTrackAudioSourceNode = createNativeMediaStreamTrackAudioSourceNodeFactory(createInvalidStateError, isNativeOfflineAudioContext);\nconst mediaStreamTrackAudioSourceNodeConstructor = createMediaStreamTrackAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaStreamTrackAudioSourceNode, getNativeContext);\nconst audioContextConstructor = createAudioContextConstructor(baseAudioContextConstructor, createInvalidStateError, createNotSupportedError, createUnknownError, mediaElementAudioSourceNodeConstructor, mediaStreamAudioDestinationNodeConstructor, mediaStreamAudioSourceNodeConstructor, mediaStreamTrackAudioSourceNodeConstructor, nativeAudioContextConstructor);\n\nconst getUnrenderedAudioWorkletNodes = createGetUnrenderedAudioWorkletNodes(unrenderedAudioWorkletNodeStore);\nconst addUnrenderedAudioWorkletNode = createAddUnrenderedAudioWorkletNode(getUnrenderedAudioWorkletNodes);\nconst connectMultipleOutputs = createConnectMultipleOutputs(createIndexSizeError);\nconst deleteUnrenderedAudioWorkletNode = createDeleteUnrenderedAudioWorkletNode(getUnrenderedAudioWorkletNodes);\nconst disconnectMultipleOutputs = createDisconnectMultipleOutputs(createIndexSizeError);\nconst activeAudioWorkletNodeInputsStore = new WeakMap();\nconst getActiveAudioWorkletNodeInputs = createGetActiveAudioWorkletNodeInputs(activeAudioWorkletNodeInputsStore, getValueForKey);\nconst createNativeAudioWorkletNodeFaker = createNativeAudioWorkletNodeFakerFactory(connectMultipleOutputs, createIndexSizeError, createInvalidStateError, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, createNativeScriptProcessorNode, createNotSupportedError, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getActiveAudioWorkletNodeInputs, monitorConnections);\nconst createNativeAudioWorkletNode = createNativeAudioWorkletNodeFactory(createInvalidStateError, createNativeAudioWorkletNodeFaker, createNativeGainNode, createNotSupportedError, monitorConnections);\nconst createAudioWorkletNodeRenderer = createAudioWorkletNodeRendererFactory(connectAudioParam, connectMultipleOutputs, createNativeAudioBufferSourceNode, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, deleteUnrenderedAudioWorkletNode, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getNativeAudioNode, nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst getBackupOfflineAudioContext = createGetBackupOfflineAudioContext(backupOfflineAudioContextStore);\nconst setActiveAudioWorkletNodeInputs = createSetActiveAudioWorkletNodeInputs(activeAudioWorkletNodeInputsStore);\n// The AudioWorkletNode constructor is only available in a SecureContext.\nconst audioWorkletNodeConstructor = isSecureContext\n ? createAudioWorkletNodeConstructor(addUnrenderedAudioWorkletNode, audioNodeConstructor, createAudioParam, createAudioWorkletNodeRenderer, createNativeAudioWorkletNode, getAudioNodeConnections, getBackupOfflineAudioContext, getNativeContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, sanitizeAudioWorkletNodeOptions, setActiveAudioWorkletNodeInputs, testAudioWorkletNodeOptionsClonability, wrapEventListener)\n : undefined;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst minimalAudioContextConstructor = createMinimalAudioContextConstructor(createInvalidStateError, createNotSupportedError, createUnknownError, minimalBaseAudioContextConstructor, nativeAudioContextConstructor);\n\nconst createNativeOfflineAudioContext = createCreateNativeOfflineAudioContext(createNotSupportedError, nativeOfflineAudioContextConstructor);\nconst startRendering = createStartRendering(audioBufferStore, cacheTestResult, getAudioNodeRenderer, getUnrenderedAudioWorkletNodes, renderNativeOfflineAudioContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\nconst minimalOfflineAudioContextConstructor = createMinimalOfflineAudioContextConstructor(cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, minimalBaseAudioContextConstructor, startRendering);\n\nconst offlineAudioContextConstructor = createOfflineAudioContextConstructor(baseAudioContextConstructor, cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, startRendering);\n\n\n\n\n\n\nconst isAnyAudioContext = createIsAnyAudioContext(CONTEXT_STORE, isNativeAudioContext);\nconst isAnyAudioNode = createIsAnyAudioNode(AUDIO_NODE_STORE, module_isNativeAudioNode);\nconst isAnyAudioParam = createIsAnyAudioParam(AUDIO_PARAM_STORE, isNativeAudioParam);\nconst isAnyOfflineAudioContext = createIsAnyOfflineAudioContext(CONTEXT_STORE, isNativeOfflineAudioContext);\nconst isSupported = () => createIsSupportedPromise(cacheTestResult, createTestAudioBufferCopyChannelMethodsSubarraySupport(nativeOfflineAudioContextConstructor), createTestAudioContextCloseMethodSupport(nativeAudioContextConstructor), createTestAudioContextDecodeAudioDataMethodTypeErrorSupport(nativeOfflineAudioContextConstructor), createTestAudioContextOptionsSupport(nativeAudioContextConstructor), createTestAudioNodeConnectMethodSupport(nativeOfflineAudioContextConstructor), createTestAudioWorkletProcessorNoOutputsSupport(nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor), createTestChannelMergerNodeChannelCountSupport(nativeOfflineAudioContextConstructor), createTestConstantSourceNodeAccurateSchedulingSupport(nativeOfflineAudioContextConstructor), createTestConvolverNodeBufferReassignabilitySupport(nativeOfflineAudioContextConstructor), createTestConvolverNodeChannelCountSupport(nativeOfflineAudioContextConstructor), testDomExceptionConstructorSupport, createTestIsSecureContextSupport(module_window), createTestMediaStreamAudioSourceNodeMediaStreamWithoutAudioTrackSupport(nativeAudioContextConstructor), createTestStereoPannerNodeDefaultValueSupport(nativeOfflineAudioContextConstructor), testTransferablesSupport);\n//# sourceMappingURL=module.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Debug.js\n/**\n * Assert that the statement is true, otherwise invoke the error.\n * @param statement\n * @param error The message which is passed into an Error\n */\nfunction Debug_assert(statement, error) {\n if (!statement) {\n throw new Error(error);\n }\n}\n/**\n * Make sure that the given value is within the range\n */\nfunction Debug_assertRange(value, gte, lte = Infinity) {\n if (!(gte <= value && value <= lte)) {\n throw new RangeError(`Value must be within [${gte}, ${lte}], got: ${value}`);\n }\n}\n/**\n * Make sure that the given value is within the range\n */\nfunction assertContextRunning(context) {\n // add a warning if the context is not started\n if (!context.isOffline && context.state !== "running") {\n Debug_warn("The AudioContext is \\"suspended\\". Invoke Tone.start() from a user action to start the audio.");\n }\n}\n/**\n * The default logger is the console\n */\nlet defaultLogger = console;\n/**\n * Set the logging interface\n */\nfunction setLogger(logger) {\n defaultLogger = logger;\n}\n/**\n * Log anything\n */\nfunction log(...args) {\n defaultLogger.log(...args);\n}\n/**\n * Warn anything\n */\nfunction Debug_warn(...args) {\n defaultLogger.warn(...args);\n}\n//# sourceMappingURL=Debug.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/TypeCheck.js\n/**\n * Test if the arg is undefined\n */\nfunction TypeCheck_isUndef(arg) {\n return typeof arg === "undefined";\n}\n/**\n * Test if the arg is not undefined\n */\nfunction TypeCheck_isDefined(arg) {\n return !TypeCheck_isUndef(arg);\n}\n/**\n * Test if the arg is a function\n */\nfunction isFunction(arg) {\n return typeof arg === "function";\n}\n/**\n * Test if the argument is a number.\n */\nfunction TypeCheck_isNumber(arg) {\n return (typeof arg === "number");\n}\n/**\n * Test if the given argument is an object literal (i.e. `{}`);\n */\nfunction TypeCheck_isObject(arg) {\n return (Object.prototype.toString.call(arg) === "[object Object]" && arg.constructor === Object);\n}\n/**\n * Test if the argument is a boolean.\n */\nfunction TypeCheck_isBoolean(arg) {\n return (typeof arg === "boolean");\n}\n/**\n * Test if the argument is an Array\n */\nfunction TypeCheck_isArray(arg) {\n return (Array.isArray(arg));\n}\n/**\n * Test if the argument is a string.\n */\nfunction TypeCheck_isString(arg) {\n return (typeof arg === "string");\n}\n/**\n * Test if the argument is in the form of a note in scientific pitch notation.\n * e.g. "C4"\n */\nfunction isNote(arg) {\n return TypeCheck_isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg);\n}\n//# sourceMappingURL=TypeCheck.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/AudioContext.js\n\n\n\n/**\n * Create a new AudioContext\n */\nfunction createAudioContext(options) {\n return new audioContextConstructor(options);\n}\n/**\n * Create a new OfflineAudioContext\n */\nfunction createOfflineAudioContext(channels, length, sampleRate) {\n return new offlineAudioContextConstructor(channels, length, sampleRate);\n}\n/**\n * A reference to the window object\n * @hidden\n */\nconst AudioContext_theWindow = typeof self === "object" ? self : null;\n/**\n * If the browser has a window object which has an AudioContext\n * @hidden\n */\nconst hasAudioContext = AudioContext_theWindow &&\n (AudioContext_theWindow.hasOwnProperty("AudioContext") || AudioContext_theWindow.hasOwnProperty("webkitAudioContext"));\nfunction createAudioWorkletNode(context, name, options) {\n Debug_assert(TypeCheck_isDefined(audioWorkletNodeConstructor), "This node only works in a secure context (https or localhost)");\n // @ts-ignore\n return new audioWorkletNodeConstructor(context, name, options);\n}\n/**\n * This promise resolves to a boolean which indicates if the\n * functionality is supported within the currently used browse.\n * Taken from [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context#issupported)\n */\n\n//# sourceMappingURL=AudioContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.js\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n if (typeof b !== "function" && b !== null)\r\n throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nfunction __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nfunction __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }\r\n var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";\r\n var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === "accessor") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== "object") throw new TypeError("Object expected");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.push(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === "field") initializers.push(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nfunction __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nfunction __propKey(x) {\r\n return typeof x === "symbol" ? x : "".concat(x);\r\n};\r\n\r\nfunction __setFunctionName(f, name, prefix) {\r\n if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";\r\n return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });\r\n};\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction tslib_es6_awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError("Generator is already executing.");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nvar __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nfunction __exportStar(m, o) {\r\n for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nfunction __values(o) {\r\n var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === "number") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");\r\n}\r\n\r\nfunction __read(o, n) {\r\n var m = typeof Symbol === "function" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i["return"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume("next", value); }\r\n function reject(value) { resume("throw", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, "default", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o["default"] = v;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");\r\n return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === "m") throw new TypeError("Private method is not writable");\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");\r\n return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nfunction __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use \'in\' operator on non-object");\r\n return typeof state === "function" ? receiver === state : state.has(receiver);\r\n}\r\n\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Ticker.js\n/**\n * A class which provides a reliable callback using either\n * a Web Worker, or if that isn\'t supported, falls back to setTimeout.\n */\nclass Ticker {\n constructor(callback, type, updateInterval) {\n this._callback = callback;\n this._type = type;\n this._updateInterval = updateInterval;\n // create the clock source for the first time\n this._createClock();\n }\n /**\n * Generate a web worker\n */\n _createWorker() {\n const blob = new Blob([\n /* javascript */ `\n\t\t\t// the initial timeout time\n\t\t\tlet timeoutTime = ${(this._updateInterval * 1000).toFixed(1)};\n\t\t\t// onmessage callback\n\t\t\tself.onmessage = function(msg){\n\t\t\t\ttimeoutTime = parseInt(msg.data);\n\t\t\t};\n\t\t\t// the tick function which posts a message\n\t\t\t// and schedules a new tick\n\t\t\tfunction tick(){\n\t\t\t\tsetTimeout(tick, timeoutTime);\n\t\t\t\tself.postMessage(\'tick\');\n\t\t\t}\n\t\t\t// call tick initially\n\t\t\ttick();\n\t\t\t`\n ], { type: "text/javascript" });\n const blobUrl = URL.createObjectURL(blob);\n const worker = new Worker(blobUrl);\n worker.onmessage = this._callback.bind(this);\n this._worker = worker;\n }\n /**\n * Create a timeout loop\n */\n _createTimeout() {\n this._timeout = setTimeout(() => {\n this._createTimeout();\n this._callback();\n }, this._updateInterval * 1000);\n }\n /**\n * Create the clock source.\n */\n _createClock() {\n if (this._type === "worker") {\n try {\n this._createWorker();\n }\n catch (e) {\n // workers not supported, fallback to timeout\n this._type = "timeout";\n this._createClock();\n }\n }\n else if (this._type === "timeout") {\n this._createTimeout();\n }\n }\n /**\n * Clean up the current clock source\n */\n _disposeClock() {\n if (this._timeout) {\n clearTimeout(this._timeout);\n this._timeout = 0;\n }\n if (this._worker) {\n this._worker.terminate();\n this._worker.onmessage = null;\n }\n }\n /**\n * The rate in seconds the ticker will update\n */\n get updateInterval() {\n return this._updateInterval;\n }\n set updateInterval(interval) {\n this._updateInterval = Math.max(interval, 128 / 44100);\n if (this._type === "worker") {\n this._worker.postMessage(Math.max(interval * 1000, 1));\n }\n }\n /**\n * The type of the ticker, either a worker or a timeout\n */\n get type() {\n return this._type;\n }\n set type(type) {\n this._disposeClock();\n this._type = type;\n this._createClock();\n }\n /**\n * Clean up\n */\n dispose() {\n this._disposeClock();\n }\n}\n//# sourceMappingURL=Ticker.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/AdvancedTypeCheck.js\n\n/**\n * Test if the given value is an instanceof AudioParam\n */\nfunction isAudioParam(arg) {\n return isAnyAudioParam(arg);\n}\n/**\n * Test if the given value is an instanceof AudioNode\n */\nfunction AdvancedTypeCheck_isAudioNode(arg) {\n return isAnyAudioNode(arg);\n}\n/**\n * Test if the arg is instanceof an OfflineAudioContext\n */\nfunction isOfflineAudioContext(arg) {\n return isAnyOfflineAudioContext(arg);\n}\n/**\n * Test if the arg is an instanceof AudioContext\n */\nfunction isAudioContext(arg) {\n return isAnyAudioContext(arg);\n}\n/**\n * Test if the arg is instanceof an AudioBuffer\n */\nfunction isAudioBuffer(arg) {\n return arg instanceof AudioBuffer;\n}\n//# sourceMappingURL=AdvancedTypeCheck.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Defaults.js\n\n\n/**\n * Some objects should not be merged\n */\nfunction noCopy(key, arg) {\n return key === "value" || isAudioParam(arg) || AdvancedTypeCheck_isAudioNode(arg) || isAudioBuffer(arg);\n}\nfunction Defaults_deepMerge(target, ...sources) {\n if (!sources.length) {\n return target;\n }\n const source = sources.shift();\n if (TypeCheck_isObject(target) && TypeCheck_isObject(source)) {\n for (const key in source) {\n if (noCopy(key, source[key])) {\n target[key] = source[key];\n }\n else if (TypeCheck_isObject(source[key])) {\n if (!target[key]) {\n Object.assign(target, { [key]: {} });\n }\n Defaults_deepMerge(target[key], source[key]);\n }\n else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n // @ts-ignore\n return Defaults_deepMerge(target, ...sources);\n}\n/**\n * Returns true if the two arrays have the same value for each of the elements\n */\nfunction deepEquals(arrayA, arrayB) {\n return arrayA.length === arrayB.length && arrayA.every((element, index) => arrayB[index] === element);\n}\n/**\n * Convert an args array into an object.\n */\nfunction Defaults_optionsFromArguments(defaults, argsArray, keys = [], objKey) {\n const opts = {};\n const args = Array.from(argsArray);\n // if the first argument is an object and has an object key\n if (TypeCheck_isObject(args[0]) && objKey && !Reflect.has(args[0], objKey)) {\n // if it\'s not part of the defaults\n const partOfDefaults = Object.keys(args[0]).some(key => Reflect.has(defaults, key));\n if (!partOfDefaults) {\n // merge that key\n Defaults_deepMerge(opts, { [objKey]: args[0] });\n // remove the obj key from the keys\n keys.splice(keys.indexOf(objKey), 1);\n // shift the first argument off\n args.shift();\n }\n }\n if (args.length === 1 && TypeCheck_isObject(args[0])) {\n Defaults_deepMerge(opts, args[0]);\n }\n else {\n for (let i = 0; i < keys.length; i++) {\n if (TypeCheck_isDefined(args[i])) {\n opts[keys[i]] = args[i];\n }\n }\n }\n return Defaults_deepMerge(defaults, opts);\n}\n/**\n * Return this instances default values by calling Constructor.getDefaults()\n */\nfunction getDefaultsFromInstance(instance) {\n return instance.constructor.getDefaults();\n}\n/**\n * Returns the fallback if the given object is undefined.\n * Take an array of arguments and return a formatted options object.\n */\nfunction Defaults_defaultArg(given, fallback) {\n if (TypeCheck_isUndef(given)) {\n return fallback;\n }\n else {\n return given;\n }\n}\n/**\n * Remove all of the properties belonging to omit from obj.\n */\nfunction Defaults_omitFromObject(obj, omit) {\n omit.forEach(prop => {\n if (Reflect.has(obj, prop)) {\n delete obj[prop];\n }\n });\n return obj;\n}\n//# sourceMappingURL=Defaults.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/Tone.js\n/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2019 Yotam Mann\n */\n\n\n\n/**\n * @class Tone is the base class of all other classes.\n * @category Core\n * @constructor\n */\nclass Tone {\n constructor() {\n //-------------------------------------\n // \tDEBUGGING\n //-------------------------------------\n /**\n * Set this debug flag to log all events that happen in this class.\n */\n this.debug = false;\n //-------------------------------------\n // \tDISPOSING\n //-------------------------------------\n /**\n * Indicates if the instance was disposed\n */\n this._wasDisposed = false;\n }\n /**\n * Returns all of the default options belonging to the class.\n */\n static getDefaults() {\n return {};\n }\n /**\n * Prints the outputs to the console log for debugging purposes.\n * Prints the contents only if either the object has a property\n * called `debug` set to true, or a variable called TONE_DEBUG_CLASS\n * is set to the name of the class.\n * @example\n * const osc = new Tone.Oscillator();\n * // prints all logs originating from this oscillator\n * osc.debug = true;\n * // calls to start/stop will print in the console\n * osc.start();\n */\n log(...args) {\n // if the object is either set to debug = true\n // or if there is a string on the Tone.global.with the class name\n if (this.debug || (AudioContext_theWindow && this.toString() === AudioContext_theWindow.TONE_DEBUG_CLASS)) {\n log(this, ...args);\n }\n }\n /**\n * disconnect and dispose.\n */\n dispose() {\n this._wasDisposed = true;\n return this;\n }\n /**\n * Indicates if the instance was disposed. \'Disposing\' an\n * instance means that all of the Web Audio nodes that were\n * created for the instance are disconnected and freed for garbage collection.\n */\n get disposed() {\n return this._wasDisposed;\n }\n /**\n * Convert the class to a string\n * @example\n * const osc = new Tone.Oscillator();\n * console.log(osc.toString());\n */\n toString() {\n return this.name;\n }\n}\n/**\n * The version number semver\n */\nTone.version = version;\n//# sourceMappingURL=Tone.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Math.js\n/**\n * The threshold for correctness for operators. Less than one sample even\n * at very high sampling rates (e.g. `1e-6 < 1 / 192000`).\n */\nconst EPSILON = 1e-6;\n/**\n * Test if A is greater than B\n */\nfunction GT(a, b) {\n return a > b + EPSILON;\n}\n/**\n * Test if A is greater than or equal to B\n */\nfunction GTE(a, b) {\n return GT(a, b) || EQ(a, b);\n}\n/**\n * Test if A is less than B\n */\nfunction LT(a, b) {\n return a + EPSILON < b;\n}\n/**\n * Test if A is less than B\n */\nfunction EQ(a, b) {\n return Math.abs(a - b) < EPSILON;\n}\n/**\n * Clamp the value within the given range\n */\nfunction Math_clamp(value, min, max) {\n return Math.max(Math.min(value, max), min);\n}\n//# sourceMappingURL=Math.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Timeline.js\n\n\n\n\n/**\n * A Timeline class for scheduling and maintaining state\n * along a timeline. All events must have a "time" property.\n * Internally, events are stored in time order for fast\n * retrieval.\n */\nclass Timeline extends Tone {\n constructor() {\n super();\n this.name = "Timeline";\n /**\n * The array of scheduled timeline events\n */\n this._timeline = [];\n const options = Defaults_optionsFromArguments(Timeline.getDefaults(), arguments, ["memory"]);\n this.memory = options.memory;\n this.increasing = options.increasing;\n }\n static getDefaults() {\n return {\n memory: Infinity,\n increasing: false,\n };\n }\n /**\n * The number of items in the timeline.\n */\n get length() {\n return this._timeline.length;\n }\n /**\n * Insert an event object onto the timeline. Events must have a "time" attribute.\n * @param event The event object to insert into the timeline.\n */\n add(event) {\n // the event needs to have a time attribute\n Debug_assert(Reflect.has(event, "time"), "Timeline: events must have a time attribute");\n event.time = event.time.valueOf();\n if (this.increasing && this.length) {\n const lastValue = this._timeline[this.length - 1];\n Debug_assert(GTE(event.time, lastValue.time), "The time must be greater than or equal to the last scheduled time");\n this._timeline.push(event);\n }\n else {\n const index = this._search(event.time);\n this._timeline.splice(index + 1, 0, event);\n }\n // if the length is more than the memory, remove the previous ones\n if (this.length > this.memory) {\n const diff = this.length - this.memory;\n this._timeline.splice(0, diff);\n }\n return this;\n }\n /**\n * Remove an event from the timeline.\n * @param {Object} event The event object to remove from the list.\n * @returns {Timeline} this\n */\n remove(event) {\n const index = this._timeline.indexOf(event);\n if (index !== -1) {\n this._timeline.splice(index, 1);\n }\n return this;\n }\n /**\n * Get the nearest event whose time is less than or equal to the given time.\n * @param time The time to query.\n */\n get(time, param = "time") {\n const index = this._search(time, param);\n if (index !== -1) {\n return this._timeline[index];\n }\n else {\n return null;\n }\n }\n /**\n * Return the first event in the timeline without removing it\n * @returns {Object} The first event object\n */\n peek() {\n return this._timeline[0];\n }\n /**\n * Return the first event in the timeline and remove it\n */\n shift() {\n return this._timeline.shift();\n }\n /**\n * Get the event which is scheduled after the given time.\n * @param time The time to query.\n */\n getAfter(time, param = "time") {\n const index = this._search(time, param);\n if (index + 1 < this._timeline.length) {\n return this._timeline[index + 1];\n }\n else {\n return null;\n }\n }\n /**\n * Get the event before the event at the given time.\n * @param time The time to query.\n */\n getBefore(time) {\n const len = this._timeline.length;\n // if it\'s after the last item, return the last item\n if (len > 0 && this._timeline[len - 1].time < time) {\n return this._timeline[len - 1];\n }\n const index = this._search(time);\n if (index - 1 >= 0) {\n return this._timeline[index - 1];\n }\n else {\n return null;\n }\n }\n /**\n * Cancel events at and after the given time\n * @param after The time to query.\n */\n cancel(after) {\n if (this._timeline.length > 1) {\n let index = this._search(after);\n if (index >= 0) {\n if (EQ(this._timeline[index].time, after)) {\n // get the first item with that time\n for (let i = index; i >= 0; i--) {\n if (EQ(this._timeline[i].time, after)) {\n index = i;\n }\n else {\n break;\n }\n }\n this._timeline = this._timeline.slice(0, index);\n }\n else {\n this._timeline = this._timeline.slice(0, index + 1);\n }\n }\n else {\n this._timeline = [];\n }\n }\n else if (this._timeline.length === 1) {\n // the first item\'s time\n if (GTE(this._timeline[0].time, after)) {\n this._timeline = [];\n }\n }\n return this;\n }\n /**\n * Cancel events before or equal to the given time.\n * @param time The time to cancel before.\n */\n cancelBefore(time) {\n const index = this._search(time);\n if (index >= 0) {\n this._timeline = this._timeline.slice(index + 1);\n }\n return this;\n }\n /**\n * Returns the previous event if there is one. null otherwise\n * @param event The event to find the previous one of\n * @return The event right before the given event\n */\n previousEvent(event) {\n const index = this._timeline.indexOf(event);\n if (index > 0) {\n return this._timeline[index - 1];\n }\n else {\n return null;\n }\n }\n /**\n * Does a binary search on the timeline array and returns the\n * nearest event index whose time is after or equal to the given time.\n * If a time is searched before the first index in the timeline, -1 is returned.\n * If the time is after the end, the index of the last item is returned.\n */\n _search(time, param = "time") {\n if (this._timeline.length === 0) {\n return -1;\n }\n let beginning = 0;\n const len = this._timeline.length;\n let end = len;\n if (len > 0 && this._timeline[len - 1][param] <= time) {\n return len - 1;\n }\n while (beginning < end) {\n // calculate the midpoint for roughly equal partition\n let midPoint = Math.floor(beginning + (end - beginning) / 2);\n const event = this._timeline[midPoint];\n const nextEvent = this._timeline[midPoint + 1];\n if (EQ(event[param], time)) {\n // choose the last one that has the same time\n for (let i = midPoint; i < this._timeline.length; i++) {\n const testEvent = this._timeline[i];\n if (EQ(testEvent[param], time)) {\n midPoint = i;\n }\n else {\n break;\n }\n }\n return midPoint;\n }\n else if (LT(event[param], time) && GT(nextEvent[param], time)) {\n return midPoint;\n }\n else if (GT(event[param], time)) {\n // search lower\n end = midPoint;\n }\n else {\n // search upper\n beginning = midPoint + 1;\n }\n }\n return -1;\n }\n /**\n * Internal iterator. Applies extra safety checks for\n * removing items from the array.\n */\n _iterate(callback, lowerBound = 0, upperBound = this._timeline.length - 1) {\n this._timeline.slice(lowerBound, upperBound + 1).forEach(callback);\n }\n /**\n * Iterate over everything in the array\n * @param callback The callback to invoke with every item\n */\n forEach(callback) {\n this._iterate(callback);\n return this;\n }\n /**\n * Iterate over everything in the array at or before the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachBefore(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const upperBound = this._search(time);\n if (upperBound !== -1) {\n this._iterate(callback, 0, upperBound);\n }\n return this;\n }\n /**\n * Iterate over everything in the array after the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachAfter(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const lowerBound = this._search(time);\n this._iterate(callback, lowerBound + 1);\n return this;\n }\n /**\n * Iterate over everything in the array between the startTime and endTime.\n * The timerange is inclusive of the startTime, but exclusive of the endTime.\n * range = [startTime, endTime).\n * @param startTime The time to check if items are before\n * @param endTime The end of the test interval.\n * @param callback The callback to invoke with every item\n */\n forEachBetween(startTime, endTime, callback) {\n let lowerBound = this._search(startTime);\n let upperBound = this._search(endTime);\n if (lowerBound !== -1 && upperBound !== -1) {\n if (this._timeline[lowerBound].time !== startTime) {\n lowerBound += 1;\n }\n // exclusive of the end time\n if (this._timeline[upperBound].time === endTime) {\n upperBound -= 1;\n }\n this._iterate(callback, lowerBound, upperBound);\n }\n else if (lowerBound === -1) {\n this._iterate(callback, 0, upperBound);\n }\n return this;\n }\n /**\n * Iterate over everything in the array at or after the given time. Similar to\n * forEachAfter, but includes the item(s) at the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachFrom(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n let lowerBound = this._search(time);\n // work backwards until the event time is less than time\n while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) {\n lowerBound--;\n }\n this._iterate(callback, lowerBound + 1);\n return this;\n }\n /**\n * Iterate over everything in the array at the given time\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachAtTime(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const upperBound = this._search(time);\n if (upperBound !== -1 && EQ(this._timeline[upperBound].time, time)) {\n let lowerBound = upperBound;\n for (let i = upperBound; i >= 0; i--) {\n if (EQ(this._timeline[i].time, time)) {\n lowerBound = i;\n }\n else {\n break;\n }\n }\n this._iterate(event => {\n callback(event);\n }, lowerBound, upperBound);\n }\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._timeline = [];\n return this;\n }\n}\n//# sourceMappingURL=Timeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ContextInitialization.js\n//-------------------------------------\n// INITIALIZING NEW CONTEXT\n//-------------------------------------\n/**\n * Array of callbacks to invoke when a new context is created\n */\nconst notifyNewContext = [];\n/**\n * Used internally to setup a new Context\n */\nfunction onContextInit(cb) {\n notifyNewContext.push(cb);\n}\n/**\n * Invoke any classes which need to also be initialized when a new context is created.\n */\nfunction initializeContext(ctx) {\n // add any additional modules\n notifyNewContext.forEach(cb => cb(ctx));\n}\n/**\n * Array of callbacks to invoke when a new context is created\n */\nconst notifyCloseContext = [];\n/**\n * Used internally to tear down a Context\n */\nfunction onContextClose(cb) {\n notifyCloseContext.push(cb);\n}\nfunction closeContext(ctx) {\n // add any additional modules\n notifyCloseContext.forEach(cb => cb(ctx));\n}\n//# sourceMappingURL=ContextInitialization.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Emitter.js\n\n\n/**\n * Emitter gives classes which extend it\n * the ability to listen for and emit events.\n * Inspiration and reference from Jerome Etienne\'s [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n * MIT (c) 2011 Jerome Etienne.\n * @category Core\n */\nclass Emitter extends Tone {\n constructor() {\n super(...arguments);\n this.name = "Emitter";\n }\n /**\n * Bind a callback to a specific event.\n * @param event The name of the event to listen for.\n * @param callback The callback to invoke when the event is emitted\n */\n on(event, callback) {\n // split the event\n const events = event.split(/\\W+/);\n events.forEach(eventName => {\n if (TypeCheck_isUndef(this._events)) {\n this._events = {};\n }\n if (!this._events.hasOwnProperty(eventName)) {\n this._events[eventName] = [];\n }\n this._events[eventName].push(callback);\n });\n return this;\n }\n /**\n * Bind a callback which is only invoked once\n * @param event The name of the event to listen for.\n * @param callback The callback to invoke when the event is emitted\n */\n once(event, callback) {\n const boundCallback = (...args) => {\n // invoke the callback\n callback(...args);\n // remove the event\n this.off(event, boundCallback);\n };\n this.on(event, boundCallback);\n return this;\n }\n /**\n * Remove the event listener.\n * @param event The event to stop listening to.\n * @param callback The callback which was bound to the event with Emitter.on.\n * If no callback is given, all callbacks events are removed.\n */\n off(event, callback) {\n const events = event.split(/\\W+/);\n events.forEach(eventName => {\n if (TypeCheck_isUndef(this._events)) {\n this._events = {};\n }\n if (this._events.hasOwnProperty(event)) {\n if (TypeCheck_isUndef(callback)) {\n this._events[event] = [];\n }\n else {\n const eventList = this._events[event];\n for (let i = eventList.length - 1; i >= 0; i--) {\n if (eventList[i] === callback) {\n eventList.splice(i, 1);\n }\n }\n }\n }\n });\n return this;\n }\n /**\n * Invoke all of the callbacks bound to the event\n * with any arguments passed in.\n * @param event The name of the event.\n * @param args The arguments to pass to the functions listening.\n */\n emit(event, ...args) {\n if (this._events) {\n if (this._events.hasOwnProperty(event)) {\n const eventList = this._events[event].slice(0);\n for (let i = 0, len = eventList.length; i < len; i++) {\n eventList[i].apply(this, args);\n }\n }\n }\n return this;\n }\n /**\n * Add Emitter functions (on/off/emit) to the object\n */\n static mixin(constr) {\n // instance._events = {};\n ["on", "once", "off", "emit"].forEach(name => {\n const property = Object.getOwnPropertyDescriptor(Emitter.prototype, name);\n Object.defineProperty(constr.prototype, name, property);\n });\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._events = undefined;\n return this;\n }\n}\n//# sourceMappingURL=Emitter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/BaseContext.js\n\nclass BaseContext extends Emitter {\n constructor() {\n super(...arguments);\n this.isOffline = false;\n }\n /*\n * This is a placeholder so that JSON.stringify does not throw an error\n * This matches what JSON.stringify(audioContext) returns on a native\n * audioContext instance.\n */\n toJSON() {\n return {};\n }\n}\n//# sourceMappingURL=BaseContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Context.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Wrapper around the native AudioContext.\n * @category Core\n */\nclass Context extends BaseContext {\n constructor() {\n super();\n this.name = "Context";\n /**\n * An object containing all of the constants AudioBufferSourceNodes\n */\n this._constants = new Map();\n /**\n * All of the setTimeout events.\n */\n this._timeouts = new Timeline();\n /**\n * The timeout id counter\n */\n this._timeoutIds = 0;\n /**\n * Private indicator if the context has been initialized\n */\n this._initialized = false;\n /**\n * Indicates if the context is an OfflineAudioContext or an AudioContext\n */\n this.isOffline = false;\n //--------------------------------------------\n // AUDIO WORKLET\n //--------------------------------------------\n /**\n * Maps a module name to promise of the addModule method\n */\n this._workletModules = new Map();\n const options = Defaults_optionsFromArguments(Context.getDefaults(), arguments, [\n "context",\n ]);\n if (options.context) {\n this._context = options.context;\n }\n else {\n this._context = createAudioContext({\n latencyHint: options.latencyHint,\n });\n }\n this._ticker = new Ticker(this.emit.bind(this, "tick"), options.clockSource, options.updateInterval);\n this.on("tick", this._timeoutLoop.bind(this));\n // fwd events from the context\n this._context.onstatechange = () => {\n this.emit("statechange", this.state);\n };\n this._setLatencyHint(options.latencyHint);\n this.lookAhead = options.lookAhead;\n }\n static getDefaults() {\n return {\n clockSource: "worker",\n latencyHint: "interactive",\n lookAhead: 0.1,\n updateInterval: 0.05,\n };\n }\n /**\n * Finish setting up the context. **You usually do not need to do this manually.**\n */\n initialize() {\n if (!this._initialized) {\n // add any additional modules\n initializeContext(this);\n this._initialized = true;\n }\n return this;\n }\n //---------------------------\n // BASE AUDIO CONTEXT METHODS\n //---------------------------\n createAnalyser() {\n return this._context.createAnalyser();\n }\n createOscillator() {\n return this._context.createOscillator();\n }\n createBufferSource() {\n return this._context.createBufferSource();\n }\n createBiquadFilter() {\n return this._context.createBiquadFilter();\n }\n createBuffer(numberOfChannels, length, sampleRate) {\n return this._context.createBuffer(numberOfChannels, length, sampleRate);\n }\n createChannelMerger(numberOfInputs) {\n return this._context.createChannelMerger(numberOfInputs);\n }\n createChannelSplitter(numberOfOutputs) {\n return this._context.createChannelSplitter(numberOfOutputs);\n }\n createConstantSource() {\n return this._context.createConstantSource();\n }\n createConvolver() {\n return this._context.createConvolver();\n }\n createDelay(maxDelayTime) {\n return this._context.createDelay(maxDelayTime);\n }\n createDynamicsCompressor() {\n return this._context.createDynamicsCompressor();\n }\n createGain() {\n return this._context.createGain();\n }\n createIIRFilter(feedForward, feedback) {\n // @ts-ignore\n return this._context.createIIRFilter(feedForward, feedback);\n }\n createPanner() {\n return this._context.createPanner();\n }\n createPeriodicWave(real, imag, constraints) {\n return this._context.createPeriodicWave(real, imag, constraints);\n }\n createStereoPanner() {\n return this._context.createStereoPanner();\n }\n createWaveShaper() {\n return this._context.createWaveShaper();\n }\n createMediaStreamSource(stream) {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaStreamSource(stream);\n }\n createMediaElementSource(element) {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaElementSource(element);\n }\n createMediaStreamDestination() {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaStreamDestination();\n }\n decodeAudioData(audioData) {\n return this._context.decodeAudioData(audioData);\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get currentTime() {\n return this._context.currentTime;\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get state() {\n return this._context.state;\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get sampleRate() {\n return this._context.sampleRate;\n }\n /**\n * The listener\n */\n get listener() {\n this.initialize();\n return this._listener;\n }\n set listener(l) {\n Debug_assert(!this._initialized, "The listener cannot be set after initialization.");\n this._listener = l;\n }\n /**\n * There is only one Transport per Context. It is created on initialization.\n */\n get transport() {\n this.initialize();\n return this._transport;\n }\n set transport(t) {\n Debug_assert(!this._initialized, "The transport cannot be set after initialization.");\n this._transport = t;\n }\n /**\n * This is the Draw object for the context which is useful for synchronizing the draw frame with the Tone.js clock.\n */\n get draw() {\n this.initialize();\n return this._draw;\n }\n set draw(d) {\n Debug_assert(!this._initialized, "Draw cannot be set after initialization.");\n this._draw = d;\n }\n /**\n * A reference to the Context\'s destination node.\n */\n get destination() {\n this.initialize();\n return this._destination;\n }\n set destination(d) {\n Debug_assert(!this._initialized, "The destination cannot be set after initialization.");\n this._destination = d;\n }\n /**\n * Create an audio worklet node from a name and options. The module\n * must first be loaded using [[addAudioWorkletModule]].\n */\n createAudioWorkletNode(name, options) {\n return createAudioWorkletNode(this.rawContext, name, options);\n }\n /**\n * Add an AudioWorkletProcessor module\n * @param url The url of the module\n * @param name The name of the module\n */\n addAudioWorkletModule(url, name) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n Debug_assert(TypeCheck_isDefined(this.rawContext.audioWorklet), "AudioWorkletNode is only available in a secure context (https or localhost)");\n if (!this._workletModules.has(name)) {\n this._workletModules.set(name, this.rawContext.audioWorklet.addModule(url));\n }\n yield this._workletModules.get(name);\n });\n }\n /**\n * Returns a promise which resolves when all of the worklets have been loaded on this context\n */\n workletsAreReady() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const promises = [];\n this._workletModules.forEach((promise) => promises.push(promise));\n yield Promise.all(promises);\n });\n }\n //---------------------------\n // TICKER\n //---------------------------\n /**\n * How often the interval callback is invoked.\n * This number corresponds to how responsive the scheduling\n * can be. context.updateInterval + context.lookAhead gives you the\n * total latency between scheduling an event and hearing it.\n */\n get updateInterval() {\n return this._ticker.updateInterval;\n }\n set updateInterval(interval) {\n this._ticker.updateInterval = interval;\n }\n /**\n * What the source of the clock is, either "worker" (default),\n * "timeout", or "offline" (none).\n */\n get clockSource() {\n return this._ticker.type;\n }\n set clockSource(type) {\n this._ticker.type = type;\n }\n /**\n * The type of playback, which affects tradeoffs between audio\n * output latency and responsiveness.\n * In addition to setting the value in seconds, the latencyHint also\n * accepts the strings "interactive" (prioritizes low latency),\n * "playback" (prioritizes sustained playback), "balanced" (balances\n * latency and performance).\n * @example\n * // prioritize sustained playback\n * const context = new Tone.Context({ latencyHint: "playback" });\n * // set this context as the global Context\n * Tone.setContext(context);\n * // the global context is gettable with Tone.getContext()\n * console.log(Tone.getContext().latencyHint);\n */\n get latencyHint() {\n return this._latencyHint;\n }\n /**\n * Update the lookAhead and updateInterval based on the latencyHint\n */\n _setLatencyHint(hint) {\n let lookAheadValue = 0;\n this._latencyHint = hint;\n if (TypeCheck_isString(hint)) {\n switch (hint) {\n case "interactive":\n lookAheadValue = 0.1;\n break;\n case "playback":\n lookAheadValue = 0.5;\n break;\n case "balanced":\n lookAheadValue = 0.25;\n break;\n }\n }\n this.lookAhead = lookAheadValue;\n this.updateInterval = lookAheadValue / 2;\n }\n /**\n * The unwrapped AudioContext or OfflineAudioContext\n */\n get rawContext() {\n return this._context;\n }\n /**\n * The current audio context time plus a short [[lookAhead]].\n */\n now() {\n return this._context.currentTime + this.lookAhead;\n }\n /**\n * The current audio context time without the [[lookAhead]].\n * In most cases it is better to use [[now]] instead of [[immediate]] since\n * with [[now]] the [[lookAhead]] is applied equally to _all_ components including internal components,\n * to making sure that everything is scheduled in sync. Mixing [[now]] and [[immediate]]\n * can cause some timing issues. If no lookAhead is desired, you can set the [[lookAhead]] to `0`.\n */\n immediate() {\n return this._context.currentTime;\n }\n /**\n * Starts the audio context from a suspended state. This is required\n * to initially start the AudioContext. See [[Tone.start]]\n */\n resume() {\n if (isAudioContext(this._context)) {\n return this._context.resume();\n }\n else {\n return Promise.resolve();\n }\n }\n /**\n * Close the context. Once closed, the context can no longer be used and\n * any AudioNodes created from the context will be silent.\n */\n close() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n if (isAudioContext(this._context)) {\n yield this._context.close();\n }\n if (this._initialized) {\n closeContext(this);\n }\n });\n }\n /**\n * **Internal** Generate a looped buffer at some constant value.\n */\n getConstant(val) {\n if (this._constants.has(val)) {\n return this._constants.get(val);\n }\n else {\n const buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n const arr = buffer.getChannelData(0);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = val;\n }\n const constant = this._context.createBufferSource();\n constant.channelCount = 1;\n constant.channelCountMode = "explicit";\n constant.buffer = buffer;\n constant.loop = true;\n constant.start(0);\n this._constants.set(val, constant);\n return constant;\n }\n }\n /**\n * Clean up. Also closes the audio context.\n */\n dispose() {\n super.dispose();\n this._ticker.dispose();\n this._timeouts.dispose();\n Object.keys(this._constants).map((val) => this._constants[val].disconnect());\n return this;\n }\n //---------------------------\n // TIMEOUTS\n //---------------------------\n /**\n * The private loop which keeps track of the context scheduled timeouts\n * Is invoked from the clock source\n */\n _timeoutLoop() {\n const now = this.now();\n let firstEvent = this._timeouts.peek();\n while (this._timeouts.length && firstEvent && firstEvent.time <= now) {\n // invoke the callback\n firstEvent.callback();\n // shift the first event off\n this._timeouts.shift();\n // get the next one\n firstEvent = this._timeouts.peek();\n }\n }\n /**\n * A setTimeout which is guaranteed by the clock source.\n * Also runs in the offline context.\n * @param fn The callback to invoke\n * @param timeout The timeout in seconds\n * @returns ID to use when invoking Context.clearTimeout\n */\n setTimeout(fn, timeout) {\n this._timeoutIds++;\n const now = this.now();\n this._timeouts.add({\n callback: fn,\n id: this._timeoutIds,\n time: now + timeout,\n });\n return this._timeoutIds;\n }\n /**\n * Clears a previously scheduled timeout with Tone.context.setTimeout\n * @param id The ID returned from setTimeout\n */\n clearTimeout(id) {\n this._timeouts.forEach((event) => {\n if (event.id === id) {\n this._timeouts.remove(event);\n }\n });\n return this;\n }\n /**\n * Clear the function scheduled by [[setInterval]]\n */\n clearInterval(id) {\n return this.clearTimeout(id);\n }\n /**\n * Adds a repeating event to the context\'s callback clock\n */\n setInterval(fn, interval) {\n const id = ++this._timeoutIds;\n const intervalFn = () => {\n const now = this.now();\n this._timeouts.add({\n callback: () => {\n // invoke the callback\n fn();\n // invoke the event to repeat it\n intervalFn();\n },\n id,\n time: now + interval,\n });\n };\n // kick it off\n intervalFn();\n return id;\n }\n}\n//# sourceMappingURL=Context.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/DummyContext.js\n\n\nclass DummyContext extends BaseContext {\n constructor() {\n super(...arguments);\n this.lookAhead = 0;\n this.latencyHint = 0;\n this.isOffline = false;\n }\n //---------------------------\n // BASE AUDIO CONTEXT METHODS\n //---------------------------\n createAnalyser() {\n return {};\n }\n createOscillator() {\n return {};\n }\n createBufferSource() {\n return {};\n }\n createBiquadFilter() {\n return {};\n }\n createBuffer(_numberOfChannels, _length, _sampleRate) {\n return {};\n }\n createChannelMerger(_numberOfInputs) {\n return {};\n }\n createChannelSplitter(_numberOfOutputs) {\n return {};\n }\n createConstantSource() {\n return {};\n }\n createConvolver() {\n return {};\n }\n createDelay(_maxDelayTime) {\n return {};\n }\n createDynamicsCompressor() {\n return {};\n }\n createGain() {\n return {};\n }\n createIIRFilter(_feedForward, _feedback) {\n return {};\n }\n createPanner() {\n return {};\n }\n createPeriodicWave(_real, _imag, _constraints) {\n return {};\n }\n createStereoPanner() {\n return {};\n }\n createWaveShaper() {\n return {};\n }\n createMediaStreamSource(_stream) {\n return {};\n }\n createMediaElementSource(_element) {\n return {};\n }\n createMediaStreamDestination() {\n return {};\n }\n decodeAudioData(_audioData) {\n return Promise.resolve({});\n }\n //---------------------------\n // TONE AUDIO CONTEXT METHODS\n //---------------------------\n createAudioWorkletNode(_name, _options) {\n return {};\n }\n get rawContext() {\n return {};\n }\n addAudioWorkletModule(_url, _name) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return Promise.resolve();\n });\n }\n resume() {\n return Promise.resolve();\n }\n setTimeout(_fn, _timeout) {\n return 0;\n }\n clearTimeout(_id) {\n return this;\n }\n setInterval(_fn, _interval) {\n return 0;\n }\n clearInterval(_id) {\n return this;\n }\n getConstant(_val) {\n return {};\n }\n get currentTime() {\n return 0;\n }\n get state() {\n return {};\n }\n get sampleRate() {\n return 0;\n }\n get listener() {\n return {};\n }\n get transport() {\n return {};\n }\n get draw() {\n return {};\n }\n set draw(_d) { }\n get destination() {\n return {};\n }\n set destination(_d) { }\n now() {\n return 0;\n }\n immediate() {\n return 0;\n }\n}\n//# sourceMappingURL=DummyContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Interface.js\n\n/**\n * Make the property not writable using `defineProperty`. Internal use only.\n */\nfunction Interface_readOnly(target, property) {\n if (TypeCheck_isArray(property)) {\n property.forEach(str => Interface_readOnly(target, str));\n }\n else {\n Object.defineProperty(target, property, {\n enumerable: true,\n writable: false,\n });\n }\n}\n/**\n * Make an attribute writeable. Internal use only.\n */\nfunction Interface_writable(target, property) {\n if (TypeCheck_isArray(property)) {\n property.forEach(str => Interface_writable(target, str));\n }\n else {\n Object.defineProperty(target, property, {\n writable: true,\n });\n }\n}\nconst Interface_noOp = () => {\n // no operation here!\n};\n//# sourceMappingURL=Interface.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioBuffer.js\n\n\n\n\n\n\n\n\n/**\n * AudioBuffer loading and storage. ToneAudioBuffer is used internally by all\n * classes that make requests for audio files such as Tone.Player,\n * Tone.Sampler and Tone.Convolver.\n * @example\n * const buffer = new Tone.ToneAudioBuffer("https://tonejs.github.io/audio/casio/A1.mp3", () => {\n * \tconsole.log("loaded");\n * });\n * @category Core\n */\nclass ToneAudioBuffer_ToneAudioBuffer extends Tone {\n constructor() {\n super();\n this.name = "ToneAudioBuffer";\n /**\n * Callback when the buffer is loaded.\n */\n this.onload = Interface_noOp;\n const options = Defaults_optionsFromArguments(ToneAudioBuffer_ToneAudioBuffer.getDefaults(), arguments, ["url", "onload", "onerror"]);\n this.reverse = options.reverse;\n this.onload = options.onload;\n if (options.url && isAudioBuffer(options.url) || options.url instanceof ToneAudioBuffer_ToneAudioBuffer) {\n this.set(options.url);\n }\n else if (TypeCheck_isString(options.url)) {\n // initiate the download\n this.load(options.url).catch(options.onerror);\n }\n }\n static getDefaults() {\n return {\n onerror: Interface_noOp,\n onload: Interface_noOp,\n reverse: false,\n };\n }\n /**\n * The sample rate of the AudioBuffer\n */\n get sampleRate() {\n if (this._buffer) {\n return this._buffer.sampleRate;\n }\n else {\n return Global_getContext().sampleRate;\n }\n }\n /**\n * Pass in an AudioBuffer or ToneAudioBuffer to set the value of this buffer.\n */\n set(buffer) {\n if (buffer instanceof ToneAudioBuffer_ToneAudioBuffer) {\n // if it\'s loaded, set it\n if (buffer.loaded) {\n this._buffer = buffer.get();\n }\n else {\n // otherwise when it\'s loaded, invoke it\'s callback\n buffer.onload = () => {\n this.set(buffer);\n this.onload(this);\n };\n }\n }\n else {\n this._buffer = buffer;\n }\n // reverse it initially\n if (this._reversed) {\n this._reverse();\n }\n return this;\n }\n /**\n * The audio buffer stored in the object.\n */\n get() {\n return this._buffer;\n }\n /**\n * Makes an fetch request for the selected url then decodes the file as an audio buffer.\n * Invokes the callback once the audio buffer loads.\n * @param url The url of the buffer to load. filetype support depends on the browser.\n * @returns A Promise which resolves with this ToneAudioBuffer\n */\n load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const doneLoading = ToneAudioBuffer_ToneAudioBuffer.load(url).then(audioBuffer => {\n this.set(audioBuffer);\n // invoke the onload method\n this.onload(this);\n });\n ToneAudioBuffer_ToneAudioBuffer.downloads.push(doneLoading);\n try {\n yield doneLoading;\n }\n finally {\n // remove the downloaded file\n const index = ToneAudioBuffer_ToneAudioBuffer.downloads.indexOf(doneLoading);\n ToneAudioBuffer_ToneAudioBuffer.downloads.splice(index, 1);\n }\n return this;\n });\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._buffer = undefined;\n return this;\n }\n /**\n * Set the audio buffer from the array.\n * To create a multichannel AudioBuffer, pass in a multidimensional array.\n * @param array The array to fill the audio buffer\n */\n fromArray(array) {\n const isMultidimensional = TypeCheck_isArray(array) && array[0].length > 0;\n const channels = isMultidimensional ? array.length : 1;\n const len = isMultidimensional ? array[0].length : array.length;\n const context = Global_getContext();\n const buffer = context.createBuffer(channels, len, context.sampleRate);\n const multiChannelArray = !isMultidimensional && channels === 1 ?\n [array] : array;\n for (let c = 0; c < channels; c++) {\n buffer.copyToChannel(multiChannelArray[c], c);\n }\n this._buffer = buffer;\n return this;\n }\n /**\n * Sums multiple channels into 1 channel\n * @param chanNum Optionally only copy a single channel from the array.\n */\n toMono(chanNum) {\n if (TypeCheck_isNumber(chanNum)) {\n this.fromArray(this.toArray(chanNum));\n }\n else {\n let outputArray = new Float32Array(this.length);\n const numChannels = this.numberOfChannels;\n for (let channel = 0; channel < numChannels; channel++) {\n const channelArray = this.toArray(channel);\n for (let i = 0; i < channelArray.length; i++) {\n outputArray[i] += channelArray[i];\n }\n }\n // divide by the number of channels\n outputArray = outputArray.map(sample => sample / numChannels);\n this.fromArray(outputArray);\n }\n return this;\n }\n /**\n * Get the buffer as an array. Single channel buffers will return a 1-dimensional\n * Float32Array, and multichannel buffers will return multidimensional arrays.\n * @param channel Optionally only copy a single channel from the array.\n */\n toArray(channel) {\n if (TypeCheck_isNumber(channel)) {\n return this.getChannelData(channel);\n }\n else if (this.numberOfChannels === 1) {\n return this.toArray(0);\n }\n else {\n const ret = [];\n for (let c = 0; c < this.numberOfChannels; c++) {\n ret[c] = this.getChannelData(c);\n }\n return ret;\n }\n }\n /**\n * Returns the Float32Array representing the PCM audio data for the specific channel.\n * @param channel The channel number to return\n * @return The audio as a TypedArray\n */\n getChannelData(channel) {\n if (this._buffer) {\n return this._buffer.getChannelData(channel);\n }\n else {\n return new Float32Array(0);\n }\n }\n /**\n * Cut a subsection of the array and return a buffer of the\n * subsection. Does not modify the original buffer\n * @param start The time to start the slice\n * @param end The end time to slice. If none is given will default to the end of the buffer\n */\n slice(start, end = this.duration) {\n const startSamples = Math.floor(start * this.sampleRate);\n const endSamples = Math.floor(end * this.sampleRate);\n Debug_assert(startSamples < endSamples, "The start time must be less than the end time");\n const length = endSamples - startSamples;\n const retBuffer = Global_getContext().createBuffer(this.numberOfChannels, length, this.sampleRate);\n for (let channel = 0; channel < this.numberOfChannels; channel++) {\n retBuffer.copyToChannel(this.getChannelData(channel).subarray(startSamples, endSamples), channel);\n }\n return new ToneAudioBuffer_ToneAudioBuffer(retBuffer);\n }\n /**\n * Reverse the buffer.\n */\n _reverse() {\n if (this.loaded) {\n for (let i = 0; i < this.numberOfChannels; i++) {\n this.getChannelData(i).reverse();\n }\n }\n return this;\n }\n /**\n * If the buffer is loaded or not\n */\n get loaded() {\n return this.length > 0;\n }\n /**\n * The duration of the buffer in seconds.\n */\n get duration() {\n if (this._buffer) {\n return this._buffer.duration;\n }\n else {\n return 0;\n }\n }\n /**\n * The length of the buffer in samples\n */\n get length() {\n if (this._buffer) {\n return this._buffer.length;\n }\n else {\n return 0;\n }\n }\n /**\n * The number of discrete audio channels. Returns 0 if no buffer is loaded.\n */\n get numberOfChannels() {\n if (this._buffer) {\n return this._buffer.numberOfChannels;\n }\n else {\n return 0;\n }\n }\n /**\n * Reverse the buffer.\n */\n get reverse() {\n return this._reversed;\n }\n set reverse(rev) {\n if (this._reversed !== rev) {\n this._reversed = rev;\n this._reverse();\n }\n }\n /**\n * Create a ToneAudioBuffer from the array. To create a multichannel AudioBuffer,\n * pass in a multidimensional array.\n * @param array The array to fill the audio buffer\n * @return A ToneAudioBuffer created from the array\n */\n static fromArray(array) {\n return (new ToneAudioBuffer_ToneAudioBuffer()).fromArray(array);\n }\n /**\n * Creates a ToneAudioBuffer from a URL, returns a promise which resolves to a ToneAudioBuffer\n * @param url The url to load.\n * @return A promise which resolves to a ToneAudioBuffer\n */\n static fromUrl(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const buffer = new ToneAudioBuffer_ToneAudioBuffer();\n return yield buffer.load(url);\n });\n }\n /**\n * Loads a url using fetch and returns the AudioBuffer.\n */\n static load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n // test if the url contains multiple extensions\n const matches = url.match(/\\[([^\\]\\[]+\\|.+)\\]$/);\n if (matches) {\n const extensions = matches[1].split("|");\n let extension = extensions[0];\n for (const ext of extensions) {\n if (ToneAudioBuffer_ToneAudioBuffer.supportsType(ext)) {\n extension = ext;\n break;\n }\n }\n url = url.replace(matches[0], extension);\n }\n // make sure there is a slash between the baseUrl and the url\n const baseUrl = ToneAudioBuffer_ToneAudioBuffer.baseUrl === "" || ToneAudioBuffer_ToneAudioBuffer.baseUrl.endsWith("/") ? ToneAudioBuffer_ToneAudioBuffer.baseUrl : ToneAudioBuffer_ToneAudioBuffer.baseUrl + "/";\n const response = yield fetch(baseUrl + url);\n if (!response.ok) {\n throw new Error(`could not load url: ${url}`);\n }\n const arrayBuffer = yield response.arrayBuffer();\n const audioBuffer = yield Global_getContext().decodeAudioData(arrayBuffer);\n return audioBuffer;\n });\n }\n /**\n * Checks a url\'s extension to see if the current browser can play that file type.\n * @param url The url/extension to test\n * @return If the file extension can be played\n * @static\n * @example\n * Tone.ToneAudioBuffer.supportsType("wav"); // returns true\n * Tone.ToneAudioBuffer.supportsType("path/to/file.wav"); // returns true\n */\n static supportsType(url) {\n const extensions = url.split(".");\n const extension = extensions[extensions.length - 1];\n const response = document.createElement("audio").canPlayType("audio/" + extension);\n return response !== "";\n }\n /**\n * Returns a Promise which resolves when all of the buffers have loaded\n */\n static loaded() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n // this makes sure that the function is always async\n yield Promise.resolve();\n while (ToneAudioBuffer_ToneAudioBuffer.downloads.length) {\n yield ToneAudioBuffer_ToneAudioBuffer.downloads[0];\n }\n });\n }\n}\n//-------------------------------------\n// STATIC METHODS\n//-------------------------------------\n/**\n * A path which is prefixed before every url.\n */\nToneAudioBuffer_ToneAudioBuffer.baseUrl = "";\n/**\n * All of the downloads\n */\nToneAudioBuffer_ToneAudioBuffer.downloads = [];\n//# sourceMappingURL=ToneAudioBuffer.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/OfflineContext.js\n\n\n\n\n\n/**\n * Wrapper around the OfflineAudioContext\n * @category Core\n * @example\n * // generate a single channel, 0.5 second buffer\n * const context = new Tone.OfflineContext(1, 0.5, 44100);\n * const osc = new Tone.Oscillator({ context });\n * context.render().then(buffer => {\n * \tconsole.log(buffer.numberOfChannels, buffer.duration);\n * });\n */\nclass OfflineContext_OfflineContext extends Context {\n constructor() {\n super({\n clockSource: "offline",\n context: isOfflineAudioContext(arguments[0]) ?\n arguments[0] : createOfflineAudioContext(arguments[0], arguments[1] * arguments[2], arguments[2]),\n lookAhead: 0,\n updateInterval: isOfflineAudioContext(arguments[0]) ?\n 128 / arguments[0].sampleRate : 128 / arguments[2],\n });\n this.name = "OfflineContext";\n /**\n * An artificial clock source\n */\n this._currentTime = 0;\n this.isOffline = true;\n this._duration = isOfflineAudioContext(arguments[0]) ?\n arguments[0].length / arguments[0].sampleRate : arguments[1];\n }\n /**\n * Override the now method to point to the internal clock time\n */\n now() {\n return this._currentTime;\n }\n /**\n * Same as this.now()\n */\n get currentTime() {\n return this._currentTime;\n }\n /**\n * Render just the clock portion of the audio context.\n */\n _renderClock(asynchronous) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n let index = 0;\n while (this._duration - this._currentTime >= 0) {\n // invoke all the callbacks on that time\n this.emit("tick");\n // increment the clock in block-sized chunks\n this._currentTime += 128 / this.sampleRate;\n // yield once a second of audio\n index++;\n const yieldEvery = Math.floor(this.sampleRate / 128);\n if (asynchronous && index % yieldEvery === 0) {\n yield new Promise(done => setTimeout(done, 1));\n }\n }\n });\n }\n /**\n * Render the output of the OfflineContext\n * @param asynchronous If the clock should be rendered asynchronously, which will not block the main thread, but be slightly slower.\n */\n render(asynchronous = true) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n yield this.workletsAreReady();\n yield this._renderClock(asynchronous);\n const buffer = yield this._context.startRendering();\n return new ToneAudioBuffer_ToneAudioBuffer(buffer);\n });\n }\n /**\n * Close the context\n */\n close() {\n return Promise.resolve();\n }\n}\n//# sourceMappingURL=OfflineContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/Global.js\n\n\n\n\n\n\n/**\n * This dummy context is used to avoid throwing immediate errors when importing in Node.js\n */\nconst dummyContext = new DummyContext();\n/**\n * The global audio context which is getable and assignable through\n * getContext and setContext\n */\nlet globalContext = dummyContext;\n/**\n * Returns the default system-wide [[Context]]\n * @category Core\n */\nfunction Global_getContext() {\n if (globalContext === dummyContext && hasAudioContext) {\n Global_setContext(new Context());\n }\n return globalContext;\n}\n/**\n * Set the default audio context\n * @category Core\n */\nfunction Global_setContext(context) {\n if (isAudioContext(context)) {\n globalContext = new Context(context);\n }\n else if (isOfflineAudioContext(context)) {\n globalContext = new OfflineContext_OfflineContext(context);\n }\n else {\n globalContext = context;\n }\n}\n/**\n * Most browsers will not play _any_ audio until a user\n * clicks something (like a play button). Invoke this method\n * on a click or keypress event handler to start the audio context.\n * More about the Autoplay policy\n * [here](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio)\n * @example\n * document.querySelector("button").addEventListener("click", async () => {\n * \tawait Tone.start();\n * \tconsole.log("context started");\n * });\n * @category Core\n */\nfunction start() {\n return globalContext.resume();\n}\n/**\n * Log Tone.js + version in the console.\n */\nif (AudioContext_theWindow && !AudioContext_theWindow.TONE_SILENCE_LOGGING) {\n let prefix = "v";\n if (version === "dev") {\n prefix = "";\n }\n const printString = ` * Tone.js ${prefix}${version} * `;\n // eslint-disable-next-line no-console\n console.log(`%c${printString}`, "background: #000; color: #fff");\n}\n//# sourceMappingURL=Global.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Conversions.js\n/**\n * Equal power gain scale. Good for cross-fading.\n * @param percent (0-1)\n */\nfunction equalPowerScale(percent) {\n const piFactor = 0.5 * Math.PI;\n return Math.sin(percent * piFactor);\n}\n/**\n * Convert decibels into gain.\n */\nfunction Conversions_dbToGain(db) {\n return Math.pow(10, db / 20);\n}\n/**\n * Convert gain to decibels.\n */\nfunction Conversions_gainToDb(gain) {\n return 20 * (Math.log(gain) / Math.LN10);\n}\n/**\n * Convert an interval (in semitones) to a frequency ratio.\n * @param interval the number of semitones above the base note\n * @example\n * Tone.intervalToFrequencyRatio(0); // 1\n * Tone.intervalToFrequencyRatio(12); // 2\n * Tone.intervalToFrequencyRatio(-12); // 0.5\n */\nfunction Conversions_intervalToFrequencyRatio(interval) {\n return Math.pow(2, (interval / 12));\n}\n/**\n * The Global [concert tuning pitch](https://en.wikipedia.org/wiki/Concert_pitch) which is used\n * to generate all the other pitch values from notes. A4\'s values in Hertz.\n */\nlet A4 = 440;\nfunction getA4() {\n return A4;\n}\nfunction setA4(freq) {\n A4 = freq;\n}\n/**\n * Convert a frequency value to a MIDI note.\n * @param frequency The value to frequency value to convert.\n * @example\n * Tone.ftom(440); // returns 69\n */\nfunction Conversions_ftom(frequency) {\n return Math.round(ftomf(frequency));\n}\n/**\n * Convert a frequency to a floating point midi value\n */\nfunction ftomf(frequency) {\n return 69 + 12 * Math.log2(frequency / A4);\n}\n/**\n * Convert a MIDI note to frequency value.\n * @param midi The midi number to convert.\n * @return The corresponding frequency value\n * @example\n * Tone.mtof(69); // 440\n */\nfunction Conversions_mtof(midi) {\n return A4 * Math.pow(2, (midi - 69) / 12);\n}\n//# sourceMappingURL=Conversions.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/TimeBase.js\n\n\n/**\n * TimeBase is a flexible encoding of time which can be evaluated to and from a string.\n */\nclass TimeBaseClass extends Tone {\n /**\n * @param context The context associated with the time value. Used to compute\n * Transport and context-relative timing.\n * @param value The time value as a number, string or object\n * @param units Unit values\n */\n constructor(context, value, units) {\n super();\n /**\n * The default units\n */\n this.defaultUnits = "s";\n this._val = value;\n this._units = units;\n this.context = context;\n this._expressions = this._getExpressions();\n }\n /**\n * All of the time encoding expressions\n */\n _getExpressions() {\n return {\n hz: {\n method: (value) => {\n return this._frequencyToUnits(parseFloat(value));\n },\n regexp: /^(\\d+(?:\\.\\d+)?)hz$/i,\n },\n i: {\n method: (value) => {\n return this._ticksToUnits(parseInt(value, 10));\n },\n regexp: /^(\\d+)i$/i,\n },\n m: {\n method: (value) => {\n return this._beatsToUnits(parseInt(value, 10) * this._getTimeSignature());\n },\n regexp: /^(\\d+)m$/i,\n },\n n: {\n method: (value, dot) => {\n const numericValue = parseInt(value, 10);\n const scalar = dot === "." ? 1.5 : 1;\n if (numericValue === 1) {\n return this._beatsToUnits(this._getTimeSignature()) * scalar;\n }\n else {\n return this._beatsToUnits(4 / numericValue) * scalar;\n }\n },\n regexp: /^(\\d+)n(\\.?)$/i,\n },\n number: {\n method: (value) => {\n return this._expressions[this.defaultUnits].method.call(this, value);\n },\n regexp: /^(\\d+(?:\\.\\d+)?)$/,\n },\n s: {\n method: (value) => {\n return this._secondsToUnits(parseFloat(value));\n },\n regexp: /^(\\d+(?:\\.\\d+)?)s$/,\n },\n samples: {\n method: (value) => {\n return parseInt(value, 10) / this.context.sampleRate;\n },\n regexp: /^(\\d+)samples$/,\n },\n t: {\n method: (value) => {\n const numericValue = parseInt(value, 10);\n return this._beatsToUnits(8 / (Math.floor(numericValue) * 3));\n },\n regexp: /^(\\d+)t$/i,\n },\n tr: {\n method: (m, q, s) => {\n let total = 0;\n if (m && m !== "0") {\n total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n }\n if (q && q !== "0") {\n total += this._beatsToUnits(parseFloat(q));\n }\n if (s && s !== "0") {\n total += this._beatsToUnits(parseFloat(s) / 4);\n }\n return total;\n },\n regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?$/,\n },\n };\n }\n //-------------------------------------\n // \tVALUE OF\n //-------------------------------------\n /**\n * Evaluate the time value. Returns the time in seconds.\n */\n valueOf() {\n if (this._val instanceof TimeBaseClass) {\n this.fromType(this._val);\n }\n if (TypeCheck_isUndef(this._val)) {\n return this._noArg();\n }\n else if (TypeCheck_isString(this._val) && TypeCheck_isUndef(this._units)) {\n for (const units in this._expressions) {\n if (this._expressions[units].regexp.test(this._val.trim())) {\n this._units = units;\n break;\n }\n }\n }\n else if (TypeCheck_isObject(this._val)) {\n let total = 0;\n for (const typeName in this._val) {\n if (TypeCheck_isDefined(this._val[typeName])) {\n const quantity = this._val[typeName];\n // @ts-ignore\n const time = (new this.constructor(this.context, typeName)).valueOf() * quantity;\n total += time;\n }\n }\n return total;\n }\n if (TypeCheck_isDefined(this._units)) {\n const expr = this._expressions[this._units];\n const matching = this._val.toString().trim().match(expr.regexp);\n if (matching) {\n return expr.method.apply(this, matching.slice(1));\n }\n else {\n return expr.method.call(this, this._val);\n }\n }\n else if (TypeCheck_isString(this._val)) {\n return parseFloat(this._val);\n }\n else {\n return this._val;\n }\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS\n //-------------------------------------\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return 1 / freq;\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return (60 / this._getBpm()) * beats;\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return seconds;\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return (ticks * (this._beatsToUnits(1)) / this._getPPQ());\n }\n /**\n * With no arguments, return \'now\'\n */\n _noArg() {\n return this._now();\n }\n //-------------------------------------\n // \tTEMPO CONVERSIONS\n //-------------------------------------\n /**\n * Return the bpm\n */\n _getBpm() {\n return this.context.transport.bpm.value;\n }\n /**\n * Return the timeSignature\n */\n _getTimeSignature() {\n return this.context.transport.timeSignature;\n }\n /**\n * Return the PPQ or 192 if Transport is not available\n */\n _getPPQ() {\n return this.context.transport.PPQ;\n }\n //-------------------------------------\n // \tCONVERSION INTERFACE\n //-------------------------------------\n /**\n * Coerce a time type into this units type.\n * @param type Any time type units\n */\n fromType(type) {\n this._units = undefined;\n switch (this.defaultUnits) {\n case "s":\n this._val = type.toSeconds();\n break;\n case "i":\n this._val = type.toTicks();\n break;\n case "hz":\n this._val = type.toFrequency();\n break;\n case "midi":\n this._val = type.toMidi();\n break;\n }\n return this;\n }\n /**\n * Return the value in hertz\n */\n toFrequency() {\n return 1 / this.toSeconds();\n }\n /**\n * Return the time in samples\n */\n toSamples() {\n return this.toSeconds() * this.context.sampleRate;\n }\n /**\n * Return the time in milliseconds.\n */\n toMilliseconds() {\n return this.toSeconds() * 1000;\n }\n}\n//# sourceMappingURL=TimeBase.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Time.js\n\n\n\n/**\n * TimeClass is a primitive type for encoding and decoding Time values.\n * TimeClass can be passed into the parameter of any method which takes time as an argument.\n * @param val The time value.\n * @param units The units of the value.\n * @example\n * const time = Tone.Time("4n"); // a quarter note\n * @category Unit\n */\nclass TimeClass extends TimeBaseClass {\n constructor() {\n super(...arguments);\n this.name = "TimeClass";\n }\n _getExpressions() {\n return Object.assign(super._getExpressions(), {\n now: {\n method: (capture) => {\n return this._now() + new this.constructor(this.context, capture).valueOf();\n },\n regexp: /^\\+(.+)/,\n },\n quantize: {\n method: (capture) => {\n const quantTo = new TimeClass(this.context, capture).valueOf();\n return this._secondsToUnits(this.context.transport.nextSubdivision(quantTo));\n },\n regexp: /^@(.+)/,\n },\n });\n }\n /**\n * Quantize the time by the given subdivision. Optionally add a\n * percentage which will move the time value towards the ideal\n * quantized value by that percentage.\n * @param subdiv The subdivision to quantize to\n * @param percent Move the time value towards the quantized value by a percentage.\n * @example\n * Tone.Time(21).quantize(2); // returns 22\n * Tone.Time(0.6).quantize("4n", 0.5); // returns 0.55\n */\n quantize(subdiv, percent = 1) {\n const subdivision = new this.constructor(this.context, subdiv).valueOf();\n const value = this.valueOf();\n const multiple = Math.round(value / subdivision);\n const ideal = multiple * subdivision;\n const diff = ideal - value;\n return value + diff * percent;\n }\n //-------------------------------------\n // CONVERSIONS\n //-------------------------------------\n /**\n * Convert a Time to Notation. The notation values are will be the\n * closest representation between 1m to 128th note.\n * @return {Notation}\n * @example\n * // if the Transport is at 120bpm:\n * Tone.Time(2).toNotation(); // returns "1m"\n */\n toNotation() {\n const time = this.toSeconds();\n const testNotations = ["1m"];\n for (let power = 1; power < 9; power++) {\n const subdiv = Math.pow(2, power);\n testNotations.push(subdiv + "n.");\n testNotations.push(subdiv + "n");\n testNotations.push(subdiv + "t");\n }\n testNotations.push("0");\n // find the closets notation representation\n let closest = testNotations[0];\n let closestSeconds = new TimeClass(this.context, testNotations[0]).toSeconds();\n testNotations.forEach(notation => {\n const notationSeconds = new TimeClass(this.context, notation).toSeconds();\n if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) {\n closest = notation;\n closestSeconds = notationSeconds;\n }\n });\n return closest;\n }\n /**\n * Return the time encoded as Bars:Beats:Sixteenths.\n */\n toBarsBeatsSixteenths() {\n const quarterTime = this._beatsToUnits(1);\n let quarters = this.valueOf() / quarterTime;\n quarters = parseFloat(quarters.toFixed(4));\n const measures = Math.floor(quarters / this._getTimeSignature());\n let sixteenths = (quarters % 1) * 4;\n quarters = Math.floor(quarters) % this._getTimeSignature();\n const sixteenthString = sixteenths.toString();\n if (sixteenthString.length > 3) {\n // the additional parseFloat removes insignificant trailing zeroes\n sixteenths = parseFloat(parseFloat(sixteenthString).toFixed(3));\n }\n const progress = [measures, quarters, sixteenths];\n return progress.join(":");\n }\n /**\n * Return the time in ticks.\n */\n toTicks() {\n const quarterTime = this._beatsToUnits(1);\n const quarters = this.valueOf() / quarterTime;\n return Math.round(quarters * this._getPPQ());\n }\n /**\n * Return the time in seconds.\n */\n toSeconds() {\n return this.valueOf();\n }\n /**\n * Return the value as a midi note.\n */\n toMidi() {\n return Conversions_ftom(this.toFrequency());\n }\n _now() {\n return this.context.now();\n }\n}\n/**\n * Create a TimeClass from a time string or number. The time is computed against the\n * global Tone.Context. To use a specific context, use [[TimeClass]]\n * @param value A value which represents time\n * @param units The value\'s units if they can\'t be inferred by the value.\n * @category Unit\n * @example\n * const time = Tone.Time("4n").toSeconds();\n * console.log(time);\n * @example\n * const note = Tone.Time(1).toNotation();\n * console.log(note);\n * @example\n * const freq = Tone.Time(0.5).toFrequency();\n * console.log(freq);\n */\nfunction Time(value, units) {\n return new TimeClass(getContext(), value, units);\n}\n//# sourceMappingURL=Time.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Frequency.js\n\n\n\n\n/**\n * Frequency is a primitive type for encoding Frequency values.\n * Eventually all time values are evaluated to hertz using the `valueOf` method.\n * @example\n * Tone.Frequency("C3"); // 261\n * Tone.Frequency(38, "midi");\n * Tone.Frequency("C3").transpose(4);\n * @category Unit\n */\nclass Frequency_FrequencyClass extends TimeClass {\n constructor() {\n super(...arguments);\n this.name = "Frequency";\n this.defaultUnits = "hz";\n }\n /**\n * The [concert tuning pitch](https://en.wikipedia.org/wiki/Concert_pitch) which is used\n * to generate all the other pitch values from notes. A4\'s values in Hertz.\n */\n static get A4() {\n return getA4();\n }\n static set A4(freq) {\n setA4(freq);\n }\n //-------------------------------------\n // \tAUGMENT BASE EXPRESSIONS\n //-------------------------------------\n _getExpressions() {\n return Object.assign({}, super._getExpressions(), {\n midi: {\n regexp: /^(\\d+(?:\\.\\d+)?midi)/,\n method(value) {\n if (this.defaultUnits === "midi") {\n return value;\n }\n else {\n return Frequency_FrequencyClass.mtof(value);\n }\n },\n },\n note: {\n regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n method(pitch, octave) {\n const index = noteToScaleIndex[pitch.toLowerCase()];\n const noteNumber = index + (parseInt(octave, 10) + 1) * 12;\n if (this.defaultUnits === "midi") {\n return noteNumber;\n }\n else {\n return Frequency_FrequencyClass.mtof(noteNumber);\n }\n },\n },\n tr: {\n regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n method(m, q, s) {\n let total = 1;\n if (m && m !== "0") {\n total *= this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n }\n if (q && q !== "0") {\n total *= this._beatsToUnits(parseFloat(q));\n }\n if (s && s !== "0") {\n total *= this._beatsToUnits(parseFloat(s) / 4);\n }\n return total;\n },\n },\n });\n }\n //-------------------------------------\n // \tEXPRESSIONS\n //-------------------------------------\n /**\n * Transposes the frequency by the given number of semitones.\n * @return A new transposed frequency\n * @example\n * Tone.Frequency("A4").transpose(3); // "C5"\n */\n transpose(interval) {\n return new Frequency_FrequencyClass(this.context, this.valueOf() * Conversions_intervalToFrequencyRatio(interval));\n }\n /**\n * Takes an array of semitone intervals and returns\n * an array of frequencies transposed by those intervals.\n * @return Returns an array of Frequencies\n * @example\n * Tone.Frequency("A4").harmonize([0, 3, 7]); // ["A4", "C5", "E5"]\n */\n harmonize(intervals) {\n return intervals.map(interval => {\n return this.transpose(interval);\n });\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS\n //-------------------------------------\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Frequency("C4").toMidi(); // 60\n */\n toMidi() {\n return Conversions_ftom(this.valueOf());\n }\n /**\n * Return the value of the frequency in Scientific Pitch Notation\n * @example\n * Tone.Frequency(69, "midi").toNote(); // "A4"\n */\n toNote() {\n const freq = this.toFrequency();\n const log = Math.log2(freq / Frequency_FrequencyClass.A4);\n let noteNumber = Math.round(12 * log) + 57;\n const octave = Math.floor(noteNumber / 12);\n if (octave < 0) {\n noteNumber += -12 * octave;\n }\n const noteName = scaleIndexToNote[noteNumber % 12];\n return noteName + octave.toString();\n }\n /**\n * Return the duration of one cycle in seconds.\n */\n toSeconds() {\n return 1 / super.toSeconds();\n }\n /**\n * Return the duration of one cycle in ticks\n */\n toTicks() {\n const quarterTime = this._beatsToUnits(1);\n const quarters = this.valueOf() / quarterTime;\n return Math.floor(quarters * this._getPPQ());\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS HELPERS\n //-------------------------------------\n /**\n * With no arguments, return 0\n */\n _noArg() {\n return 0;\n }\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return freq;\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return 1 / ((ticks * 60) / (this._getBpm() * this._getPPQ()));\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return 1 / super._beatsToUnits(beats);\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return 1 / seconds;\n }\n /**\n * Convert a MIDI note to frequency value.\n * @param midi The midi number to convert.\n * @return The corresponding frequency value\n */\n static mtof(midi) {\n return Conversions_mtof(midi);\n }\n /**\n * Convert a frequency value to a MIDI note.\n * @param frequency The value to frequency value to convert.\n */\n static ftom(frequency) {\n return Conversions_ftom(frequency);\n }\n}\n//-------------------------------------\n// \tFREQUENCY CONVERSIONS\n//-------------------------------------\n/**\n * Note to scale index.\n * @hidden\n */\nconst noteToScaleIndex = {\n cbb: -2, cb: -1, c: 0, "c#": 1, cx: 2,\n dbb: 0, db: 1, d: 2, "d#": 3, dx: 4,\n ebb: 2, eb: 3, e: 4, "e#": 5, ex: 6,\n fbb: 3, fb: 4, f: 5, "f#": 6, fx: 7,\n gbb: 5, gb: 6, g: 7, "g#": 8, gx: 9,\n abb: 7, ab: 8, a: 9, "a#": 10, ax: 11,\n bbb: 9, bb: 10, b: 11, "b#": 12, bx: 13,\n};\n/**\n * scale index to note (sharps)\n * @hidden\n */\nconst scaleIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];\n/**\n * Convert a value into a FrequencyClass object.\n * @category Unit\n * @example\n * const midi = Tone.Frequency("C3").toMidi();\n * console.log(midi);\n * @example\n * const hertz = Tone.Frequency(38, "midi").toFrequency();\n * console.log(hertz);\n */\nfunction Frequency(value, units) {\n return new Frequency_FrequencyClass(getContext(), value, units);\n}\n//# sourceMappingURL=Frequency.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/TransportTime.js\n\n\n/**\n * TransportTime is a the time along the Transport\'s\n * timeline. It is similar to Tone.Time, but instead of evaluating\n * against the AudioContext\'s clock, it is evaluated against\n * the Transport\'s position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n * @category Unit\n */\nclass TransportTime_TransportTimeClass extends TimeClass {\n constructor() {\n super(...arguments);\n this.name = "TransportTime";\n }\n /**\n * Return the current time in whichever context is relevant\n */\n _now() {\n return this.context.transport.seconds;\n }\n}\n/**\n * TransportTime is a the time along the Transport\'s\n * timeline. It is similar to [[Time]], but instead of evaluating\n * against the AudioContext\'s clock, it is evaluated against\n * the Transport\'s position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n * @category Unit\n */\nfunction TransportTime(value, units) {\n return new TransportTime_TransportTimeClass(getContext(), value, units);\n}\n//# sourceMappingURL=TransportTime.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneWithContext.js\n\n\n\n\n\n\n\n/**\n * The Base class for all nodes that have an AudioContext.\n */\nclass ToneWithContext_ToneWithContext extends Tone {\n constructor() {\n super();\n const options = Defaults_optionsFromArguments(ToneWithContext_ToneWithContext.getDefaults(), arguments, ["context"]);\n if (this.defaultContext) {\n this.context = this.defaultContext;\n }\n else {\n this.context = options.context;\n }\n }\n static getDefaults() {\n return {\n context: Global_getContext(),\n };\n }\n /**\n * Return the current time of the Context clock plus the lookAhead.\n * @example\n * setInterval(() => {\n * \tconsole.log(Tone.now());\n * }, 100);\n */\n now() {\n return this.context.currentTime + this.context.lookAhead;\n }\n /**\n * Return the current time of the Context clock without any lookAhead.\n * @example\n * setInterval(() => {\n * \tconsole.log(Tone.immediate());\n * }, 100);\n */\n immediate() {\n return this.context.currentTime;\n }\n /**\n * The duration in seconds of one sample.\n * @example\n * console.log(Tone.Transport.sampleTime);\n */\n get sampleTime() {\n return 1 / this.context.sampleRate;\n }\n /**\n * The number of seconds of 1 processing block (128 samples)\n * @example\n * console.log(Tone.Destination.blockTime);\n */\n get blockTime() {\n return 128 / this.context.sampleRate;\n }\n /**\n * Convert the incoming time to seconds.\n * This is calculated against the current [[Tone.Transport]] bpm\n * @example\n * const gain = new Tone.Gain();\n * setInterval(() => console.log(gain.toSeconds("4n")), 100);\n * // ramp the tempo to 60 bpm over 30 seconds\n * Tone.getTransport().bpm.rampTo(60, 30);\n */\n toSeconds(time) {\n return new TimeClass(this.context, time).toSeconds();\n }\n /**\n * Convert the input to a frequency number\n * @example\n * const gain = new Tone.Gain();\n * console.log(gain.toFrequency("4n"));\n */\n toFrequency(freq) {\n return new Frequency_FrequencyClass(this.context, freq).toFrequency();\n }\n /**\n * Convert the input time into ticks\n * @example\n * const gain = new Tone.Gain();\n * console.log(gain.toTicks("4n"));\n */\n toTicks(time) {\n return new TransportTime_TransportTimeClass(this.context, time).toTicks();\n }\n //-------------------------------------\n // \tGET/SET\n //-------------------------------------\n /**\n * Get a subset of the properties which are in the partial props\n */\n _getPartialProperties(props) {\n const options = this.get();\n // remove attributes from the prop that are not in the partial\n Object.keys(options).forEach(name => {\n if (TypeCheck_isUndef(props[name])) {\n delete options[name];\n }\n });\n return options;\n }\n /**\n * Get the object\'s attributes.\n * @example\n * const osc = new Tone.Oscillator();\n * console.log(osc.get());\n */\n get() {\n const defaults = getDefaultsFromInstance(this);\n Object.keys(defaults).forEach(attribute => {\n if (Reflect.has(this, attribute)) {\n const member = this[attribute];\n if (TypeCheck_isDefined(member) && TypeCheck_isDefined(member.value) && TypeCheck_isDefined(member.setValueAtTime)) {\n defaults[attribute] = member.value;\n }\n else if (member instanceof ToneWithContext_ToneWithContext) {\n defaults[attribute] = member._getPartialProperties(defaults[attribute]);\n // otherwise make sure it\'s a serializable type\n }\n else if (TypeCheck_isArray(member) || TypeCheck_isNumber(member) || TypeCheck_isString(member) || TypeCheck_isBoolean(member)) {\n defaults[attribute] = member;\n }\n else {\n // remove all undefined and unserializable attributes\n delete defaults[attribute];\n }\n }\n });\n return defaults;\n }\n /**\n * Set multiple properties at once with an object.\n * @example\n * const filter = new Tone.Filter().toDestination();\n * // set values using an object\n * filter.set({\n * \tfrequency: "C6",\n * \ttype: "highpass"\n * });\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/Analogsynth_octaves_highmid.mp3").connect(filter);\n * player.autostart = true;\n */\n set(props) {\n Object.keys(props).forEach(attribute => {\n if (Reflect.has(this, attribute) && TypeCheck_isDefined(this[attribute])) {\n if (this[attribute] && TypeCheck_isDefined(this[attribute].value) && TypeCheck_isDefined(this[attribute].setValueAtTime)) {\n // small optimization\n if (this[attribute].value !== props[attribute]) {\n this[attribute].value = props[attribute];\n }\n }\n else if (this[attribute] instanceof ToneWithContext_ToneWithContext) {\n this[attribute].set(props[attribute]);\n }\n else {\n this[attribute] = props[attribute];\n }\n }\n });\n return this;\n }\n}\n//# sourceMappingURL=ToneWithContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/StateTimeline.js\n\n\n/**\n * A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)`\n * @param initial The initial state of the StateTimeline. Defaults to `undefined`\n */\nclass StateTimeline_StateTimeline extends Timeline {\n constructor(initial = "stopped") {\n super();\n this.name = "StateTimeline";\n this._initial = initial;\n this.setStateAtTime(this._initial, 0);\n }\n /**\n * Returns the scheduled state scheduled before or at\n * the given time.\n * @param time The time to query.\n * @return The name of the state input in setStateAtTime.\n */\n getValueAtTime(time) {\n const event = this.get(time);\n if (event !== null) {\n return event.state;\n }\n else {\n return this._initial;\n }\n }\n /**\n * Add a state to the timeline.\n * @param state The name of the state to set.\n * @param time The time to query.\n * @param options Any additional options that are needed in the timeline.\n */\n setStateAtTime(state, time, options) {\n Debug_assertRange(time, 0);\n this.add(Object.assign({}, options, {\n state,\n time,\n }));\n return this;\n }\n /**\n * Return the event before the time with the given state\n * @param state The state to look for\n * @param time When to check before\n * @return The event with the given state before the time\n */\n getLastState(state, time) {\n // time = this.toSeconds(time);\n const index = this._search(time);\n for (let i = index; i >= 0; i--) {\n const event = this._timeline[i];\n if (event.state === state) {\n return event;\n }\n }\n }\n /**\n * Return the event after the time with the given state\n * @param state The state to look for\n * @param time When to check from\n * @return The event with the given state after the time\n */\n getNextState(state, time) {\n // time = this.toSeconds(time);\n const index = this._search(time);\n if (index !== -1) {\n for (let i = index; i < this._timeline.length; i++) {\n const event = this._timeline[i];\n if (event.state === state) {\n return event;\n }\n }\n }\n }\n}\n//# sourceMappingURL=StateTimeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Param.js\n\n\n\n\n\n\n\n\n/**\n * Param wraps the native Web Audio\'s AudioParam to provide\n * additional unit conversion functionality. It also\n * serves as a base-class for classes which have a single,\n * automatable parameter.\n * @category Core\n */\nclass Param_Param extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Param_Param.getDefaults(), arguments, ["param", "units", "convert"]));\n this.name = "Param";\n this.overridden = false;\n /**\n * The minimum output value\n */\n this._minOutput = 1e-7;\n const options = Defaults_optionsFromArguments(Param_Param.getDefaults(), arguments, ["param", "units", "convert"]);\n Debug_assert(TypeCheck_isDefined(options.param) &&\n (isAudioParam(options.param) || options.param instanceof Param_Param), "param must be an AudioParam");\n while (!isAudioParam(options.param)) {\n options.param = options.param._param;\n }\n this._swappable = TypeCheck_isDefined(options.swappable) ? options.swappable : false;\n if (this._swappable) {\n this.input = this.context.createGain();\n // initialize\n this._param = options.param;\n this.input.connect(this._param);\n }\n else {\n this._param = this.input = options.param;\n }\n this._events = new Timeline(1000);\n this._initialValue = this._param.defaultValue;\n this.units = options.units;\n this.convert = options.convert;\n this._minValue = options.minValue;\n this._maxValue = options.maxValue;\n // if the value is defined, set it immediately\n if (TypeCheck_isDefined(options.value) && options.value !== this._toType(this._initialValue)) {\n this.setValueAtTime(options.value, 0);\n }\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n convert: true,\n units: "number",\n });\n }\n get value() {\n const now = this.now();\n return this.getValueAtTime(now);\n }\n set value(value) {\n this.cancelScheduledValues(this.now());\n this.setValueAtTime(value, this.now());\n }\n get minValue() {\n // if it\'s not the default minValue, return it\n if (TypeCheck_isDefined(this._minValue)) {\n return this._minValue;\n }\n else if (this.units === "time" || this.units === "frequency" ||\n this.units === "normalRange" || this.units === "positive" ||\n this.units === "transportTime" || this.units === "ticks" ||\n this.units === "bpm" || this.units === "hertz" || this.units === "samples") {\n return 0;\n }\n else if (this.units === "audioRange") {\n return -1;\n }\n else if (this.units === "decibels") {\n return -Infinity;\n }\n else {\n return this._param.minValue;\n }\n }\n get maxValue() {\n if (TypeCheck_isDefined(this._maxValue)) {\n return this._maxValue;\n }\n else if (this.units === "normalRange" ||\n this.units === "audioRange") {\n return 1;\n }\n else {\n return this._param.maxValue;\n }\n }\n /**\n * Type guard based on the unit name\n */\n _is(arg, type) {\n return this.units === type;\n }\n /**\n * Make sure the value is always in the defined range\n */\n _assertRange(value) {\n if (TypeCheck_isDefined(this.maxValue) && TypeCheck_isDefined(this.minValue)) {\n Debug_assertRange(value, this._fromType(this.minValue), this._fromType(this.maxValue));\n }\n return value;\n }\n /**\n * Convert the given value from the type specified by Param.units\n * into the destination value (such as Gain or Frequency).\n */\n _fromType(val) {\n if (this.convert && !this.overridden) {\n if (this._is(val, "time")) {\n return this.toSeconds(val);\n }\n else if (this._is(val, "decibels")) {\n return Conversions_dbToGain(val);\n }\n else if (this._is(val, "frequency")) {\n return this.toFrequency(val);\n }\n else {\n return val;\n }\n }\n else if (this.overridden) {\n // if it\'s overridden, should only schedule 0s\n return 0;\n }\n else {\n return val;\n }\n }\n /**\n * Convert the parameters value into the units specified by Param.units.\n */\n _toType(val) {\n if (this.convert && this.units === "decibels") {\n return Conversions_gainToDb(val);\n }\n else {\n return val;\n }\n }\n //-------------------------------------\n // ABSTRACT PARAM INTERFACE\n // all docs are generated from ParamInterface.ts\n //-------------------------------------\n setValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n const numericValue = this._fromType(value);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to setValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(time)}`);\n this._assertRange(numericValue);\n this.log(this.units, "setValueAtTime", value, computedTime);\n this._events.add({\n time: computedTime,\n type: "setValueAtTime",\n value: numericValue,\n });\n this._param.setValueAtTime(numericValue, computedTime);\n return this;\n }\n getValueAtTime(time) {\n const computedTime = Math.max(this.toSeconds(time), 0);\n const after = this._events.getAfter(computedTime);\n const before = this._events.get(computedTime);\n let value = this._initialValue;\n // if it was set by\n if (before === null) {\n value = this._initialValue;\n }\n else if (before.type === "setTargetAtTime" && (after === null || after.type === "setValueAtTime")) {\n const previous = this._events.getBefore(before.time);\n let previousVal;\n if (previous === null) {\n previousVal = this._initialValue;\n }\n else {\n previousVal = previous.value;\n }\n if (before.type === "setTargetAtTime") {\n value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, computedTime);\n }\n }\n else if (after === null) {\n value = before.value;\n }\n else if (after.type === "linearRampToValueAtTime" || after.type === "exponentialRampToValueAtTime") {\n let beforeValue = before.value;\n if (before.type === "setTargetAtTime") {\n const previous = this._events.getBefore(before.time);\n if (previous === null) {\n beforeValue = this._initialValue;\n }\n else {\n beforeValue = previous.value;\n }\n }\n if (after.type === "linearRampToValueAtTime") {\n value = this._linearInterpolate(before.time, beforeValue, after.time, after.value, computedTime);\n }\n else {\n value = this._exponentialInterpolate(before.time, beforeValue, after.time, after.value, computedTime);\n }\n }\n else {\n value = before.value;\n }\n return this._toType(value);\n }\n setRampPoint(time) {\n time = this.toSeconds(time);\n let currentVal = this.getValueAtTime(time);\n this.cancelAndHoldAtTime(time);\n if (this._fromType(currentVal) === 0) {\n currentVal = this._toType(this._minOutput);\n }\n this.setValueAtTime(currentVal, time);\n return this;\n }\n linearRampToValueAtTime(value, endTime) {\n const numericValue = this._fromType(value);\n const computedTime = this.toSeconds(endTime);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to linearRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`);\n this._assertRange(numericValue);\n this._events.add({\n time: computedTime,\n type: "linearRampToValueAtTime",\n value: numericValue,\n });\n this.log(this.units, "linearRampToValueAtTime", value, computedTime);\n this._param.linearRampToValueAtTime(numericValue, computedTime);\n return this;\n }\n exponentialRampToValueAtTime(value, endTime) {\n let numericValue = this._fromType(value);\n // the value can\'t be 0\n numericValue = EQ(numericValue, 0) ? this._minOutput : numericValue;\n this._assertRange(numericValue);\n const computedTime = this.toSeconds(endTime);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to exponentialRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`);\n // store the event\n this._events.add({\n time: computedTime,\n type: "exponentialRampToValueAtTime",\n value: numericValue,\n });\n this.log(this.units, "exponentialRampToValueAtTime", value, computedTime);\n this._param.exponentialRampToValueAtTime(numericValue, computedTime);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.exponentialApproachValueAtTime(value, startTime, rampTime);\n return this;\n }\n exponentialApproachValueAtTime(value, time, rampTime) {\n time = this.toSeconds(time);\n rampTime = this.toSeconds(rampTime);\n const timeConstant = Math.log(rampTime + 1) / Math.log(200);\n this.setTargetAtTime(value, time, timeConstant);\n // at 90% start a linear ramp to the final value\n this.cancelAndHoldAtTime(time + rampTime * 0.9);\n this.linearRampToValueAtTime(value, time + rampTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n const numericValue = this._fromType(value);\n // The value will never be able to approach without timeConstant > 0.\n Debug_assert(isFinite(timeConstant) && timeConstant > 0, "timeConstant must be a number greater than 0");\n const computedTime = this.toSeconds(startTime);\n this._assertRange(numericValue);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to setTargetAtTime: ${JSON.stringify(value)}, ${JSON.stringify(startTime)}`);\n this._events.add({\n constant: timeConstant,\n time: computedTime,\n type: "setTargetAtTime",\n value: numericValue,\n });\n this.log(this.units, "setTargetAtTime", value, computedTime, timeConstant);\n this._param.setTargetAtTime(numericValue, computedTime, timeConstant);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling = 1) {\n duration = this.toSeconds(duration);\n startTime = this.toSeconds(startTime);\n const startingValue = this._fromType(values[0]) * scaling;\n this.setValueAtTime(this._toType(startingValue), startTime);\n const segTime = duration / (values.length - 1);\n for (let i = 1; i < values.length; i++) {\n const numericValue = this._fromType(values[i]) * scaling;\n this.linearRampToValueAtTime(this._toType(numericValue), startTime + i * segTime);\n }\n return this;\n }\n cancelScheduledValues(time) {\n const computedTime = this.toSeconds(time);\n Debug_assert(isFinite(computedTime), `Invalid argument to cancelScheduledValues: ${JSON.stringify(time)}`);\n this._events.cancel(computedTime);\n this._param.cancelScheduledValues(computedTime);\n this.log(this.units, "cancelScheduledValues", computedTime);\n return this;\n }\n cancelAndHoldAtTime(time) {\n const computedTime = this.toSeconds(time);\n const valueAtTime = this._fromType(this.getValueAtTime(computedTime));\n // remove the schedule events\n Debug_assert(isFinite(computedTime), `Invalid argument to cancelAndHoldAtTime: ${JSON.stringify(time)}`);\n this.log(this.units, "cancelAndHoldAtTime", computedTime, "value=" + valueAtTime);\n // if there is an event at the given computedTime\n // and that even is not a "set"\n const before = this._events.get(computedTime);\n const after = this._events.getAfter(computedTime);\n if (before && EQ(before.time, computedTime)) {\n // remove everything after\n if (after) {\n this._param.cancelScheduledValues(after.time);\n this._events.cancel(after.time);\n }\n else {\n this._param.cancelAndHoldAtTime(computedTime);\n this._events.cancel(computedTime + this.sampleTime);\n }\n }\n else if (after) {\n this._param.cancelScheduledValues(after.time);\n // cancel the next event(s)\n this._events.cancel(after.time);\n if (after.type === "linearRampToValueAtTime") {\n this.linearRampToValueAtTime(this._toType(valueAtTime), computedTime);\n }\n else if (after.type === "exponentialRampToValueAtTime") {\n this.exponentialRampToValueAtTime(this._toType(valueAtTime), computedTime);\n }\n }\n // set the value at the given time\n this._events.add({\n time: computedTime,\n type: "setValueAtTime",\n value: valueAtTime,\n });\n this._param.setValueAtTime(valueAtTime, computedTime);\n return this;\n }\n rampTo(value, rampTime = 0.1, startTime) {\n if (this.units === "frequency" || this.units === "bpm" || this.units === "decibels") {\n this.exponentialRampTo(value, rampTime, startTime);\n }\n else {\n this.linearRampTo(value, rampTime, startTime);\n }\n return this;\n }\n /**\n * Apply all of the previously scheduled events to the passed in Param or AudioParam.\n * The applied values will start at the context\'s current time and schedule\n * all of the events which are scheduled on this Param onto the passed in param.\n */\n apply(param) {\n const now = this.context.currentTime;\n // set the param\'s value at the current time and schedule everything else\n param.setValueAtTime(this.getValueAtTime(now), now);\n // if the previous event was a curve, then set the rest of it\n const previousEvent = this._events.get(now);\n if (previousEvent && previousEvent.type === "setTargetAtTime") {\n // approx it until the next event with linear ramps\n const nextEvent = this._events.getAfter(previousEvent.time);\n // or for 2 seconds if there is no event\n const endTime = nextEvent ? nextEvent.time : now + 2;\n const subdivisions = (endTime - now) / 10;\n for (let i = now; i < endTime; i += subdivisions) {\n param.linearRampToValueAtTime(this.getValueAtTime(i), i);\n }\n }\n this._events.forEachAfter(this.context.currentTime, event => {\n if (event.type === "cancelScheduledValues") {\n param.cancelScheduledValues(event.time);\n }\n else if (event.type === "setTargetAtTime") {\n param.setTargetAtTime(event.value, event.time, event.constant);\n }\n else {\n param[event.type](event.value, event.time);\n }\n });\n return this;\n }\n /**\n * Replace the Param\'s internal AudioParam. Will apply scheduled curves\n * onto the parameter and replace the connections.\n */\n setParam(param) {\n Debug_assert(this._swappable, "The Param must be assigned as \'swappable\' in the constructor");\n const input = this.input;\n input.disconnect(this._param);\n this.apply(param);\n this._param = param;\n input.connect(this._param);\n return this;\n }\n dispose() {\n super.dispose();\n this._events.dispose();\n return this;\n }\n get defaultValue() {\n return this._toType(this._param.defaultValue);\n }\n //-------------------------------------\n // \tAUTOMATION CURVE CALCULATIONS\n // \tMIT License, copyright (c) 2014 Jordan Santell\n //-------------------------------------\n // Calculates the the value along the curve produced by setTargetAtTime\n _exponentialApproach(t0, v0, v1, timeConstant, t) {\n return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n }\n // Calculates the the value along the curve produced by linearRampToValueAtTime\n _linearInterpolate(t0, v0, t1, v1, t) {\n return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n }\n // Calculates the the value along the curve produced by exponentialRampToValueAtTime\n _exponentialInterpolate(t0, v0, t1, v1, t) {\n return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n }\n}\n//# sourceMappingURL=Param.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioNode.js\n\n\n\n\n\n/**\n * ToneAudioNode is the base class for classes which process audio.\n */\nclass ToneAudioNode_ToneAudioNode extends ToneWithContext_ToneWithContext {\n constructor() {\n super(...arguments);\n /**\n * The name of the class\n */\n this.name = "ToneAudioNode";\n /**\n * List all of the node that must be set to match the ChannelProperties\n */\n this._internalChannels = [];\n }\n /**\n * The number of inputs feeding into the AudioNode.\n * For source nodes, this will be 0.\n * @example\n * const node = new Tone.Gain();\n * console.log(node.numberOfInputs);\n */\n get numberOfInputs() {\n if (TypeCheck_isDefined(this.input)) {\n if (isAudioParam(this.input) || this.input instanceof Param_Param) {\n return 1;\n }\n else {\n return this.input.numberOfInputs;\n }\n }\n else {\n return 0;\n }\n }\n /**\n * The number of outputs of the AudioNode.\n * @example\n * const node = new Tone.Gain();\n * console.log(node.numberOfOutputs);\n */\n get numberOfOutputs() {\n if (TypeCheck_isDefined(this.output)) {\n return this.output.numberOfOutputs;\n }\n else {\n return 0;\n }\n }\n //-------------------------------------\n // AUDIO PROPERTIES\n //-------------------------------------\n /**\n * Used to decide which nodes to get/set properties on\n */\n _isAudioNode(node) {\n return TypeCheck_isDefined(node) && (node instanceof ToneAudioNode_ToneAudioNode || AdvancedTypeCheck_isAudioNode(node));\n }\n /**\n * Get all of the audio nodes (either internal or input/output) which together\n * make up how the class node responds to channel input/output\n */\n _getInternalNodes() {\n const nodeList = this._internalChannels.slice(0);\n if (this._isAudioNode(this.input)) {\n nodeList.push(this.input);\n }\n if (this._isAudioNode(this.output)) {\n if (this.input !== this.output) {\n nodeList.push(this.output);\n }\n }\n return nodeList;\n }\n /**\n * Set the audio options for this node such as channelInterpretation\n * channelCount, etc.\n * @param options\n */\n _setChannelProperties(options) {\n const nodeList = this._getInternalNodes();\n nodeList.forEach(node => {\n node.channelCount = options.channelCount;\n node.channelCountMode = options.channelCountMode;\n node.channelInterpretation = options.channelInterpretation;\n });\n }\n /**\n * Get the current audio options for this node such as channelInterpretation\n * channelCount, etc.\n */\n _getChannelProperties() {\n const nodeList = this._getInternalNodes();\n Debug_assert(nodeList.length > 0, "ToneAudioNode does not have any internal nodes");\n // use the first node to get properties\n // they should all be the same\n const node = nodeList[0];\n return {\n channelCount: node.channelCount,\n channelCountMode: node.channelCountMode,\n channelInterpretation: node.channelInterpretation,\n };\n }\n /**\n * channelCount is the number of channels used when up-mixing and down-mixing\n * connections to any inputs to the node. The default value is 2 except for\n * specific nodes where its value is specially determined.\n */\n get channelCount() {\n return this._getChannelProperties().channelCount;\n }\n set channelCount(channelCount) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelCount }));\n }\n /**\n * channelCountMode determines how channels will be counted when up-mixing and\n * down-mixing connections to any inputs to the node.\n * The default value is "max". This attribute has no effect for nodes with no inputs.\n * * "max" - computedNumberOfChannels is the maximum of the number of channels of all connections to an input. In this mode channelCount is ignored.\n * * "clamped-max" - computedNumberOfChannels is determined as for "max" and then clamped to a maximum value of the given channelCount.\n * * "explicit" - computedNumberOfChannels is the exact value as specified by the channelCount.\n */\n get channelCountMode() {\n return this._getChannelProperties().channelCountMode;\n }\n set channelCountMode(channelCountMode) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelCountMode }));\n }\n /**\n * channelInterpretation determines how individual channels will be treated\n * when up-mixing and down-mixing connections to any inputs to the node.\n * The default value is "speakers".\n */\n get channelInterpretation() {\n return this._getChannelProperties().channelInterpretation;\n }\n set channelInterpretation(channelInterpretation) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelInterpretation }));\n }\n //-------------------------------------\n // CONNECTIONS\n //-------------------------------------\n /**\n * connect the output of a ToneAudioNode to an AudioParam, AudioNode, or ToneAudioNode\n * @param destination The output to connect to\n * @param outputNum The output to connect from\n * @param inputNum The input to connect to\n */\n connect(destination, outputNum = 0, inputNum = 0) {\n ToneAudioNode_connect(this, destination, outputNum, inputNum);\n return this;\n }\n /**\n * Connect the output to the context\'s destination node.\n * @example\n * const osc = new Tone.Oscillator("C2").start();\n * osc.toDestination();\n */\n toDestination() {\n this.connect(this.context.destination);\n return this;\n }\n /**\n * Connect the output to the context\'s destination node.\n * See [[toDestination]]\n * @deprecated\n */\n toMaster() {\n Debug_warn("toMaster() has been renamed toDestination()");\n return this.toDestination();\n }\n /**\n * disconnect the output\n */\n disconnect(destination, outputNum = 0, inputNum = 0) {\n ToneAudioNode_disconnect(this, destination, outputNum, inputNum);\n return this;\n }\n /**\n * Connect the output of this node to the rest of the nodes in series.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/handdrum-loop.mp3");\n * player.autostart = true;\n * const filter = new Tone.AutoFilter(4).start();\n * const distortion = new Tone.Distortion(0.5);\n * // connect the player to the filter, distortion and then to the master output\n * player.chain(filter, distortion, Tone.Destination);\n */\n chain(...nodes) {\n ToneAudioNode_connectSeries(this, ...nodes);\n return this;\n }\n /**\n * connect the output of this node to the rest of the nodes in parallel.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/conga-rhythm.mp3");\n * player.autostart = true;\n * const pitchShift = new Tone.PitchShift(4).toDestination();\n * const filter = new Tone.Filter("G5").toDestination();\n * // connect a node to the pitch shift and filter in parallel\n * player.fan(pitchShift, filter);\n */\n fan(...nodes) {\n nodes.forEach(node => this.connect(node));\n return this;\n }\n /**\n * Dispose and disconnect\n */\n dispose() {\n super.dispose();\n if (TypeCheck_isDefined(this.input)) {\n if (this.input instanceof ToneAudioNode_ToneAudioNode) {\n this.input.dispose();\n }\n else if (AdvancedTypeCheck_isAudioNode(this.input)) {\n this.input.disconnect();\n }\n }\n if (TypeCheck_isDefined(this.output)) {\n if (this.output instanceof ToneAudioNode_ToneAudioNode) {\n this.output.dispose();\n }\n else if (AdvancedTypeCheck_isAudioNode(this.output)) {\n this.output.disconnect();\n }\n }\n this._internalChannels = [];\n return this;\n }\n}\n//-------------------------------------\n// CONNECTIONS\n//-------------------------------------\n/**\n * connect together all of the arguments in series\n * @param nodes\n */\nfunction ToneAudioNode_connectSeries(...nodes) {\n const first = nodes.shift();\n nodes.reduce((prev, current) => {\n if (prev instanceof ToneAudioNode_ToneAudioNode) {\n prev.connect(current);\n }\n else if (AdvancedTypeCheck_isAudioNode(prev)) {\n ToneAudioNode_connect(prev, current);\n }\n return current;\n }, first);\n}\n/**\n * Connect two nodes together so that signal flows from the\n * first node to the second. Optionally specify the input and output channels.\n * @param srcNode The source node\n * @param dstNode The destination node\n * @param outputNumber The output channel of the srcNode\n * @param inputNumber The input channel of the dstNode\n */\nfunction ToneAudioNode_connect(srcNode, dstNode, outputNumber = 0, inputNumber = 0) {\n Debug_assert(TypeCheck_isDefined(srcNode), "Cannot connect from undefined node");\n Debug_assert(TypeCheck_isDefined(dstNode), "Cannot connect to undefined node");\n if (dstNode instanceof ToneAudioNode_ToneAudioNode || AdvancedTypeCheck_isAudioNode(dstNode)) {\n Debug_assert(dstNode.numberOfInputs > 0, "Cannot connect to node with no inputs");\n }\n Debug_assert(srcNode.numberOfOutputs > 0, "Cannot connect from node with no outputs");\n // resolve the input of the dstNode\n while ((dstNode instanceof ToneAudioNode_ToneAudioNode || dstNode instanceof Param_Param)) {\n if (TypeCheck_isDefined(dstNode.input)) {\n dstNode = dstNode.input;\n }\n }\n while (srcNode instanceof ToneAudioNode_ToneAudioNode) {\n if (TypeCheck_isDefined(srcNode.output)) {\n srcNode = srcNode.output;\n }\n }\n // make the connection\n if (isAudioParam(dstNode)) {\n srcNode.connect(dstNode, outputNumber);\n }\n else {\n srcNode.connect(dstNode, outputNumber, inputNumber);\n }\n}\n/**\n * Disconnect a node from all nodes or optionally include a destination node and input/output channels.\n * @param srcNode The source node\n * @param dstNode The destination node\n * @param outputNumber The output channel of the srcNode\n * @param inputNumber The input channel of the dstNode\n */\nfunction ToneAudioNode_disconnect(srcNode, dstNode, outputNumber = 0, inputNumber = 0) {\n // resolve the destination node\n if (TypeCheck_isDefined(dstNode)) {\n while (dstNode instanceof ToneAudioNode_ToneAudioNode) {\n dstNode = dstNode.input;\n }\n }\n // resolve the src node\n while (!(AdvancedTypeCheck_isAudioNode(srcNode))) {\n if (TypeCheck_isDefined(srcNode.output)) {\n srcNode = srcNode.output;\n }\n }\n if (isAudioParam(dstNode)) {\n srcNode.disconnect(dstNode, outputNumber);\n }\n else if (AdvancedTypeCheck_isAudioNode(dstNode)) {\n srcNode.disconnect(dstNode, outputNumber, inputNumber);\n }\n else {\n srcNode.disconnect();\n }\n}\n//# sourceMappingURL=ToneAudioNode.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Gain.js\n\n\n\n\n/**\n * A thin wrapper around the Native Web Audio GainNode.\n * The GainNode is a basic building block of the Web Audio\n * API and is useful for routing audio and adjusting gains.\n * @category Core\n * @example\n * return Tone.Offline(() => {\n * \tconst gainNode = new Tone.Gain(0).toDestination();\n * \tconst osc = new Tone.Oscillator(30).connect(gainNode).start();\n * \tgainNode.gain.rampTo(1, 0.1);\n * \tgainNode.gain.rampTo(0, 0.4, 0.2);\n * }, 0.7, 1);\n */\nclass Gain_Gain extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Gain_Gain.getDefaults(), arguments, ["gain", "units"]));\n this.name = "Gain";\n /**\n * The wrapped GainNode.\n */\n this._gainNode = this.context.createGain();\n // input = output\n this.input = this._gainNode;\n this.output = this._gainNode;\n const options = Defaults_optionsFromArguments(Gain_Gain.getDefaults(), arguments, ["gain", "units"]);\n this.gain = new Param_Param({\n context: this.context,\n convert: options.convert,\n param: this._gainNode.gain,\n units: options.units,\n value: options.gain,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n Interface_readOnly(this, "gain");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n convert: true,\n gain: 1,\n units: "gain",\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._gainNode.disconnect();\n this.gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Gain.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/OneShotSource.js\n\n\n\n\n/**\n * Base class for fire-and-forget nodes\n */\nclass OneShotSource extends ToneAudioNode_ToneAudioNode {\n constructor(options) {\n super(options);\n /**\n * The callback to invoke after the\n * source is done playing.\n */\n this.onended = Interface_noOp;\n /**\n * The start time\n */\n this._startTime = -1;\n /**\n * The stop time\n */\n this._stopTime = -1;\n /**\n * The id of the timeout\n */\n this._timeout = -1;\n /**\n * The public output node\n */\n this.output = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The output gain node.\n */\n this._gainNode = this.output;\n /**\n * Get the playback state at the given time\n */\n this.getStateAtTime = function (time) {\n const computedTime = this.toSeconds(time);\n if (this._startTime !== -1 &&\n computedTime >= this._startTime &&\n (this._stopTime === -1 || computedTime <= this._stopTime)) {\n return "started";\n }\n else {\n return "stopped";\n }\n };\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n this._curve = options.curve;\n this.onended = options.onended;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n curve: "linear",\n fadeIn: 0,\n fadeOut: 0,\n onended: Interface_noOp,\n });\n }\n /**\n * Start the source at the given time\n * @param time When to start the source\n */\n _startGain(time, gain = 1) {\n Debug_assert(this._startTime === -1, "Source cannot be started more than once");\n // apply a fade in envelope\n const fadeInTime = this.toSeconds(this._fadeIn);\n // record the start time\n this._startTime = time + fadeInTime;\n this._startTime = Math.max(this._startTime, this.context.currentTime);\n // schedule the envelope\n if (fadeInTime > 0) {\n this._gainNode.gain.setValueAtTime(0, time);\n if (this._curve === "linear") {\n this._gainNode.gain.linearRampToValueAtTime(gain, time + fadeInTime);\n }\n else {\n this._gainNode.gain.exponentialApproachValueAtTime(gain, time, fadeInTime);\n }\n }\n else {\n this._gainNode.gain.setValueAtTime(gain, time);\n }\n return this;\n }\n /**\n * Stop the source node at the given time.\n * @param time When to stop the source\n */\n stop(time) {\n this.log("stop", time);\n this._stopGain(this.toSeconds(time));\n return this;\n }\n /**\n * Stop the source at the given time\n * @param time When to stop the source\n */\n _stopGain(time) {\n Debug_assert(this._startTime !== -1, "\'start\' must be called before \'stop\'");\n // cancel the previous stop\n this.cancelStop();\n // the fadeOut time\n const fadeOutTime = this.toSeconds(this._fadeOut);\n // schedule the stop callback\n this._stopTime = this.toSeconds(time) + fadeOutTime;\n this._stopTime = Math.max(this._stopTime, this.context.currentTime);\n if (fadeOutTime > 0) {\n // start the fade out curve at the given time\n if (this._curve === "linear") {\n this._gainNode.gain.linearRampTo(0, fadeOutTime, time);\n }\n else {\n this._gainNode.gain.targetRampTo(0, fadeOutTime, time);\n }\n }\n else {\n // stop any ongoing ramps, and set the value to 0\n this._gainNode.gain.cancelAndHoldAtTime(time);\n this._gainNode.gain.setValueAtTime(0, time);\n }\n this.context.clearTimeout(this._timeout);\n this._timeout = this.context.setTimeout(() => {\n // allow additional time for the exponential curve to fully decay\n const additionalTail = this._curve === "exponential" ? fadeOutTime * 2 : 0;\n this._stopSource(this.now() + additionalTail);\n this._onended();\n }, this._stopTime - this.context.currentTime);\n return this;\n }\n /**\n * Invoke the onended callback\n */\n _onended() {\n if (this.onended !== Interface_noOp) {\n this.onended(this);\n // overwrite onended to make sure it only is called once\n this.onended = Interface_noOp;\n // dispose when it\'s ended to free up for garbage collection only in the online context\n if (!this.context.isOffline) {\n const disposeCallback = () => this.dispose();\n // @ts-ignore\n if (typeof window.requestIdleCallback !== "undefined") {\n // @ts-ignore\n window.requestIdleCallback(disposeCallback);\n }\n else {\n setTimeout(disposeCallback, 1000);\n }\n }\n }\n }\n /**\n * Get the playback state at the current time\n */\n get state() {\n return this.getStateAtTime(this.now());\n }\n /**\n * Cancel a scheduled stop event\n */\n cancelStop() {\n this.log("cancelStop");\n Debug_assert(this._startTime !== -1, "Source is not started");\n // cancel the stop envelope\n this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime);\n this.context.clearTimeout(this._timeout);\n this._stopTime = -1;\n return this;\n }\n dispose() {\n super.dispose();\n this._gainNode.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=OneShotSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/ToneConstantSource.js\n\n\n\n\n/**\n * Wrapper around the native fire-and-forget ConstantSource.\n * Adds the ability to reschedule the stop method.\n * @category Signal\n */\nclass ToneConstantSource_ToneConstantSource extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneConstantSource_ToneConstantSource.getDefaults(), arguments, ["offset"]));\n this.name = "ToneConstantSource";\n /**\n * The signal generator\n */\n this._source = this.context.createConstantSource();\n const options = Defaults_optionsFromArguments(ToneConstantSource_ToneConstantSource.getDefaults(), arguments, ["offset"]);\n ToneAudioNode_connect(this._source, this._gainNode);\n this.offset = new Param_Param({\n context: this.context,\n convert: options.convert,\n param: this._source.offset,\n units: options.units,\n value: options.offset,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n convert: true,\n offset: 1,\n units: "number",\n });\n }\n /**\n * Start the source node at the given time\n * @param time When to start the source\n */\n start(time) {\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n this._startGain(computedTime);\n this._source.start(computedTime);\n return this;\n }\n _stopSource(time) {\n this._source.stop(time);\n }\n dispose() {\n super.dispose();\n if (this.state === "started") {\n this.stop();\n }\n this._source.disconnect();\n this.offset.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneConstantSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Signal.js\n\n\n\n\n\n\n/**\n * A signal is an audio-rate value. Tone.Signal is a core component of the library.\n * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n * has all of the methods available to native Web Audio\n * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n * as well as additional conveniences. Read more about working with signals\n * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // a scheduleable signal which can be connected to control an AudioParam or another Signal\n * const signal = new Tone.Signal({\n * \tvalue: "C4",\n * \tunits: "frequency"\n * }).connect(osc.frequency);\n * // the scheduled ramp controls the connected signal\n * signal.rampTo("C2", 4, "+0.5");\n * @category Signal\n */\nclass Signal_Signal extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Signal_Signal.getDefaults(), arguments, ["value", "units"]));\n this.name = "Signal";\n /**\n * Indicates if the value should be overridden on connection.\n */\n this.override = true;\n const options = Defaults_optionsFromArguments(Signal_Signal.getDefaults(), arguments, ["value", "units"]);\n this.output = this._constantSource = new ToneConstantSource_ToneConstantSource({\n context: this.context,\n convert: options.convert,\n offset: options.value,\n units: options.units,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n this._constantSource.start(0);\n this.input = this._param = this._constantSource.offset;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n convert: true,\n units: "number",\n value: 0,\n });\n }\n connect(destination, outputNum = 0, inputNum = 0) {\n // start it only when connected to something\n Signal_connectSignal(this, destination, outputNum, inputNum);\n return this;\n }\n dispose() {\n super.dispose();\n this._param.dispose();\n this._constantSource.dispose();\n return this;\n }\n //-------------------------------------\n // ABSTRACT PARAM INTERFACE\n // just a proxy for the ConstantSourceNode\'s offset AudioParam\n // all docs are generated from AbstractParam.ts\n //-------------------------------------\n setValueAtTime(value, time) {\n this._param.setValueAtTime(value, time);\n return this;\n }\n getValueAtTime(time) {\n return this._param.getValueAtTime(time);\n }\n setRampPoint(time) {\n this._param.setRampPoint(time);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n this._param.linearRampToValueAtTime(value, time);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n this._param.exponentialRampToValueAtTime(value, time);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n this._param.exponentialRampTo(value, rampTime, startTime);\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n this._param.linearRampTo(value, rampTime, startTime);\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n this._param.targetRampTo(value, rampTime, startTime);\n return this;\n }\n exponentialApproachValueAtTime(value, time, rampTime) {\n this._param.exponentialApproachValueAtTime(value, time, rampTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n this._param.setTargetAtTime(value, startTime, timeConstant);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling) {\n this._param.setValueCurveAtTime(values, startTime, duration, scaling);\n return this;\n }\n cancelScheduledValues(time) {\n this._param.cancelScheduledValues(time);\n return this;\n }\n cancelAndHoldAtTime(time) {\n this._param.cancelAndHoldAtTime(time);\n return this;\n }\n rampTo(value, rampTime, startTime) {\n this._param.rampTo(value, rampTime, startTime);\n return this;\n }\n get value() {\n return this._param.value;\n }\n set value(value) {\n this._param.value = value;\n }\n get convert() {\n return this._param.convert;\n }\n set convert(convert) {\n this._param.convert = convert;\n }\n get units() {\n return this._param.units;\n }\n get overridden() {\n return this._param.overridden;\n }\n set overridden(overridden) {\n this._param.overridden = overridden;\n }\n get maxValue() {\n return this._param.maxValue;\n }\n get minValue() {\n return this._param.minValue;\n }\n /**\n * See [[Param.apply]].\n */\n apply(param) {\n this._param.apply(param);\n return this;\n }\n}\n/**\n * When connecting from a signal, it\'s necessary to zero out the node destination\n * node if that node is also a signal. If the destination is not 0, then the values\n * will be summed. This method insures that the output of the destination signal will\n * be the same as the source signal, making the destination signal a pass through node.\n * @param signal The output signal to connect from\n * @param destination the destination to connect to\n * @param outputNum the optional output number\n * @param inputNum the input number\n */\nfunction Signal_connectSignal(signal, destination, outputNum, inputNum) {\n if (destination instanceof Param_Param || isAudioParam(destination) ||\n (destination instanceof Signal_Signal && destination.override)) {\n // cancel changes\n destination.cancelScheduledValues(0);\n // reset the value\n destination.setValueAtTime(0, 0);\n // mark the value as overridden\n if (destination instanceof Signal_Signal) {\n destination.overridden = true;\n }\n }\n ToneAudioNode_connect(signal, destination, outputNum, inputNum);\n}\n//# sourceMappingURL=Signal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickParam.js\n\n\n\n\n/**\n * A Param class just for computing ticks. Similar to the [[Param]] class,\n * but offers conversion to BPM values as well as ability to compute tick\n * duration and elapsed ticks\n */\nclass TickParam extends Param_Param {\n constructor() {\n super(Defaults_optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]));\n this.name = "TickParam";\n /**\n * The timeline which tracks all of the automations.\n */\n this._events = new Timeline(Infinity);\n /**\n * The internal holder for the multiplier value\n */\n this._multiplier = 1;\n const options = Defaults_optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]);\n // set the multiplier\n this._multiplier = options.multiplier;\n // clear the ticks from the beginning\n this._events.cancel(0);\n // set an initial event\n this._events.add({\n ticks: 0,\n time: 0,\n type: "setValueAtTime",\n value: this._fromType(options.value),\n });\n this.setValueAtTime(options.value, 0);\n }\n static getDefaults() {\n return Object.assign(Param_Param.getDefaults(), {\n multiplier: 1,\n units: "hertz",\n value: 1,\n });\n }\n setTargetAtTime(value, time, constant) {\n // approximate it with multiple linear ramps\n time = this.toSeconds(time);\n this.setRampPoint(time);\n const computedValue = this._fromType(value);\n // start from previously scheduled value\n const prevEvent = this._events.get(time);\n const segments = Math.round(Math.max(1 / constant, 1));\n for (let i = 0; i <= segments; i++) {\n const segTime = constant * i + time;\n const rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, computedValue, constant, segTime);\n this.linearRampToValueAtTime(this._toType(rampVal), segTime);\n }\n return this;\n }\n setValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n super.setValueAtTime(value, time);\n const event = this._events.get(computedTime);\n const previousEvent = this._events.previousEvent(event);\n const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime);\n event.ticks = Math.max(ticksUntilTime, 0);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n super.linearRampToValueAtTime(value, time);\n const event = this._events.get(computedTime);\n const previousEvent = this._events.previousEvent(event);\n const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime);\n event.ticks = Math.max(ticksUntilTime, 0);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n // aproximate it with multiple linear ramps\n time = this.toSeconds(time);\n const computedVal = this._fromType(value);\n // start from previously scheduled value\n const prevEvent = this._events.get(time);\n // approx 10 segments per second\n const segments = Math.round(Math.max((time - prevEvent.time) * 10, 1));\n const segmentDur = ((time - prevEvent.time) / segments);\n for (let i = 0; i <= segments; i++) {\n const segTime = segmentDur * i + prevEvent.time;\n const rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, computedVal, segTime);\n this.linearRampToValueAtTime(this._toType(rampVal), segTime);\n }\n return this;\n }\n /**\n * Returns the tick value at the time. Takes into account\n * any automation curves scheduled on the signal.\n * @param event The time to get the tick count at\n * @return The number of ticks which have elapsed at the time given any automations.\n */\n _getTicksUntilEvent(event, time) {\n if (event === null) {\n event = {\n ticks: 0,\n time: 0,\n type: "setValueAtTime",\n value: 0,\n };\n }\n else if (TypeCheck_isUndef(event.ticks)) {\n const previousEvent = this._events.previousEvent(event);\n event.ticks = this._getTicksUntilEvent(previousEvent, event.time);\n }\n const val0 = this._fromType(this.getValueAtTime(event.time));\n let val1 = this._fromType(this.getValueAtTime(time));\n // if it\'s right on the line, take the previous value\n const onTheLineEvent = this._events.get(time);\n if (onTheLineEvent && onTheLineEvent.time === time && onTheLineEvent.type === "setValueAtTime") {\n val1 = this._fromType(this.getValueAtTime(time - this.sampleTime));\n }\n return 0.5 * (time - event.time) * (val0 + val1) + event.ticks;\n }\n /**\n * Returns the tick value at the time. Takes into account\n * any automation curves scheduled on the signal.\n * @param time The time to get the tick count at\n * @return The number of ticks which have elapsed at the time given any automations.\n */\n getTicksAtTime(time) {\n const computedTime = this.toSeconds(time);\n const event = this._events.get(computedTime);\n return Math.max(this._getTicksUntilEvent(event, computedTime), 0);\n }\n /**\n * Return the elapsed time of the number of ticks from the given time\n * @param ticks The number of ticks to calculate\n * @param time The time to get the next tick from\n * @return The duration of the number of ticks from the given time in seconds\n */\n getDurationOfTicks(ticks, time) {\n const computedTime = this.toSeconds(time);\n const currentTick = this.getTicksAtTime(time);\n return this.getTimeOfTick(currentTick + ticks) - computedTime;\n }\n /**\n * Given a tick, returns the time that tick occurs at.\n * @return The time that the tick occurs.\n */\n getTimeOfTick(tick) {\n const before = this._events.get(tick, "ticks");\n const after = this._events.getAfter(tick, "ticks");\n if (before && before.ticks === tick) {\n return before.time;\n }\n else if (before && after &&\n after.type === "linearRampToValueAtTime" &&\n before.value !== after.value) {\n const val0 = this._fromType(this.getValueAtTime(before.time));\n const val1 = this._fromType(this.getValueAtTime(after.time));\n const delta = (val1 - val0) / (after.time - before.time);\n const k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick));\n const sol1 = (-val0 + k) / delta;\n const sol2 = (-val0 - k) / delta;\n return (sol1 > 0 ? sol1 : sol2) + before.time;\n }\n else if (before) {\n if (before.value === 0) {\n return Infinity;\n }\n else {\n return before.time + (tick - before.ticks) / before.value;\n }\n }\n else {\n return tick / this._initialValue;\n }\n }\n /**\n * Convert some number of ticks their the duration in seconds accounting\n * for any automation curves starting at the given time.\n * @param ticks The number of ticks to convert to seconds.\n * @param when When along the automation timeline to convert the ticks.\n * @return The duration in seconds of the ticks.\n */\n ticksToTime(ticks, when) {\n return this.getDurationOfTicks(ticks, when);\n }\n /**\n * The inverse of [[ticksToTime]]. Convert a duration in\n * seconds to the corresponding number of ticks accounting for any\n * automation curves starting at the given time.\n * @param duration The time interval to convert to ticks.\n * @param when When along the automation timeline to convert the ticks.\n * @return The duration in ticks.\n */\n timeToTicks(duration, when) {\n const computedTime = this.toSeconds(when);\n const computedDuration = this.toSeconds(duration);\n const startTicks = this.getTicksAtTime(computedTime);\n const endTicks = this.getTicksAtTime(computedTime + computedDuration);\n return endTicks - startTicks;\n }\n /**\n * Convert from the type when the unit value is BPM\n */\n _fromType(val) {\n if (this.units === "bpm" && this.multiplier) {\n return 1 / (60 / val / this.multiplier);\n }\n else {\n return super._fromType(val);\n }\n }\n /**\n * Special case of type conversion where the units === "bpm"\n */\n _toType(val) {\n if (this.units === "bpm" && this.multiplier) {\n return (val / this.multiplier) * 60;\n }\n else {\n return super._toType(val);\n }\n }\n /**\n * A multiplier on the bpm value. Useful for setting a PPQ relative to the base frequency value.\n */\n get multiplier() {\n return this._multiplier;\n }\n set multiplier(m) {\n // get and reset the current value with the new multiplier\n // might be necessary to clear all the previous values\n const currentVal = this.value;\n this._multiplier = m;\n this.cancelScheduledValues(0);\n this.setValueAtTime(currentVal, 0);\n }\n}\n//# sourceMappingURL=TickParam.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickSignal.js\n\n\n\n/**\n * TickSignal extends Tone.Signal, but adds the capability\n * to calculate the number of elapsed ticks. exponential and target curves\n * are approximated with multiple linear ramps.\n *\n * Thank you Bruno Dias, H. Sofia Pinto, and David M. Matos,\n * for your [WAC paper](https://smartech.gatech.edu/bitstream/handle/1853/54588/WAC2016-49.pdf)\n * describing integrating timing functions for tempo calculations.\n */\nclass TickSignal extends Signal_Signal {\n constructor() {\n super(Defaults_optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]));\n this.name = "TickSignal";\n const options = Defaults_optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]);\n this.input = this._param = new TickParam({\n context: this.context,\n convert: options.convert,\n multiplier: options.multiplier,\n param: this._constantSource.offset,\n units: options.units,\n value: options.value,\n });\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n multiplier: 1,\n units: "hertz",\n value: 1,\n });\n }\n ticksToTime(ticks, when) {\n return this._param.ticksToTime(ticks, when);\n }\n timeToTicks(duration, when) {\n return this._param.timeToTicks(duration, when);\n }\n getTimeOfTick(tick) {\n return this._param.getTimeOfTick(tick);\n }\n getDurationOfTicks(ticks, time) {\n return this._param.getDurationOfTicks(ticks, time);\n }\n getTicksAtTime(time) {\n return this._param.getTicksAtTime(time);\n }\n /**\n * A multiplier on the bpm value. Useful for setting a PPQ relative to the base frequency value.\n */\n get multiplier() {\n return this._param.multiplier;\n }\n set multiplier(m) {\n this._param.multiplier = m;\n }\n dispose() {\n super.dispose();\n this._param.dispose();\n return this;\n }\n}\n//# sourceMappingURL=TickSignal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickSource.js\n\n\n\n\n\n\n\n\n/**\n * Uses [TickSignal](TickSignal) to track elapsed ticks with complex automation curves.\n */\nclass TickSource extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]));\n this.name = "TickSource";\n /**\n * The state timeline\n */\n this._state = new StateTimeline_StateTimeline();\n /**\n * The offset values of the ticks\n */\n this._tickOffset = new Timeline();\n const options = Defaults_optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]);\n this.frequency = new TickSignal({\n context: this.context,\n units: options.units,\n value: options.frequency,\n });\n Interface_readOnly(this, "frequency");\n // set the initial state\n this._state.setStateAtTime("stopped", 0);\n // add the first event\n this.setTicksAtTime(0, 0);\n }\n static getDefaults() {\n return Object.assign({\n frequency: 1,\n units: "hertz",\n }, ToneWithContext_ToneWithContext.getDefaults());\n }\n /**\n * Returns the playback state of the source, either "started", "stopped" or "paused".\n */\n get state() {\n return this.getStateAtTime(this.now());\n }\n /**\n * Start the clock at the given time. Optionally pass in an offset\n * of where to start the tick counter from.\n * @param time The time the clock should start\n * @param offset The number of ticks to start the source at\n */\n start(time, offset) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) !== "started") {\n this._state.setStateAtTime("started", computedTime);\n if (TypeCheck_isDefined(offset)) {\n this.setTicksAtTime(offset, computedTime);\n }\n }\n return this;\n }\n /**\n * Stop the clock. Stopping the clock resets the tick counter to 0.\n * @param time The time when the clock should stop.\n */\n stop(time) {\n const computedTime = this.toSeconds(time);\n // cancel the previous stop\n if (this._state.getValueAtTime(computedTime) === "stopped") {\n const event = this._state.get(computedTime);\n if (event && event.time > 0) {\n this._tickOffset.cancel(event.time);\n this._state.cancel(event.time);\n }\n }\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n this.setTicksAtTime(0, computedTime);\n return this;\n }\n /**\n * Pause the clock. Pausing does not reset the tick counter.\n * @param time The time when the clock should stop.\n */\n pause(time) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) === "started") {\n this._state.setStateAtTime("paused", computedTime);\n }\n return this;\n }\n /**\n * Cancel start/stop/pause and setTickAtTime events scheduled after the given time.\n * @param time When to clear the events after\n */\n cancel(time) {\n time = this.toSeconds(time);\n this._state.cancel(time);\n this._tickOffset.cancel(time);\n return this;\n }\n /**\n * Get the elapsed ticks at the given time\n * @param time When to get the tick value\n * @return The number of ticks\n */\n getTicksAtTime(time) {\n const computedTime = this.toSeconds(time);\n const stopEvent = this._state.getLastState("stopped", computedTime);\n // this event allows forEachBetween to iterate until the current time\n const tmpEvent = { state: "paused", time: computedTime };\n this._state.add(tmpEvent);\n // keep track of the previous offset event\n let lastState = stopEvent;\n let elapsedTicks = 0;\n // iterate through all the events since the last stop\n this._state.forEachBetween(stopEvent.time, computedTime + this.sampleTime, e => {\n let periodStartTime = lastState.time;\n // if there is an offset event in this period use that\n const offsetEvent = this._tickOffset.get(e.time);\n if (offsetEvent && offsetEvent.time >= lastState.time) {\n elapsedTicks = offsetEvent.ticks;\n periodStartTime = offsetEvent.time;\n }\n if (lastState.state === "started" && e.state !== "started") {\n elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime);\n }\n lastState = e;\n });\n // remove the temporary event\n this._state.remove(tmpEvent);\n // return the ticks\n return elapsedTicks;\n }\n /**\n * The number of times the callback was invoked. Starts counting at 0\n * and increments after the callback was invoked. Returns -1 when stopped.\n */\n get ticks() {\n return this.getTicksAtTime(this.now());\n }\n set ticks(t) {\n this.setTicksAtTime(t, this.now());\n }\n /**\n * The time since ticks=0 that the TickSource has been running. Accounts\n * for tempo curves\n */\n get seconds() {\n return this.getSecondsAtTime(this.now());\n }\n set seconds(s) {\n const now = this.now();\n const ticks = this.frequency.timeToTicks(s, now);\n this.setTicksAtTime(ticks, now);\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n time = this.toSeconds(time);\n const stopEvent = this._state.getLastState("stopped", time);\n // this event allows forEachBetween to iterate until the current time\n const tmpEvent = { state: "paused", time };\n this._state.add(tmpEvent);\n // keep track of the previous offset event\n let lastState = stopEvent;\n let elapsedSeconds = 0;\n // iterate through all the events since the last stop\n this._state.forEachBetween(stopEvent.time, time + this.sampleTime, e => {\n let periodStartTime = lastState.time;\n // if there is an offset event in this period use that\n const offsetEvent = this._tickOffset.get(e.time);\n if (offsetEvent && offsetEvent.time >= lastState.time) {\n elapsedSeconds = offsetEvent.seconds;\n periodStartTime = offsetEvent.time;\n }\n if (lastState.state === "started" && e.state !== "started") {\n elapsedSeconds += e.time - periodStartTime;\n }\n lastState = e;\n });\n // remove the temporary event\n this._state.remove(tmpEvent);\n // return the ticks\n return elapsedSeconds;\n }\n /**\n * Set the clock\'s ticks at the given time.\n * @param ticks The tick value to set\n * @param time When to set the tick value\n */\n setTicksAtTime(ticks, time) {\n time = this.toSeconds(time);\n this._tickOffset.cancel(time);\n this._tickOffset.add({\n seconds: this.frequency.getDurationOfTicks(ticks, time),\n ticks,\n time,\n });\n return this;\n }\n /**\n * Returns the scheduled state at the given time.\n * @param time The time to query.\n */\n getStateAtTime(time) {\n time = this.toSeconds(time);\n return this._state.getValueAtTime(time);\n }\n /**\n * Get the time of the given tick. The second argument\n * is when to test before. Since ticks can be set (with setTicksAtTime)\n * there may be multiple times for a given tick value.\n * @param tick The tick number.\n * @param before When to measure the tick value from.\n * @return The time of the tick\n */\n getTimeOfTick(tick, before = this.now()) {\n const offset = this._tickOffset.get(before);\n const event = this._state.get(before);\n const startTime = Math.max(offset.time, event.time);\n const absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks;\n return this.frequency.getTimeOfTick(absoluteTicks);\n }\n /**\n * Invoke the callback event at all scheduled ticks between the\n * start time and the end time\n * @param startTime The beginning of the search range\n * @param endTime The end of the search range\n * @param callback The callback to invoke with each tick\n */\n forEachTickBetween(startTime, endTime, callback) {\n // only iterate through the sections where it is "started"\n let lastStateEvent = this._state.get(startTime);\n this._state.forEachBetween(startTime, endTime, event => {\n if (lastStateEvent && lastStateEvent.state === "started" && event.state !== "started") {\n this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback);\n }\n lastStateEvent = event;\n });\n let error = null;\n if (lastStateEvent && lastStateEvent.state === "started") {\n const maxStartTime = Math.max(lastStateEvent.time, startTime);\n // figure out the difference between the frequency ticks and the\n const startTicks = this.frequency.getTicksAtTime(maxStartTime);\n const ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time);\n const diff = startTicks - ticksAtStart;\n let offset = Math.ceil(diff) - diff;\n // guard against floating point issues\n offset = EQ(offset, 1) ? 0 : offset;\n let nextTickTime = this.frequency.getTimeOfTick(startTicks + offset);\n while (nextTickTime < endTime) {\n try {\n callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime)));\n }\n catch (e) {\n error = e;\n break;\n }\n nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime);\n }\n }\n if (error) {\n throw error;\n }\n return this;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._state.dispose();\n this._tickOffset.dispose();\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=TickSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Clock.js\n\n\n\n\n\n\n\n/**\n * A sample accurate clock which provides a callback at the given rate.\n * While the callback is not sample-accurate (it is still susceptible to\n * loose JS timing), the time passed in as the argument to the callback\n * is precise. For most applications, it is better to use Tone.Transport\n * instead of the Clock by itself since you can synchronize multiple callbacks.\n * @example\n * // the callback will be invoked approximately once a second\n * // and will print the time exactly once a second apart.\n * const clock = new Tone.Clock(time => {\n * \tconsole.log(time);\n * }, 1);\n * clock.start();\n * @category Core\n */\nclass Clock_Clock extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Clock_Clock.getDefaults(), arguments, ["callback", "frequency"]));\n this.name = "Clock";\n /**\n * The callback function to invoke at the scheduled tick.\n */\n this.callback = Interface_noOp;\n /**\n * The last time the loop callback was invoked\n */\n this._lastUpdate = 0;\n /**\n * Keep track of the playback state\n */\n this._state = new StateTimeline_StateTimeline("stopped");\n /**\n * Context bound reference to the _loop method\n * This is necessary to remove the event in the end.\n */\n this._boundLoop = this._loop.bind(this);\n const options = Defaults_optionsFromArguments(Clock_Clock.getDefaults(), arguments, ["callback", "frequency"]);\n this.callback = options.callback;\n this._tickSource = new TickSource({\n context: this.context,\n frequency: options.frequency,\n units: options.units,\n });\n this._lastUpdate = 0;\n this.frequency = this._tickSource.frequency;\n Interface_readOnly(this, "frequency");\n // add an initial state\n this._state.setStateAtTime("stopped", 0);\n // bind a callback to the worker thread\n this.context.on("tick", this._boundLoop);\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n callback: Interface_noOp,\n frequency: 1,\n units: "hertz",\n });\n }\n /**\n * Returns the playback state of the source, either "started", "stopped" or "paused".\n */\n get state() {\n return this._state.getValueAtTime(this.now());\n }\n /**\n * Start the clock at the given time. Optionally pass in an offset\n * of where to start the tick counter from.\n * @param time The time the clock should start\n * @param offset Where the tick counter starts counting from.\n */\n start(time, offset) {\n // make sure the context is running\n assertContextRunning(this.context);\n // start the loop\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n if (this._state.getValueAtTime(computedTime) !== "started") {\n this._state.setStateAtTime("started", computedTime);\n this._tickSource.start(computedTime, offset);\n if (computedTime < this._lastUpdate) {\n this.emit("start", computedTime, offset);\n }\n }\n return this;\n }\n /**\n * Stop the clock. Stopping the clock resets the tick counter to 0.\n * @param time The time when the clock should stop.\n * @example\n * const clock = new Tone.Clock(time => {\n * \tconsole.log(time);\n * }, 1);\n * clock.start();\n * // stop the clock after 10 seconds\n * clock.stop("+10");\n */\n stop(time) {\n const computedTime = this.toSeconds(time);\n this.log("stop", computedTime);\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n this._tickSource.stop(computedTime);\n if (computedTime < this._lastUpdate) {\n this.emit("stop", computedTime);\n }\n return this;\n }\n /**\n * Pause the clock. Pausing does not reset the tick counter.\n * @param time The time when the clock should stop.\n */\n pause(time) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) === "started") {\n this._state.setStateAtTime("paused", computedTime);\n this._tickSource.pause(computedTime);\n if (computedTime < this._lastUpdate) {\n this.emit("pause", computedTime);\n }\n }\n return this;\n }\n /**\n * The number of times the callback was invoked. Starts counting at 0\n * and increments after the callback was invoked.\n */\n get ticks() {\n return Math.ceil(this.getTicksAtTime(this.now()));\n }\n set ticks(t) {\n this._tickSource.ticks = t;\n }\n /**\n * The time since ticks=0 that the Clock has been running. Accounts for tempo curves\n */\n get seconds() {\n return this._tickSource.seconds;\n }\n set seconds(s) {\n this._tickSource.seconds = s;\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n return this._tickSource.getSecondsAtTime(time);\n }\n /**\n * Set the clock\'s ticks at the given time.\n * @param ticks The tick value to set\n * @param time When to set the tick value\n */\n setTicksAtTime(ticks, time) {\n this._tickSource.setTicksAtTime(ticks, time);\n return this;\n }\n /**\n * Get the time of the given tick. The second argument\n * is when to test before. Since ticks can be set (with setTicksAtTime)\n * there may be multiple times for a given tick value.\n * @param tick The tick number.\n * @param before When to measure the tick value from.\n * @return The time of the tick\n */\n getTimeOfTick(tick, before = this.now()) {\n return this._tickSource.getTimeOfTick(tick, before);\n }\n /**\n * Get the clock\'s ticks at the given time.\n * @param time When to get the tick value\n * @return The tick value at the given time.\n */\n getTicksAtTime(time) {\n return this._tickSource.getTicksAtTime(time);\n }\n /**\n * Get the time of the next tick\n * @param offset The tick number.\n */\n nextTickTime(offset, when) {\n const computedTime = this.toSeconds(when);\n const currentTick = this.getTicksAtTime(computedTime);\n return this._tickSource.getTimeOfTick(currentTick + offset, computedTime);\n }\n /**\n * The scheduling loop.\n */\n _loop() {\n const startTime = this._lastUpdate;\n const endTime = this.now();\n this._lastUpdate = endTime;\n this.log("loop", startTime, endTime);\n if (startTime !== endTime) {\n // the state change events\n this._state.forEachBetween(startTime, endTime, e => {\n switch (e.state) {\n case "started":\n const offset = this._tickSource.getTicksAtTime(e.time);\n this.emit("start", e.time, offset);\n break;\n case "stopped":\n if (e.time !== 0) {\n this.emit("stop", e.time);\n }\n break;\n case "paused":\n this.emit("pause", e.time);\n break;\n }\n });\n // the tick callbacks\n this._tickSource.forEachTickBetween(startTime, endTime, (time, ticks) => {\n this.callback(time, ticks);\n });\n }\n }\n /**\n * Returns the scheduled state at the given time.\n * @param time The time to query.\n * @return The name of the state input in setStateAtTime.\n * @example\n * const clock = new Tone.Clock();\n * clock.start("+0.1");\n * clock.getStateAtTime("+0.1"); // returns "started"\n */\n getStateAtTime(time) {\n const computedTime = this.toSeconds(time);\n return this._state.getValueAtTime(computedTime);\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.context.off("tick", this._boundLoop);\n this._tickSource.dispose();\n this._state.dispose();\n return this;\n }\n}\nEmitter.mixin(Clock_Clock);\n//# sourceMappingURL=Clock.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Delay.js\n\n\n\n\n/**\n * Wrapper around Web Audio\'s native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface).\n * @category Core\n * @example\n * return Tone.Offline(() => {\n * \tconst delay = new Tone.Delay(0.1).toDestination();\n * \t// connect the signal to both the delay and the destination\n * \tconst pulse = new Tone.PulseOscillator().connect(delay).toDestination();\n * \t// start and stop the pulse\n * \tpulse.start(0).stop(0.01);\n * }, 0.5, 1);\n */\nclass Delay_Delay extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Delay_Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]));\n this.name = "Delay";\n const options = optionsFromArguments(Delay_Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]);\n const maxDelayInSeconds = this.toSeconds(options.maxDelay);\n this._maxDelay = Math.max(maxDelayInSeconds, this.toSeconds(options.delayTime));\n this._delayNode = this.input = this.output = this.context.createDelay(maxDelayInSeconds);\n this.delayTime = new Param({\n context: this.context,\n param: this._delayNode.delayTime,\n units: "time",\n value: options.delayTime,\n minValue: 0,\n maxValue: this.maxDelay,\n });\n readOnly(this, "delayTime");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n delayTime: 0,\n maxDelay: 1,\n });\n }\n /**\n * The maximum delay time. This cannot be changed after\n * the value is passed into the constructor.\n */\n get maxDelay() {\n return this._maxDelay;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._delayNode.disconnect();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Delay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Offline.js\n\n\n\n\n/**\n * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext.\n * The OfflineAudioContext is capable of rendering much faster than real time in many cases.\n * The callback function also passes in an offline instance of [[Context]] which can be used\n * to schedule events along the Transport.\n * @param callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer.\n * @param duration the amount of time to record for.\n * @return The promise which is invoked with the ToneAudioBuffer of the recorded output.\n * @example\n * // render 2 seconds of the oscillator\n * Tone.Offline(() => {\n * \t// only nodes created in this callback will be recorded\n * \tconst oscillator = new Tone.Oscillator().toDestination().start(0);\n * }, 2).then((buffer) => {\n * \t// do something with the output buffer\n * \tconsole.log(buffer);\n * });\n * @example\n * // can also schedule events along the Transport\n * // using the passed in Offline Transport\n * Tone.Offline(({ transport }) => {\n * \tconst osc = new Tone.Oscillator().toDestination();\n * \ttransport.schedule(time => {\n * \t\tosc.start(time).stop(time + 0.1);\n * \t}, 1);\n * \t// make sure to start the transport\n * \ttransport.start(0.2);\n * }, 4).then((buffer) => {\n * \t// do something with the output buffer\n * \tconsole.log(buffer);\n * });\n * @category Core\n */\nfunction Offline(callback, duration, channels = 2, sampleRate = getContext().sampleRate) {\n return __awaiter(this, void 0, void 0, function* () {\n // set the OfflineAudioContext based on the current context\n const originalContext = getContext();\n const context = new OfflineContext(channels, duration, sampleRate);\n setContext(context);\n // invoke the callback/scheduling\n yield callback(context);\n // then render the audio\n const bufferPromise = context.render();\n // return the original AudioContext\n setContext(originalContext);\n // await the rendering\n const buffer = yield bufferPromise;\n // return the audio\n return new ToneAudioBuffer(buffer);\n });\n}\n//# sourceMappingURL=Offline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioBuffers.js\n\n\n\n\n\n\n/**\n * A data structure for holding multiple buffers in a Map-like datastructure.\n *\n * @example\n * const pianoSamples = new Tone.ToneAudioBuffers({\n * \tA1: "https://tonejs.github.io/audio/casio/A1.mp3",\n * \tA2: "https://tonejs.github.io/audio/casio/A2.mp3",\n * }, () => {\n * \tconst player = new Tone.Player().toDestination();\n * \t// play one of the samples when they all load\n * \tplayer.buffer = pianoSamples.get("A2");\n * \tplayer.start();\n * });\n * @example\n * // To pass in additional parameters in the second parameter\n * const buffers = new Tone.ToneAudioBuffers({\n * \t urls: {\n * \t\t A1: "A1.mp3",\n * \t\t A2: "A2.mp3",\n * \t },\n * \t onload: () => console.log("loaded"),\n * \t baseUrl: "https://tonejs.github.io/audio/casio/"\n * });\n * @category Core\n */\nclass ToneAudioBuffers_ToneAudioBuffers extends Tone {\n constructor() {\n super();\n this.name = "ToneAudioBuffers";\n /**\n * All of the buffers\n */\n this._buffers = new Map();\n /**\n * Keep track of the number of loaded buffers\n */\n this._loadingCount = 0;\n const options = Defaults_optionsFromArguments(ToneAudioBuffers_ToneAudioBuffers.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls");\n this.baseUrl = options.baseUrl;\n // add each one\n Object.keys(options.urls).forEach(name => {\n this._loadingCount++;\n const url = options.urls[name];\n this.add(name, url, this._bufferLoaded.bind(this, options.onload), options.onerror);\n });\n }\n static getDefaults() {\n return {\n baseUrl: "",\n onerror: Interface_noOp,\n onload: Interface_noOp,\n urls: {},\n };\n }\n /**\n * True if the buffers object has a buffer by that name.\n * @param name The key or index of the buffer.\n */\n has(name) {\n return this._buffers.has(name.toString());\n }\n /**\n * Get a buffer by name. If an array was loaded,\n * then use the array index.\n * @param name The key or index of the buffer.\n */\n get(name) {\n Debug_assert(this.has(name), `ToneAudioBuffers has no buffer named: ${name}`);\n return this._buffers.get(name.toString());\n }\n /**\n * A buffer was loaded. decrement the counter.\n */\n _bufferLoaded(callback) {\n this._loadingCount--;\n if (this._loadingCount === 0 && callback) {\n callback();\n }\n }\n /**\n * If the buffers are loaded or not\n */\n get loaded() {\n return Array.from(this._buffers).every(([_, buffer]) => buffer.loaded);\n }\n /**\n * Add a buffer by name and url to the Buffers\n * @param name A unique name to give the buffer\n * @param url Either the url of the bufer, or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n * @param onerror Invoked if the buffer can\'t be loaded\n */\n add(name, url, callback = Interface_noOp, onerror = Interface_noOp) {\n if (TypeCheck_isString(url)) {\n this._buffers.set(name.toString(), new ToneAudioBuffer_ToneAudioBuffer(this.baseUrl + url, callback, onerror));\n }\n else {\n this._buffers.set(name.toString(), new ToneAudioBuffer_ToneAudioBuffer(url, callback, onerror));\n }\n return this;\n }\n dispose() {\n super.dispose();\n this._buffers.forEach(buffer => buffer.dispose());\n this._buffers.clear();\n return this;\n }\n}\n//# sourceMappingURL=ToneAudioBuffers.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Midi.js\n\n\n\n/**\n * Midi is a primitive type for encoding Time values.\n * Midi can be constructed with or without the `new` keyword. Midi can be passed\n * into the parameter of any method which takes time as an argument.\n * @category Unit\n */\nclass Midi_MidiClass extends (/* unused pure expression or super */ null && (FrequencyClass)) {\n constructor() {\n super(...arguments);\n this.name = "MidiClass";\n this.defaultUnits = "midi";\n }\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return ftom(super._frequencyToUnits(freq));\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return ftom(super._ticksToUnits(ticks));\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return ftom(super._beatsToUnits(beats));\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return ftom(super._secondsToUnits(seconds));\n }\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Midi(60).toMidi(); // 60\n */\n toMidi() {\n return this.valueOf();\n }\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Midi(60).toFrequency(); // 261.6255653005986\n */\n toFrequency() {\n return mtof(this.toMidi());\n }\n /**\n * Transposes the frequency by the given number of semitones.\n * @return A new transposed MidiClass\n * @example\n * Tone.Midi("A4").transpose(3); // "C5"\n */\n transpose(interval) {\n return new Midi_MidiClass(this.context, this.toMidi() + interval);\n }\n}\n/**\n * Convert a value into a FrequencyClass object.\n * @category Unit\n */\nfunction Midi(value, units) {\n return new Midi_MidiClass(getContext(), value, units);\n}\n//# sourceMappingURL=Midi.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Ticks.js\n\n\n/**\n * Ticks is a primitive type for encoding Time values.\n * Ticks can be constructed with or without the `new` keyword. Ticks can be passed\n * into the parameter of any method which takes time as an argument.\n * @example\n * const t = Tone.Ticks("4n"); // a quarter note as ticks\n * @category Unit\n */\nclass Ticks_TicksClass extends TransportTime_TransportTimeClass {\n constructor() {\n super(...arguments);\n this.name = "Ticks";\n this.defaultUnits = "i";\n }\n /**\n * Get the current time in the given units\n */\n _now() {\n return this.context.transport.ticks;\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return this._getPPQ() * beats;\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return Math.floor(seconds / (60 / this._getBpm()) * this._getPPQ());\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return ticks;\n }\n /**\n * Return the time in ticks\n */\n toTicks() {\n return this.valueOf();\n }\n /**\n * Return the time in seconds\n */\n toSeconds() {\n return (this.valueOf() / this._getPPQ()) * (60 / this._getBpm());\n }\n}\n/**\n * Convert a time representation to ticks\n * @category Unit\n */\nfunction Ticks(value, units) {\n return new Ticks_TicksClass(getContext(), value, units);\n}\n//# sourceMappingURL=Ticks.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Draw.js\n\n\n\n/**\n * Draw is useful for synchronizing visuals and audio events.\n * Callbacks from Tone.Transport or any of the Tone.Event classes\n * always happen _before_ the scheduled time and are not synchronized\n * to the animation frame so they are not good for triggering tightly\n * synchronized visuals and sound. Draw makes it easy to schedule\n * callbacks using the AudioContext time and uses requestAnimationFrame.\n * @example\n * Tone.Transport.schedule((time) => {\n * \t// use the time argument to schedule a callback with Draw\n * \tTone.Draw.schedule(() => {\n * \t\t// do drawing or DOM manipulation here\n * \t\tconsole.log(time);\n * \t}, time);\n * }, "+0.5");\n * Tone.Transport.start();\n * @category Core\n */\nclass Draw extends ToneWithContext_ToneWithContext {\n constructor() {\n super(...arguments);\n this.name = "Draw";\n /**\n * The duration after which events are not invoked.\n */\n this.expiration = 0.25;\n /**\n * The amount of time before the scheduled time\n * that the callback can be invoked. Default is\n * half the time of an animation frame (0.008 seconds).\n */\n this.anticipation = 0.008;\n /**\n * All of the events.\n */\n this._events = new Timeline();\n /**\n * The draw loop\n */\n this._boundDrawLoop = this._drawLoop.bind(this);\n /**\n * The animation frame id\n */\n this._animationFrame = -1;\n }\n /**\n * Schedule a function at the given time to be invoked\n * on the nearest animation frame.\n * @param callback Callback is invoked at the given time.\n * @param time The time relative to the AudioContext time to invoke the callback.\n * @example\n * Tone.Transport.scheduleRepeat(time => {\n * \tTone.Draw.schedule(() => console.log(time), time);\n * }, 1);\n * Tone.Transport.start();\n */\n schedule(callback, time) {\n this._events.add({\n callback,\n time: this.toSeconds(time),\n });\n // start the draw loop on the first event\n if (this._events.length === 1) {\n this._animationFrame = requestAnimationFrame(this._boundDrawLoop);\n }\n return this;\n }\n /**\n * Cancel events scheduled after the given time\n * @param after Time after which scheduled events will be removed from the scheduling timeline.\n */\n cancel(after) {\n this._events.cancel(this.toSeconds(after));\n return this;\n }\n /**\n * The draw loop\n */\n _drawLoop() {\n const now = this.context.currentTime;\n while (this._events.length && this._events.peek().time - this.anticipation <= now) {\n const event = this._events.shift();\n if (event && now - event.time <= this.expiration) {\n event.callback();\n }\n }\n if (this._events.length > 0) {\n this._animationFrame = requestAnimationFrame(this._boundDrawLoop);\n }\n }\n dispose() {\n super.dispose();\n this._events.dispose();\n cancelAnimationFrame(this._animationFrame);\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.draw = new Draw({ context });\n});\nonContextClose(context => {\n context.draw.dispose();\n});\n//# sourceMappingURL=Draw.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/IntervalTimeline.js\n\n\n\n/**\n * Similar to Tone.Timeline, but all events represent\n * intervals with both "time" and "duration" times. The\n * events are placed in a tree structure optimized\n * for querying an intersection point with the timeline\n * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree)\n * to represent the data.\n */\nclass IntervalTimeline extends Tone {\n constructor() {\n super(...arguments);\n this.name = "IntervalTimeline";\n /**\n * The root node of the inteval tree\n */\n this._root = null;\n /**\n * Keep track of the length of the timeline.\n */\n this._length = 0;\n }\n /**\n * The event to add to the timeline. All events must\n * have a time and duration value\n * @param event The event to add to the timeline\n */\n add(event) {\n Debug_assert(TypeCheck_isDefined(event.time), "Events must have a time property");\n Debug_assert(TypeCheck_isDefined(event.duration), "Events must have a duration parameter");\n event.time = event.time.valueOf();\n let node = new IntervalNode(event.time, event.time + event.duration, event);\n if (this._root === null) {\n this._root = node;\n }\n else {\n this._root.insert(node);\n }\n this._length++;\n // Restructure tree to be balanced\n while (node !== null) {\n node.updateHeight();\n node.updateMax();\n this._rebalance(node);\n node = node.parent;\n }\n return this;\n }\n /**\n * Remove an event from the timeline.\n * @param event The event to remove from the timeline\n */\n remove(event) {\n if (this._root !== null) {\n const results = [];\n this._root.search(event.time, results);\n for (const node of results) {\n if (node.event === event) {\n this._removeNode(node);\n this._length--;\n break;\n }\n }\n }\n return this;\n }\n /**\n * The number of items in the timeline.\n * @readOnly\n */\n get length() {\n return this._length;\n }\n /**\n * Remove events whose time time is after the given time\n * @param after The time to query.\n */\n cancel(after) {\n this.forEachFrom(after, event => this.remove(event));\n return this;\n }\n /**\n * Set the root node as the given node\n */\n _setRoot(node) {\n this._root = node;\n if (this._root !== null) {\n this._root.parent = null;\n }\n }\n /**\n * Replace the references to the node in the node\'s parent\n * with the replacement node.\n */\n _replaceNodeInParent(node, replacement) {\n if (node.parent !== null) {\n if (node.isLeftChild()) {\n node.parent.left = replacement;\n }\n else {\n node.parent.right = replacement;\n }\n this._rebalance(node.parent);\n }\n else {\n this._setRoot(replacement);\n }\n }\n /**\n * Remove the node from the tree and replace it with\n * a successor which follows the schema.\n */\n _removeNode(node) {\n if (node.left === null && node.right === null) {\n this._replaceNodeInParent(node, null);\n }\n else if (node.right === null) {\n this._replaceNodeInParent(node, node.left);\n }\n else if (node.left === null) {\n this._replaceNodeInParent(node, node.right);\n }\n else {\n const balance = node.getBalance();\n let replacement;\n let temp = null;\n if (balance > 0) {\n if (node.left.right === null) {\n replacement = node.left;\n replacement.right = node.right;\n temp = replacement;\n }\n else {\n replacement = node.left.right;\n while (replacement.right !== null) {\n replacement = replacement.right;\n }\n if (replacement.parent) {\n replacement.parent.right = replacement.left;\n temp = replacement.parent;\n replacement.left = node.left;\n replacement.right = node.right;\n }\n }\n }\n else if (node.right.left === null) {\n replacement = node.right;\n replacement.left = node.left;\n temp = replacement;\n }\n else {\n replacement = node.right.left;\n while (replacement.left !== null) {\n replacement = replacement.left;\n }\n if (replacement.parent) {\n replacement.parent.left = replacement.right;\n temp = replacement.parent;\n replacement.left = node.left;\n replacement.right = node.right;\n }\n }\n if (node.parent !== null) {\n if (node.isLeftChild()) {\n node.parent.left = replacement;\n }\n else {\n node.parent.right = replacement;\n }\n }\n else {\n this._setRoot(replacement);\n }\n if (temp) {\n this._rebalance(temp);\n }\n }\n node.dispose();\n }\n /**\n * Rotate the tree to the left\n */\n _rotateLeft(node) {\n const parent = node.parent;\n const isLeftChild = node.isLeftChild();\n // Make node.right the new root of this sub tree (instead of node)\n const pivotNode = node.right;\n if (pivotNode) {\n node.right = pivotNode.left;\n pivotNode.left = node;\n }\n if (parent !== null) {\n if (isLeftChild) {\n parent.left = pivotNode;\n }\n else {\n parent.right = pivotNode;\n }\n }\n else {\n this._setRoot(pivotNode);\n }\n }\n /**\n * Rotate the tree to the right\n */\n _rotateRight(node) {\n const parent = node.parent;\n const isLeftChild = node.isLeftChild();\n // Make node.left the new root of this sub tree (instead of node)\n const pivotNode = node.left;\n if (pivotNode) {\n node.left = pivotNode.right;\n pivotNode.right = node;\n }\n if (parent !== null) {\n if (isLeftChild) {\n parent.left = pivotNode;\n }\n else {\n parent.right = pivotNode;\n }\n }\n else {\n this._setRoot(pivotNode);\n }\n }\n /**\n * Balance the BST\n */\n _rebalance(node) {\n const balance = node.getBalance();\n if (balance > 1 && node.left) {\n if (node.left.getBalance() < 0) {\n this._rotateLeft(node.left);\n }\n else {\n this._rotateRight(node);\n }\n }\n else if (balance < -1 && node.right) {\n if (node.right.getBalance() > 0) {\n this._rotateRight(node.right);\n }\n else {\n this._rotateLeft(node);\n }\n }\n }\n /**\n * Get an event whose time and duration span the give time. Will\n * return the match whose "time" value is closest to the given time.\n * @return The event which spans the desired time\n */\n get(time) {\n if (this._root !== null) {\n const results = [];\n this._root.search(time, results);\n if (results.length > 0) {\n let max = results[0];\n for (let i = 1; i < results.length; i++) {\n if (results[i].low > max.low) {\n max = results[i];\n }\n }\n return max.event;\n }\n }\n return null;\n }\n /**\n * Iterate over everything in the timeline.\n * @param callback The callback to invoke with every item\n */\n forEach(callback) {\n if (this._root !== null) {\n const allNodes = [];\n this._root.traverse(node => allNodes.push(node));\n allNodes.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Iterate over everything in the array in which the given time\n * overlaps with the time and duration time of the event.\n * @param time The time to check if items are overlapping\n * @param callback The callback to invoke with every item\n */\n forEachAtTime(time, callback) {\n if (this._root !== null) {\n const results = [];\n this._root.search(time, results);\n results.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Iterate over everything in the array in which the time is greater\n * than or equal to the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachFrom(time, callback) {\n if (this._root !== null) {\n const results = [];\n this._root.searchAfter(time, results);\n results.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n if (this._root !== null) {\n this._root.traverse(node => node.dispose());\n }\n this._root = null;\n return this;\n }\n}\n//-------------------------------------\n// \tINTERVAL NODE HELPER\n//-------------------------------------\n/**\n * Represents a node in the binary search tree, with the addition\n * of a "high" value which keeps track of the highest value of\n * its children.\n * References:\n * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/\n * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf\n * @param low\n * @param high\n */\nclass IntervalNode {\n constructor(low, high, event) {\n // the nodes to the left\n this._left = null;\n // the nodes to the right\n this._right = null;\n // the parent node\n this.parent = null;\n // the number of child nodes\n this.height = 0;\n this.event = event;\n // the low value\n this.low = low;\n // the high value\n this.high = high;\n // the high value for this and all child nodes\n this.max = this.high;\n }\n /**\n * Insert a node into the correct spot in the tree\n */\n insert(node) {\n if (node.low <= this.low) {\n if (this.left === null) {\n this.left = node;\n }\n else {\n this.left.insert(node);\n }\n }\n else if (this.right === null) {\n this.right = node;\n }\n else {\n this.right.insert(node);\n }\n }\n /**\n * Search the tree for nodes which overlap\n * with the given point\n * @param point The point to query\n * @param results The array to put the results\n */\n search(point, results) {\n // If p is to the right of the rightmost point of any interval\n // in this node and all children, there won\'t be any matches.\n if (point > this.max) {\n return;\n }\n // Search left children\n if (this.left !== null) {\n this.left.search(point, results);\n }\n // Check this node\n if (this.low <= point && this.high > point) {\n results.push(this);\n }\n // If p is to the left of the time of this interval,\n // then it can\'t be in any child to the right.\n if (this.low > point) {\n return;\n }\n // Search right children\n if (this.right !== null) {\n this.right.search(point, results);\n }\n }\n /**\n * Search the tree for nodes which are less\n * than the given point\n * @param point The point to query\n * @param results The array to put the results\n */\n searchAfter(point, results) {\n // Check this node\n if (this.low >= point) {\n results.push(this);\n if (this.left !== null) {\n this.left.searchAfter(point, results);\n }\n }\n // search the right side\n if (this.right !== null) {\n this.right.searchAfter(point, results);\n }\n }\n /**\n * Invoke the callback on this element and both it\'s branches\n * @param {Function} callback\n */\n traverse(callback) {\n callback(this);\n if (this.left !== null) {\n this.left.traverse(callback);\n }\n if (this.right !== null) {\n this.right.traverse(callback);\n }\n }\n /**\n * Update the height of the node\n */\n updateHeight() {\n if (this.left !== null && this.right !== null) {\n this.height = Math.max(this.left.height, this.right.height) + 1;\n }\n else if (this.right !== null) {\n this.height = this.right.height + 1;\n }\n else if (this.left !== null) {\n this.height = this.left.height + 1;\n }\n else {\n this.height = 0;\n }\n }\n /**\n * Update the height of the node\n */\n updateMax() {\n this.max = this.high;\n if (this.left !== null) {\n this.max = Math.max(this.max, this.left.max);\n }\n if (this.right !== null) {\n this.max = Math.max(this.max, this.right.max);\n }\n }\n /**\n * The balance is how the leafs are distributed on the node\n * @return Negative numbers are balanced to the right\n */\n getBalance() {\n let balance = 0;\n if (this.left !== null && this.right !== null) {\n balance = this.left.height - this.right.height;\n }\n else if (this.left !== null) {\n balance = this.left.height + 1;\n }\n else if (this.right !== null) {\n balance = -(this.right.height + 1);\n }\n return balance;\n }\n /**\n * @returns true if this node is the left child of its parent\n */\n isLeftChild() {\n return this.parent !== null && this.parent.left === this;\n }\n /**\n * get/set the left node\n */\n get left() {\n return this._left;\n }\n set left(node) {\n this._left = node;\n if (node !== null) {\n node.parent = this;\n }\n this.updateHeight();\n this.updateMax();\n }\n /**\n * get/set the right node\n */\n get right() {\n return this._right;\n }\n set right(node) {\n this._right = node;\n if (node !== null) {\n node.parent = this;\n }\n this.updateHeight();\n this.updateMax();\n }\n /**\n * null out references.\n */\n dispose() {\n this.parent = null;\n this._left = null;\n this._right = null;\n this.event = null;\n }\n}\n//# sourceMappingURL=IntervalTimeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/index.js\n\n// export * from "./clock/Transport";\n\n\n\n// export * from "./context/Destination";\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// get the units and export them under the "Unit" namespace\n\n\n// export the debug stuff as Debug\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Volume.js\n\n\n\n\n/**\n * Volume is a simple volume node, useful for creating a volume fader.\n *\n * @example\n * const vol = new Tone.Volume(-12).toDestination();\n * const osc = new Tone.Oscillator().connect(vol).start();\n * @category Component\n */\nclass Volume_Volume extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Volume_Volume.getDefaults(), arguments, ["volume"]));\n this.name = "Volume";\n const options = Defaults_optionsFromArguments(Volume_Volume.getDefaults(), arguments, ["volume"]);\n this.input = this.output = new Gain_Gain({\n context: this.context,\n gain: options.volume,\n units: "decibels",\n });\n this.volume = this.output.gain;\n Interface_readOnly(this, "volume");\n this._unmutedVolume = options.volume;\n // set the mute initially\n this.mute = options.mute;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0,\n });\n }\n /**\n * Mute the output.\n * @example\n * const vol = new Tone.Volume(-12).toDestination();\n * const osc = new Tone.Oscillator().connect(vol).start();\n * // mute the output\n * vol.mute = true;\n */\n get mute() {\n return this.volume.value === -Infinity;\n }\n set mute(mute) {\n if (!this.mute && mute) {\n this._unmutedVolume = this.volume.value;\n // maybe it should ramp here?\n this.volume.value = -Infinity;\n }\n else if (this.mute && !mute) {\n this.volume.value = this._unmutedVolume;\n }\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this.input.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Volume.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Destination.js\n\n\n\n\n\n/**\n * A single master output which is connected to the\n * AudioDestinationNode (aka your speakers).\n * It provides useful conveniences such as the ability\n * to set the volume and mute the entire application.\n * It also gives you the ability to apply master effects to your application.\n *\n * @example\n * const oscillator = new Tone.Oscillator().start();\n * // the audio will go from the oscillator to the speakers\n * oscillator.connect(Tone.getDestination());\n * // a convenience for connecting to the master output is also provided:\n * oscillator.toDestination();\n * @category Core\n */\nclass Destination extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Destination.getDefaults(), arguments));\n this.name = "Destination";\n this.input = new Volume_Volume({ context: this.context });\n this.output = new Gain_Gain({ context: this.context });\n /**\n * The volume of the master output in decibels. -Infinity is silent, and 0 is no change.\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * osc.start();\n * // ramp the volume down to silent over 10 seconds\n * Tone.getDestination().volume.rampTo(-Infinity, 10);\n */\n this.volume = this.input.volume;\n const options = Defaults_optionsFromArguments(Destination.getDefaults(), arguments);\n ToneAudioNode_connectSeries(this.input, this.output, this.context.rawContext.destination);\n this.mute = options.mute;\n this._internalChannels = [this.input, this.context.rawContext.destination, this.output];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0,\n });\n }\n /**\n * Mute the output.\n * @example\n * const oscillator = new Tone.Oscillator().start().toDestination();\n * setTimeout(() => {\n * \t// mute the output\n * \tTone.Destination.mute = true;\n * }, 1000);\n */\n get mute() {\n return this.input.mute;\n }\n set mute(mute) {\n this.input.mute = mute;\n }\n /**\n * Add a master effects chain. NOTE: this will disconnect any nodes which were previously\n * chained in the master effects chain.\n * @param args All arguments will be connected in a row and the Master will be routed through it.\n * @example\n * // route all audio through a filter and compressor\n * const lowpass = new Tone.Filter(800, "lowpass");\n * const compressor = new Tone.Compressor(-18);\n * Tone.Destination.chain(lowpass, compressor);\n */\n chain(...args) {\n this.input.disconnect();\n args.unshift(this.input);\n args.push(this.output);\n ToneAudioNode_connectSeries(...args);\n return this;\n }\n /**\n * The maximum number of channels the system can output\n * @example\n * console.log(Tone.Destination.maxChannelCount);\n */\n get maxChannelCount() {\n return this.context.rawContext.destination.maxChannelCount;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.destination = new Destination({ context });\n});\nonContextClose(context => {\n context.destination.dispose();\n});\n//# sourceMappingURL=Destination.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/TimelineValue.js\n\n\n/**\n * Represents a single value which is gettable and settable in a timed way\n */\nclass TimelineValue extends Tone {\n /**\n * @param initialValue The value to return if there is no scheduled values\n */\n constructor(initialValue) {\n super();\n this.name = "TimelineValue";\n /**\n * The timeline which stores the values\n */\n this._timeline = new Timeline({ memory: 10 });\n this._initialValue = initialValue;\n }\n /**\n * Set the value at the given time\n */\n set(value, time) {\n this._timeline.add({\n value, time\n });\n return this;\n }\n /**\n * Get the value at the given time\n */\n get(time) {\n const event = this._timeline.get(time);\n if (event) {\n return event.value;\n }\n else {\n return this._initialValue;\n }\n }\n}\n//# sourceMappingURL=TimelineValue.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TransportEvent.js\n\n/**\n * TransportEvent is an internal class used by [[Transport]]\n * to schedule events. Do no invoke this class directly, it is\n * handled from within Tone.Transport.\n */\nclass TransportEvent {\n /**\n * @param transport The transport object which the event belongs to\n */\n constructor(transport, opts) {\n /**\n * The unique id of the event\n */\n this.id = TransportEvent._eventId++;\n const options = Object.assign(TransportEvent.getDefaults(), opts);\n this.transport = transport;\n this.callback = options.callback;\n this._once = options.once;\n this.time = options.time;\n }\n static getDefaults() {\n return {\n callback: Interface_noOp,\n once: false,\n time: 0,\n };\n }\n /**\n * Invoke the event callback.\n * @param time The AudioContext time in seconds of the event\n */\n invoke(time) {\n if (this.callback) {\n this.callback(time);\n if (this._once) {\n this.transport.clear(this.id);\n }\n }\n }\n /**\n * Clean up\n */\n dispose() {\n this.callback = undefined;\n return this;\n }\n}\n/**\n * Current ID counter\n */\nTransportEvent._eventId = 0;\n//# sourceMappingURL=TransportEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TransportRepeatEvent.js\n\n\n/**\n * TransportRepeatEvent is an internal class used by Tone.Transport\n * to schedule repeat events. This class should not be instantiated directly.\n */\nclass TransportRepeatEvent extends TransportEvent {\n /**\n * @param transport The transport object which the event belongs to\n */\n constructor(transport, opts) {\n super(transport, opts);\n /**\n * The ID of the current timeline event\n */\n this._currentId = -1;\n /**\n * The ID of the next timeline event\n */\n this._nextId = -1;\n /**\n * The time of the next event\n */\n this._nextTick = this.time;\n /**\n * a reference to the bound start method\n */\n this._boundRestart = this._restart.bind(this);\n const options = Object.assign(TransportRepeatEvent.getDefaults(), opts);\n this.duration = new Ticks_TicksClass(transport.context, options.duration).valueOf();\n this._interval = new Ticks_TicksClass(transport.context, options.interval).valueOf();\n this._nextTick = options.time;\n this.transport.on("start", this._boundRestart);\n this.transport.on("loopStart", this._boundRestart);\n this.context = this.transport.context;\n this._restart();\n }\n static getDefaults() {\n return Object.assign({}, TransportEvent.getDefaults(), {\n duration: Infinity,\n interval: 1,\n once: false,\n });\n }\n /**\n * Invoke the callback. Returns the tick time which\n * the next event should be scheduled at.\n * @param time The AudioContext time in seconds of the event\n */\n invoke(time) {\n // create more events if necessary\n this._createEvents(time);\n // call the super class\n super.invoke(time);\n }\n /**\n * Push more events onto the timeline to keep up with the position of the timeline\n */\n _createEvents(time) {\n // schedule the next event\n const ticks = this.transport.getTicksAtTime(time);\n if (ticks >= this.time && ticks >= this._nextTick && this._nextTick + this._interval < this.time + this.duration) {\n this._nextTick += this._interval;\n this._currentId = this._nextId;\n this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n }\n }\n /**\n * Push more events onto the timeline to keep up with the position of the timeline\n */\n _restart(time) {\n this.transport.clear(this._currentId);\n this.transport.clear(this._nextId);\n this._nextTick = this.time;\n const ticks = this.transport.getTicksAtTime(time);\n if (ticks > this.time) {\n this._nextTick = this.time + Math.ceil((ticks - this.time) / this._interval) * this._interval;\n }\n this._currentId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n this._nextTick += this._interval;\n this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.transport.clear(this._currentId);\n this.transport.clear(this._nextId);\n this.transport.off("start", this._boundRestart);\n this.transport.off("loopStart", this._boundRestart);\n return this;\n }\n}\n//# sourceMappingURL=TransportRepeatEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Transport.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Transport for timing musical events.\n * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame)\n * Transport timing events pass in the exact time of the scheduled event\n * in the argument of the callback function. Pass that time value to the object\n * you\'re scheduling. <br><br>\n * A single transport is created for you when the library is initialized.\n * <br><br>\n * The transport emits the events: "start", "stop", "pause", and "loop" which are\n * called with the time of that event as the argument.\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * // repeated event every 8th note\n * Tone.Transport.scheduleRepeat((time) => {\n * \t// use the callback time to schedule events\n * \tosc.start(time).stop(time + 0.1);\n * }, "8n");\n * // transport must be started before it starts invoking events\n * Tone.Transport.start();\n * @category Core\n */\nclass Transport extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Transport.getDefaults(), arguments));\n this.name = "Transport";\n //-------------------------------------\n // \tLOOPING\n //-------------------------------------\n /**\n * If the transport loops or not.\n */\n this._loop = new TimelineValue(false);\n /**\n * The loop start position in ticks\n */\n this._loopStart = 0;\n /**\n * The loop end position in ticks\n */\n this._loopEnd = 0;\n //-------------------------------------\n // \tTIMELINE EVENTS\n //-------------------------------------\n /**\n * All the events in an object to keep track by ID\n */\n this._scheduledEvents = {};\n /**\n * The scheduled events.\n */\n this._timeline = new Timeline();\n /**\n * Repeated events\n */\n this._repeatedEvents = new IntervalTimeline();\n /**\n * All of the synced Signals\n */\n this._syncedSignals = [];\n /**\n * The swing amount\n */\n this._swingAmount = 0;\n const options = Defaults_optionsFromArguments(Transport.getDefaults(), arguments);\n // CLOCK/TEMPO\n this._ppq = options.ppq;\n this._clock = new Clock_Clock({\n callback: this._processTick.bind(this),\n context: this.context,\n frequency: 0,\n units: "bpm",\n });\n this._bindClockEvents();\n this.bpm = this._clock.frequency;\n this._clock.frequency.multiplier = options.ppq;\n this.bpm.setValueAtTime(options.bpm, 0);\n Interface_readOnly(this, "bpm");\n this._timeSignature = options.timeSignature;\n // SWING\n this._swingTicks = options.ppq / 2; // 8n\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n bpm: 120,\n loopEnd: "4m",\n loopStart: 0,\n ppq: 192,\n swing: 0,\n swingSubdivision: "8n",\n timeSignature: 4,\n });\n }\n //-------------------------------------\n // \tTICKS\n //-------------------------------------\n /**\n * called on every tick\n * @param tickTime clock relative tick time\n */\n _processTick(tickTime, ticks) {\n // do the loop test\n if (this._loop.get(tickTime)) {\n if (ticks >= this._loopEnd) {\n this.emit("loopEnd", tickTime);\n this._clock.setTicksAtTime(this._loopStart, tickTime);\n ticks = this._loopStart;\n this.emit("loopStart", tickTime, this._clock.getSecondsAtTime(tickTime));\n this.emit("loop", tickTime);\n }\n }\n // handle swing\n if (this._swingAmount > 0 &&\n ticks % this._ppq !== 0 && // not on a downbeat\n ticks % (this._swingTicks * 2) !== 0) {\n // add some swing\n const progress = (ticks % (this._swingTicks * 2)) / (this._swingTicks * 2);\n const amount = Math.sin((progress) * Math.PI) * this._swingAmount;\n tickTime += new Ticks_TicksClass(this.context, this._swingTicks * 2 / 3).toSeconds() * amount;\n }\n // invoke the timeline events scheduled on this tick\n this._timeline.forEachAtTime(ticks, event => event.invoke(tickTime));\n }\n //-------------------------------------\n // \tSCHEDULABLE EVENTS\n //-------------------------------------\n /**\n * Schedule an event along the timeline.\n * @param callback The callback to be invoked at the time.\n * @param time The time to invoke the callback at.\n * @return The id of the event which can be used for canceling the event.\n * @example\n * // schedule an event on the 16th measure\n * Tone.Transport.schedule((time) => {\n * \t// invoked on measure 16\n * \tconsole.log("measure 16!");\n * }, "16:0:0");\n */\n schedule(callback, time) {\n const event = new TransportEvent(this, {\n callback,\n time: new TransportTime_TransportTimeClass(this.context, time).toTicks(),\n });\n return this._addEvent(event, this._timeline);\n }\n /**\n * Schedule a repeated event along the timeline. The event will fire\n * at the `interval` starting at the `startTime` and for the specified\n * `duration`.\n * @param callback The callback to invoke.\n * @param interval The duration between successive callbacks. Must be a positive number.\n * @param startTime When along the timeline the events should start being invoked.\n * @param duration How long the event should repeat.\n * @return The ID of the scheduled event. Use this to cancel the event.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // a callback invoked every eighth note after the first measure\n * Tone.Transport.scheduleRepeat((time) => {\n * \tosc.start(time).stop(time + 0.1);\n * }, "8n", "1m");\n */\n scheduleRepeat(callback, interval, startTime, duration = Infinity) {\n const event = new TransportRepeatEvent(this, {\n callback,\n duration: new TimeClass(this.context, duration).toTicks(),\n interval: new TimeClass(this.context, interval).toTicks(),\n time: new TransportTime_TransportTimeClass(this.context, startTime).toTicks(),\n });\n // kick it off if the Transport is started\n // @ts-ignore\n return this._addEvent(event, this._repeatedEvents);\n }\n /**\n * Schedule an event that will be removed after it is invoked.\n * @param callback The callback to invoke once.\n * @param time The time the callback should be invoked.\n * @returns The ID of the scheduled event.\n */\n scheduleOnce(callback, time) {\n const event = new TransportEvent(this, {\n callback,\n once: true,\n time: new TransportTime_TransportTimeClass(this.context, time).toTicks(),\n });\n return this._addEvent(event, this._timeline);\n }\n /**\n * Clear the passed in event id from the timeline\n * @param eventId The id of the event.\n */\n clear(eventId) {\n if (this._scheduledEvents.hasOwnProperty(eventId)) {\n const item = this._scheduledEvents[eventId.toString()];\n item.timeline.remove(item.event);\n item.event.dispose();\n delete this._scheduledEvents[eventId.toString()];\n }\n return this;\n }\n /**\n * Add an event to the correct timeline. Keep track of the\n * timeline it was added to.\n * @returns the event id which was just added\n */\n _addEvent(event, timeline) {\n this._scheduledEvents[event.id.toString()] = {\n event,\n timeline,\n };\n timeline.add(event);\n return event.id;\n }\n /**\n * Remove scheduled events from the timeline after\n * the given time. Repeated events will be removed\n * if their startTime is after the given time\n * @param after Clear all events after this time.\n */\n cancel(after = 0) {\n const computedAfter = this.toTicks(after);\n this._timeline.forEachFrom(computedAfter, event => this.clear(event.id));\n this._repeatedEvents.forEachFrom(computedAfter, event => this.clear(event.id));\n return this;\n }\n //-------------------------------------\n // \tSTART/STOP/PAUSE\n //-------------------------------------\n /**\n * Bind start/stop/pause events from the clock and emit them.\n */\n _bindClockEvents() {\n this._clock.on("start", (time, offset) => {\n offset = new Ticks_TicksClass(this.context, offset).toSeconds();\n this.emit("start", time, offset);\n });\n this._clock.on("stop", (time) => {\n this.emit("stop", time);\n });\n this._clock.on("pause", (time) => {\n this.emit("pause", time);\n });\n }\n /**\n * Returns the playback state of the source, either "started", "stopped", or "paused"\n */\n get state() {\n return this._clock.getStateAtTime(this.now());\n }\n /**\n * Start the transport and all sources synced to the transport.\n * @param time The time when the transport should start.\n * @param offset The timeline offset to start the transport.\n * @example\n * // start the transport in one second starting at beginning of the 5th measure.\n * Tone.Transport.start("+1", "4:0:0");\n */\n start(time, offset) {\n let offsetTicks;\n if (TypeCheck_isDefined(offset)) {\n offsetTicks = this.toTicks(offset);\n }\n // start the clock\n this._clock.start(time, offsetTicks);\n return this;\n }\n /**\n * Stop the transport and all sources synced to the transport.\n * @param time The time when the transport should stop.\n * @example\n * Tone.Transport.stop();\n */\n stop(time) {\n this._clock.stop(time);\n return this;\n }\n /**\n * Pause the transport and all sources synced to the transport.\n */\n pause(time) {\n this._clock.pause(time);\n return this;\n }\n /**\n * Toggle the current state of the transport. If it is\n * started, it will stop it, otherwise it will start the Transport.\n * @param time The time of the event\n */\n toggle(time) {\n time = this.toSeconds(time);\n if (this._clock.getStateAtTime(time) !== "started") {\n this.start(time);\n }\n else {\n this.stop(time);\n }\n return this;\n }\n //-------------------------------------\n // \tSETTERS/GETTERS\n //-------------------------------------\n /**\n * The time signature as just the numerator over 4.\n * For example 4/4 would be just 4 and 6/8 would be 3.\n * @example\n * // common time\n * Tone.Transport.timeSignature = 4;\n * // 7/8\n * Tone.Transport.timeSignature = [7, 8];\n * // this will be reduced to a single number\n * Tone.Transport.timeSignature; // returns 3.5\n */\n get timeSignature() {\n return this._timeSignature;\n }\n set timeSignature(timeSig) {\n if (TypeCheck_isArray(timeSig)) {\n timeSig = (timeSig[0] / timeSig[1]) * 4;\n }\n this._timeSignature = timeSig;\n }\n /**\n * When the Transport.loop = true, this is the starting position of the loop.\n */\n get loopStart() {\n return new TimeClass(this.context, this._loopStart, "i").toSeconds();\n }\n set loopStart(startPosition) {\n this._loopStart = this.toTicks(startPosition);\n }\n /**\n * When the Transport.loop = true, this is the ending position of the loop.\n */\n get loopEnd() {\n return new TimeClass(this.context, this._loopEnd, "i").toSeconds();\n }\n set loopEnd(endPosition) {\n this._loopEnd = this.toTicks(endPosition);\n }\n /**\n * If the transport loops or not.\n */\n get loop() {\n return this._loop.get(this.now());\n }\n set loop(loop) {\n this._loop.set(loop, this.now());\n }\n /**\n * Set the loop start and stop at the same time.\n * @example\n * // loop over the first measure\n * Tone.Transport.setLoopPoints(0, "1m");\n * Tone.Transport.loop = true;\n */\n setLoopPoints(startPosition, endPosition) {\n this.loopStart = startPosition;\n this.loopEnd = endPosition;\n return this;\n }\n /**\n * The swing value. Between 0-1 where 1 equal to the note + half the subdivision.\n */\n get swing() {\n return this._swingAmount;\n }\n set swing(amount) {\n // scale the values to a normal range\n this._swingAmount = amount;\n }\n /**\n * Set the subdivision which the swing will be applied to.\n * The default value is an 8th note. Value must be less\n * than a quarter note.\n */\n get swingSubdivision() {\n return new Ticks_TicksClass(this.context, this._swingTicks).toNotation();\n }\n set swingSubdivision(subdivision) {\n this._swingTicks = this.toTicks(subdivision);\n }\n /**\n * The Transport\'s position in Bars:Beats:Sixteenths.\n * Setting the value will jump to that position right away.\n */\n get position() {\n const now = this.now();\n const ticks = this._clock.getTicksAtTime(now);\n return new Ticks_TicksClass(this.context, ticks).toBarsBeatsSixteenths();\n }\n set position(progress) {\n const ticks = this.toTicks(progress);\n this.ticks = ticks;\n }\n /**\n * The Transport\'s position in seconds\n * Setting the value will jump to that position right away.\n */\n get seconds() {\n return this._clock.seconds;\n }\n set seconds(s) {\n const now = this.now();\n const ticks = this._clock.frequency.timeToTicks(s, now);\n this.ticks = ticks;\n }\n /**\n * The Transport\'s loop position as a normalized value. Always\n * returns 0 if the transport if loop is not true.\n */\n get progress() {\n if (this.loop) {\n const now = this.now();\n const ticks = this._clock.getTicksAtTime(now);\n return (ticks - this._loopStart) / (this._loopEnd - this._loopStart);\n }\n else {\n return 0;\n }\n }\n /**\n * The transports current tick position.\n */\n get ticks() {\n return this._clock.ticks;\n }\n set ticks(t) {\n if (this._clock.ticks !== t) {\n const now = this.now();\n // stop everything synced to the transport\n if (this.state === "started") {\n const ticks = this._clock.getTicksAtTime(now);\n // schedule to start on the next tick, #573\n const remainingTick = this._clock.frequency.getDurationOfTicks(Math.ceil(ticks) - ticks, now);\n const time = now + remainingTick;\n this.emit("stop", time);\n this._clock.setTicksAtTime(t, time);\n // restart it with the new time\n this.emit("start", time, this._clock.getSecondsAtTime(time));\n }\n else {\n this._clock.setTicksAtTime(t, now);\n }\n }\n }\n /**\n * Get the clock\'s ticks at the given time.\n * @param time When to get the tick value\n * @return The tick value at the given time.\n */\n getTicksAtTime(time) {\n return Math.round(this._clock.getTicksAtTime(time));\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n return this._clock.getSecondsAtTime(time);\n }\n /**\n * Pulses Per Quarter note. This is the smallest resolution\n * the Transport timing supports. This should be set once\n * on initialization and not set again. Changing this value\n * after other objects have been created can cause problems.\n */\n get PPQ() {\n return this._clock.frequency.multiplier;\n }\n set PPQ(ppq) {\n this._clock.frequency.multiplier = ppq;\n }\n //-------------------------------------\n // \tSYNCING\n //-------------------------------------\n /**\n * Returns the time aligned to the next subdivision\n * of the Transport. If the Transport is not started,\n * it will return 0.\n * Note: this will not work precisely during tempo ramps.\n * @param subdivision The subdivision to quantize to\n * @return The context time of the next subdivision.\n * @example\n * // the transport must be started, otherwise returns 0\n * Tone.Transport.start();\n * Tone.Transport.nextSubdivision("4n");\n */\n nextSubdivision(subdivision) {\n subdivision = this.toTicks(subdivision);\n if (this.state !== "started") {\n // if the transport\'s not started, return 0\n return 0;\n }\n else {\n const now = this.now();\n // the remainder of the current ticks and the subdivision\n const transportPos = this.getTicksAtTime(now);\n const remainingTicks = subdivision - transportPos % subdivision;\n return this._clock.nextTickTime(remainingTicks, now);\n }\n }\n /**\n * Attaches the signal to the tempo control signal so that\n * any changes in the tempo will change the signal in the same\n * ratio.\n *\n * @param signal\n * @param ratio Optionally pass in the ratio between the two signals.\n * \t\t\tOtherwise it will be computed based on their current values.\n */\n syncSignal(signal, ratio) {\n if (!ratio) {\n // get the sync ratio\n const now = this.now();\n if (signal.getValueAtTime(now) !== 0) {\n const bpm = this.bpm.getValueAtTime(now);\n const computedFreq = 1 / (60 / bpm / this.PPQ);\n ratio = signal.getValueAtTime(now) / computedFreq;\n }\n else {\n ratio = 0;\n }\n }\n const ratioSignal = new Gain_Gain(ratio);\n // @ts-ignore\n this.bpm.connect(ratioSignal);\n // @ts-ignore\n ratioSignal.connect(signal._param);\n this._syncedSignals.push({\n initial: signal.value,\n ratio: ratioSignal,\n signal,\n });\n signal.value = 0;\n return this;\n }\n /**\n * Unsyncs a previously synced signal from the transport\'s control.\n * See Transport.syncSignal.\n */\n unsyncSignal(signal) {\n for (let i = this._syncedSignals.length - 1; i >= 0; i--) {\n const syncedSignal = this._syncedSignals[i];\n if (syncedSignal.signal === signal) {\n syncedSignal.ratio.dispose();\n syncedSignal.signal.value = syncedSignal.initial;\n this._syncedSignals.splice(i, 1);\n }\n }\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._clock.dispose();\n Interface_writable(this, "bpm");\n this._timeline.dispose();\n this._repeatedEvents.dispose();\n return this;\n }\n}\nEmitter.mixin(Transport);\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.transport = new Transport({ context });\n});\nonContextClose(context => {\n context.transport.dispose();\n});\n//# sourceMappingURL=Transport.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/Source.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Base class for sources.\n * start/stop of this.context.transport.\n *\n * ```\n * // Multiple state change events can be chained together,\n * // but must be set in the correct order and with ascending times\n * // OK\n * state.start().stop("+0.2");\n * // OK\n * state.start().stop("+0.2").start("+0.4").stop("+0.7")\n * // BAD\n * state.stop("+0.2").start();\n * // BAD\n * state.start("+0.3").stop("+0.2");\n * ```\n */\nclass Source_Source extends ToneAudioNode_ToneAudioNode {\n constructor(options) {\n super(options);\n /**\n * Sources have no inputs\n */\n this.input = undefined;\n /**\n * Keep track of the scheduled state.\n */\n this._state = new StateTimeline_StateTimeline("stopped");\n /**\n * The synced `start` callback function from the transport\n */\n this._synced = false;\n /**\n * Keep track of all of the scheduled event ids\n */\n this._scheduled = [];\n /**\n * Placeholder functions for syncing/unsyncing to transport\n */\n this._syncedStart = Interface_noOp;\n this._syncedStop = Interface_noOp;\n this._state.memory = 100;\n this._state.increasing = true;\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n mute: options.mute,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n Interface_readOnly(this, "volume");\n this.onstop = options.onstop;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n onstop: Interface_noOp,\n volume: 0,\n });\n }\n /**\n * Returns the playback state of the source, either "started" or "stopped".\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/ahntone_c3.mp3", () => {\n * \tplayer.start();\n * \tconsole.log(player.state);\n * }).toDestination();\n */\n get state() {\n if (this._synced) {\n if (this.context.transport.state === "started") {\n return this._state.getValueAtTime(this.context.transport.seconds);\n }\n else {\n return "stopped";\n }\n }\n else {\n return this._state.getValueAtTime(this.now());\n }\n }\n /**\n * Mute the output.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // mute the output\n * osc.mute = true;\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n /**\n * Ensure that the scheduled time is not before the current time.\n * Should only be used when scheduled unsynced.\n */\n _clampToCurrentTime(time) {\n if (this._synced) {\n return time;\n }\n else {\n return Math.max(time, this.context.currentTime);\n }\n }\n /**\n * Start the source at the specified time. If no time is given,\n * start the source now.\n * @param time When the source should be started.\n * @example\n * const source = new Tone.Oscillator().toDestination();\n * source.start("+0.5"); // starts the source 0.5 seconds from now\n */\n start(time, offset, duration) {\n let computedTime = TypeCheck_isUndef(time) && this._synced ? this.context.transport.seconds : this.toSeconds(time);\n computedTime = this._clampToCurrentTime(computedTime);\n // if it\'s started, stop it and restart it\n if (!this._synced && this._state.getValueAtTime(computedTime) === "started") {\n // time should be strictly greater than the previous start time\n Debug_assert(GT(computedTime, this._state.get(computedTime).time), "Start time must be strictly greater than previous start time");\n this._state.cancel(computedTime);\n this._state.setStateAtTime("started", computedTime);\n this.log("restart", computedTime);\n this.restart(computedTime, offset, duration);\n }\n else {\n this.log("start", computedTime);\n this._state.setStateAtTime("started", computedTime);\n if (this._synced) {\n // add the offset time to the event\n const event = this._state.get(computedTime);\n if (event) {\n event.offset = this.toSeconds(Defaults_defaultArg(offset, 0));\n event.duration = duration ? this.toSeconds(duration) : undefined;\n }\n const sched = this.context.transport.schedule(t => {\n this._start(t, offset, duration);\n }, computedTime);\n this._scheduled.push(sched);\n // if the transport is already started\n // and the time is greater than where the transport is\n if (this.context.transport.state === "started" &&\n this.context.transport.getSecondsAtTime(this.immediate()) > computedTime) {\n this._syncedStart(this.now(), this.context.transport.seconds);\n }\n }\n else {\n assertContextRunning(this.context);\n this._start(computedTime, offset, duration);\n }\n }\n return this;\n }\n /**\n * Stop the source at the specified time. If no time is given,\n * stop the source now.\n * @param time When the source should be stopped.\n * @example\n * const source = new Tone.Oscillator().toDestination();\n * source.start();\n * source.stop("+0.5"); // stops the source 0.5 seconds from now\n */\n stop(time) {\n let computedTime = TypeCheck_isUndef(time) && this._synced ? this.context.transport.seconds : this.toSeconds(time);\n computedTime = this._clampToCurrentTime(computedTime);\n if (this._state.getValueAtTime(computedTime) === "started" || TypeCheck_isDefined(this._state.getNextState("started", computedTime))) {\n this.log("stop", computedTime);\n if (!this._synced) {\n this._stop(computedTime);\n }\n else {\n const sched = this.context.transport.schedule(this._stop.bind(this), computedTime);\n this._scheduled.push(sched);\n }\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n }\n return this;\n }\n /**\n * Restart the source.\n */\n restart(time, offset, duration) {\n time = this.toSeconds(time);\n if (this._state.getValueAtTime(time) === "started") {\n this._state.cancel(time);\n this._restart(time, offset, duration);\n }\n return this;\n }\n /**\n * Sync the source to the Transport so that all subsequent\n * calls to `start` and `stop` are synced to the TransportTime\n * instead of the AudioContext time.\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * // sync the source so that it plays between 0 and 0.3 on the Transport\'s timeline\n * osc.sync().start(0).stop(0.3);\n * // start the transport.\n * Tone.Transport.start();\n * // set it to loop once a second\n * Tone.Transport.loop = true;\n * Tone.Transport.loopEnd = 1;\n */\n sync() {\n if (!this._synced) {\n this._synced = true;\n this._syncedStart = (time, offset) => {\n if (offset > 0) {\n // get the playback state at that time\n const stateEvent = this._state.get(offset);\n // listen for start events which may occur in the middle of the sync\'ed time\n if (stateEvent && stateEvent.state === "started" && stateEvent.time !== offset) {\n // get the offset\n const startOffset = offset - this.toSeconds(stateEvent.time);\n let duration;\n if (stateEvent.duration) {\n duration = this.toSeconds(stateEvent.duration) - startOffset;\n }\n this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration);\n }\n }\n };\n this._syncedStop = time => {\n const seconds = this.context.transport.getSecondsAtTime(Math.max(time - this.sampleTime, 0));\n if (this._state.getValueAtTime(seconds) === "started") {\n this._stop(time);\n }\n };\n this.context.transport.on("start", this._syncedStart);\n this.context.transport.on("loopStart", this._syncedStart);\n this.context.transport.on("stop", this._syncedStop);\n this.context.transport.on("pause", this._syncedStop);\n this.context.transport.on("loopEnd", this._syncedStop);\n }\n return this;\n }\n /**\n * Unsync the source to the Transport. See Source.sync\n */\n unsync() {\n if (this._synced) {\n this.context.transport.off("stop", this._syncedStop);\n this.context.transport.off("pause", this._syncedStop);\n this.context.transport.off("loopEnd", this._syncedStop);\n this.context.transport.off("start", this._syncedStart);\n this.context.transport.off("loopStart", this._syncedStart);\n }\n this._synced = false;\n // clear all of the scheduled ids\n this._scheduled.forEach(id => this.context.transport.clear(id));\n this._scheduled = [];\n this._state.cancel(0);\n // stop it also\n this._stop(0);\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.onstop = Interface_noOp;\n this.unsync();\n this._volume.dispose();\n this._state.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Source.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/ToneBufferSource.js\n\n\n\n\n\n\n\n\n\n/**\n * Wrapper around the native BufferSourceNode.\n * @category Source\n */\nclass ToneBufferSource_ToneBufferSource extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneBufferSource_ToneBufferSource.getDefaults(), arguments, ["url", "onload"]));\n this.name = "ToneBufferSource";\n /**\n * The oscillator\n */\n this._source = this.context.createBufferSource();\n this._internalChannels = [this._source];\n /**\n * indicators if the source has started/stopped\n */\n this._sourceStarted = false;\n this._sourceStopped = false;\n const options = Defaults_optionsFromArguments(ToneBufferSource_ToneBufferSource.getDefaults(), arguments, ["url", "onload"]);\n ToneAudioNode_connect(this._source, this._gainNode);\n this._source.onended = () => this._stopSource();\n /**\n * The playbackRate of the buffer\n */\n this.playbackRate = new Param_Param({\n context: this.context,\n param: this._source.playbackRate,\n units: "positive",\n value: options.playbackRate,\n });\n // set some values initially\n this.loop = options.loop;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this._buffer = new ToneAudioBuffer_ToneAudioBuffer(options.url, options.onload, options.onerror);\n this._internalChannels.push(this._source);\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n url: new ToneAudioBuffer_ToneAudioBuffer(),\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n onload: Interface_noOp,\n onerror: Interface_noOp,\n playbackRate: 1,\n });\n }\n /**\n * The fadeIn time of the amplitude envelope.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(t) {\n this._fadeIn = t;\n }\n /**\n * The fadeOut time of the amplitude envelope.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(t) {\n this._fadeOut = t;\n }\n /**\n * The curve applied to the fades, either "linear" or "exponential"\n */\n get curve() {\n return this._curve;\n }\n set curve(t) {\n this._curve = t;\n }\n /**\n * Start the buffer\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset)\n * @param gain The gain to play the buffer back at.\n */\n start(time, offset, duration, gain = 1) {\n Debug_assert(this.buffer.loaded, "buffer is either not set or not loaded");\n const computedTime = this.toSeconds(time);\n // apply the gain envelope\n this._startGain(computedTime, gain);\n // if it\'s a loop the default offset is the loopstart point\n if (this.loop) {\n offset = Defaults_defaultArg(offset, this.loopStart);\n }\n else {\n // otherwise the default offset is 0\n offset = Defaults_defaultArg(offset, 0);\n }\n // make sure the offset is not less than 0\n let computedOffset = Math.max(this.toSeconds(offset), 0);\n // start the buffer source\n if (this.loop) {\n // modify the offset if it\'s greater than the loop time\n const loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration;\n const loopStart = this.toSeconds(this.loopStart);\n const loopDuration = loopEnd - loopStart;\n // move the offset back\n if (GTE(computedOffset, loopEnd)) {\n computedOffset = ((computedOffset - loopStart) % loopDuration) + loopStart;\n }\n // when the offset is very close to the duration, set it to 0\n if (EQ(computedOffset, this.buffer.duration)) {\n computedOffset = 0;\n }\n }\n // this.buffer.loaded would have return false if the AudioBuffer was undefined\n this._source.buffer = this.buffer.get();\n this._source.loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration;\n if (LT(computedOffset, this.buffer.duration)) {\n this._sourceStarted = true;\n this._source.start(computedTime, computedOffset);\n }\n // if a duration is given, schedule a stop\n if (TypeCheck_isDefined(duration)) {\n let computedDur = this.toSeconds(duration);\n // make sure it\'s never negative\n computedDur = Math.max(computedDur, 0);\n this.stop(computedTime + computedDur);\n }\n return this;\n }\n _stopSource(time) {\n if (!this._sourceStopped && this._sourceStarted) {\n this._sourceStopped = true;\n this._source.stop(this.toSeconds(time));\n this._onended();\n }\n }\n /**\n * If loop is true, the loop will start at this position.\n */\n get loopStart() {\n return this._source.loopStart;\n }\n set loopStart(loopStart) {\n this._source.loopStart = this.toSeconds(loopStart);\n }\n /**\n * If loop is true, the loop will end at this position.\n */\n get loopEnd() {\n return this._source.loopEnd;\n }\n set loopEnd(loopEnd) {\n this._source.loopEnd = this.toSeconds(loopEnd);\n }\n /**\n * The audio buffer belonging to the player.\n */\n get buffer() {\n return this._buffer;\n }\n set buffer(buffer) {\n this._buffer.set(buffer);\n }\n /**\n * If the buffer should loop once it\'s over.\n */\n get loop() {\n return this._source.loop;\n }\n set loop(loop) {\n this._source.loop = loop;\n if (this._sourceStarted) {\n this.cancelStop();\n }\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._source.onended = null;\n this._source.disconnect();\n this._buffer.dispose();\n this.playbackRate.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneBufferSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/Noise.js\n\n\n\n\n\n/**\n * Noise is a noise generator. It uses looped noise buffers to save on performance.\n * Noise supports the noise types: "pink", "white", and "brown". Read more about\n * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise).\n *\n * @example\n * // initialize the noise and start\n * const noise = new Tone.Noise("pink").start();\n * // make an autofilter to shape the noise\n * const autoFilter = new Tone.AutoFilter({\n * \tfrequency: "8n",\n * \tbaseFrequency: 200,\n * \toctaves: 8\n * }).toDestination().start();\n * // connect the noise\n * noise.connect(autoFilter);\n * // start the autofilter LFO\n * autoFilter.start();\n * @category Source\n */\nclass Noise_Noise extends (/* unused pure expression or super */ null && (Source)) {\n constructor() {\n super(optionsFromArguments(Noise_Noise.getDefaults(), arguments, ["type"]));\n this.name = "Noise";\n /**\n * Private reference to the source\n */\n this._source = null;\n const options = optionsFromArguments(Noise_Noise.getDefaults(), arguments, ["type"]);\n this._playbackRate = options.playbackRate;\n this.type = options.type;\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n fadeIn: 0,\n fadeOut: 0,\n playbackRate: 1,\n type: "white",\n });\n }\n /**\n * The type of the noise. Can be "white", "brown", or "pink".\n * @example\n * const noise = new Tone.Noise().toDestination().start();\n * noise.type = "brown";\n */\n get type() {\n return this._type;\n }\n set type(type) {\n assert(type in _noiseBuffers, "Noise: invalid type: " + type);\n if (this._type !== type) {\n this._type = type;\n // if it\'s playing, stop and restart it\n if (this.state === "started") {\n const now = this.now();\n this._stop(now);\n this._start(now);\n }\n }\n }\n /**\n * The playback rate of the noise. Affects\n * the "frequency" of the noise.\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n if (this._source) {\n this._source.playbackRate.value = rate;\n }\n }\n /**\n * internal start method\n */\n _start(time) {\n const buffer = _noiseBuffers[this._type];\n this._source = new ToneBufferSource({\n url: buffer,\n context: this.context,\n fadeIn: this._fadeIn,\n fadeOut: this._fadeOut,\n loop: true,\n onended: () => this.onstop(this),\n playbackRate: this._playbackRate,\n }).connect(this.output);\n this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001));\n }\n /**\n * internal stop method\n */\n _stop(time) {\n if (this._source) {\n this._source.stop(this.toSeconds(time));\n this._source = null;\n }\n }\n /**\n * The fadeIn time of the amplitude envelope.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(time) {\n this._fadeIn = time;\n if (this._source) {\n this._source.fadeIn = this._fadeIn;\n }\n }\n /**\n * The fadeOut time of the amplitude envelope.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(time) {\n this._fadeOut = time;\n if (this._source) {\n this._source.fadeOut = this._fadeOut;\n }\n }\n _restart(time) {\n // TODO could be optimized by cancelling the buffer source \'stop\'\n this._stop(time);\n this._start(time);\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n if (this._source) {\n this._source.disconnect();\n }\n return this;\n }\n}\n//--------------------\n// THE NOISE BUFFERS\n//--------------------\n// Noise buffer stats\nconst BUFFER_LENGTH = 44100 * 5;\nconst NUM_CHANNELS = 2;\n/**\n * Cache the noise buffers\n */\nconst _noiseCache = {\n brown: null,\n pink: null,\n white: null,\n};\n/**\n * The noise arrays. Generated on initialization.\n * borrowed heavily from https://github.com/zacharydenton/noise.js\n * (c) 2013 Zach Denton (MIT)\n */\nconst _noiseBuffers = {\n get brown() {\n if (!_noiseCache.brown) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n let lastOut = 0.0;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n const white = Math.random() * 2 - 1;\n channel[i] = (lastOut + (0.02 * white)) / 1.02;\n lastOut = channel[i];\n channel[i] *= 3.5; // (roughly) compensate for gain\n }\n }\n _noiseCache.brown = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.brown;\n },\n get pink() {\n if (!_noiseCache.pink) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n let b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n const white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.96900 * b2 + white * 0.1538520;\n b3 = 0.86650 * b3 + white * 0.3104856;\n b4 = 0.55000 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.0168980;\n channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n channel[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n }\n _noiseCache.pink = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.pink;\n },\n get white() {\n if (!_noiseCache.white) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n channel[i] = Math.random() * 2 - 1;\n }\n }\n _noiseCache.white = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.white;\n },\n};\n//# sourceMappingURL=Noise.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/UserMedia.js\n\n\n\n\n\n\n\n/**\n * UserMedia uses MediaDevices.getUserMedia to open up and external microphone or audio input.\n * Check [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n * to see which browsers are supported. Access to an external input\n * is limited to secure (HTTPS) connections.\n * @example\n * const meter = new Tone.Meter();\n * const mic = new Tone.UserMedia().connect(meter);\n * mic.open().then(() => {\n * \t// promise resolves when input is available\n * \tconsole.log("mic open");\n * \t// print the incoming mic levels in decibels\n * \tsetInterval(() => console.log(meter.getValue()), 100);\n * }).catch(e => {\n * \t// promise is rejected when the user doesn\'t have or allow mic access\n * \tconsole.log("mic not open");\n * });\n * @category Source\n */\nclass UserMedia extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]));\n this.name = "UserMedia";\n const options = optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]);\n this._volume = this.output = new Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n readOnly(this, "volume");\n this.mute = options.mute;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0\n });\n }\n /**\n * Open the media stream. If a string is passed in, it is assumed\n * to be the label or id of the stream, if a number is passed in,\n * it is the input number of the stream.\n * @param labelOrId The label or id of the audio input media device.\n * With no argument, the default stream is opened.\n * @return The promise is resolved when the stream is open.\n */\n open(labelOrId) {\n return __awaiter(this, void 0, void 0, function* () {\n assert(UserMedia.supported, "UserMedia is not supported");\n // close the previous stream\n if (this.state === "started") {\n this.close();\n }\n const devices = yield UserMedia.enumerateDevices();\n if (isNumber(labelOrId)) {\n this._device = devices[labelOrId];\n }\n else {\n this._device = devices.find((device) => {\n return device.label === labelOrId || device.deviceId === labelOrId;\n });\n // didn\'t find a matching device\n if (!this._device && devices.length > 0) {\n this._device = devices[0];\n }\n assert(isDefined(this._device), `No matching device ${labelOrId}`);\n }\n // do getUserMedia\n const constraints = {\n audio: {\n echoCancellation: false,\n sampleRate: this.context.sampleRate,\n noiseSuppression: false,\n mozNoiseSuppression: false,\n }\n };\n if (this._device) {\n // @ts-ignore\n constraints.audio.deviceId = this._device.deviceId;\n }\n const stream = yield navigator.mediaDevices.getUserMedia(constraints);\n // start a new source only if the previous one is closed\n if (!this._stream) {\n this._stream = stream;\n // Wrap a MediaStreamSourceNode around the live input stream.\n const mediaStreamNode = this.context.createMediaStreamSource(stream);\n // Connect the MediaStreamSourceNode to a gate gain node\n connect(mediaStreamNode, this.output);\n this._mediaStream = mediaStreamNode;\n }\n return this;\n });\n }\n /**\n * Close the media stream\n */\n close() {\n if (this._stream && this._mediaStream) {\n this._stream.getAudioTracks().forEach((track) => {\n track.stop();\n });\n this._stream = undefined;\n // remove the old media stream\n this._mediaStream.disconnect();\n this._mediaStream = undefined;\n }\n this._device = undefined;\n return this;\n }\n /**\n * Returns a promise which resolves with the list of audio input devices available.\n * @return The promise that is resolved with the devices\n * @example\n * Tone.UserMedia.enumerateDevices().then((devices) => {\n * \t// print the device labels\n * \tconsole.log(devices.map(device => device.label));\n * });\n */\n static enumerateDevices() {\n return __awaiter(this, void 0, void 0, function* () {\n const allDevices = yield navigator.mediaDevices.enumerateDevices();\n return allDevices.filter(device => {\n return device.kind === "audioinput";\n });\n });\n }\n /**\n * Returns the playback state of the source, "started" when the microphone is open\n * and "stopped" when the mic is closed.\n */\n get state() {\n return this._stream && this._stream.active ? "started" : "stopped";\n }\n /**\n * Returns an identifier for the represented device that is\n * persisted across sessions. It is un-guessable by other applications and\n * unique to the origin of the calling application. It is reset when the\n * user clears cookies (for Private Browsing, a different identifier is\n * used that is not persisted across sessions). Returns undefined when the\n * device is not open.\n */\n get deviceId() {\n if (this._device) {\n return this._device.deviceId;\n }\n else {\n return undefined;\n }\n }\n /**\n * Returns a group identifier. Two devices have the\n * same group identifier if they belong to the same physical device.\n * Returns null when the device is not open.\n */\n get groupId() {\n if (this._device) {\n return this._device.groupId;\n }\n else {\n return undefined;\n }\n }\n /**\n * Returns a label describing this device (for example "Built-in Microphone").\n * Returns undefined when the device is not open or label is not available\n * because of permissions.\n */\n get label() {\n if (this._device) {\n return this._device.label;\n }\n else {\n return undefined;\n }\n }\n /**\n * Mute the output.\n * @example\n * const mic = new Tone.UserMedia();\n * mic.open().then(() => {\n * \t// promise resolves when input is available\n * });\n * // mute the output\n * mic.mute = true;\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n dispose() {\n super.dispose();\n this.close();\n this._volume.dispose();\n this.volume.dispose();\n return this;\n }\n /**\n * If getUserMedia is supported by the browser.\n */\n static get supported() {\n return isDefined(navigator.mediaDevices) &&\n isDefined(navigator.mediaDevices.getUserMedia);\n }\n}\n//# sourceMappingURL=UserMedia.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/OscillatorInterface.js\n\n\n/**\n * Render a segment of the oscillator to an offline context and return the results as an array\n */\nfunction generateWaveform(instance, length) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const duration = length / instance.context.sampleRate;\n const context = new OfflineContext_OfflineContext(1, duration, instance.context.sampleRate);\n const clone = new instance.constructor(Object.assign(instance.get(), {\n // should do 2 iterations\n frequency: 2 / duration,\n // zero out the detune\n detune: 0,\n context\n })).toDestination();\n clone.start(0);\n const buffer = yield context.render();\n return buffer.getChannelData(0);\n });\n}\n//# sourceMappingURL=OscillatorInterface.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/ToneOscillatorNode.js\n\n\n\n\n\n/**\n * Wrapper around the native fire-and-forget OscillatorNode.\n * Adds the ability to reschedule the stop method.\n * ***[[Oscillator]] is better for most use-cases***\n * @category Source\n */\nclass ToneOscillatorNode_ToneOscillatorNode extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneOscillatorNode_ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "ToneOscillatorNode";\n /**\n * The oscillator\n */\n this._oscillator = this.context.createOscillator();\n this._internalChannels = [this._oscillator];\n const options = Defaults_optionsFromArguments(ToneOscillatorNode_ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]);\n ToneAudioNode_connect(this._oscillator, this._gainNode);\n this.type = options.type;\n this.frequency = new Param_Param({\n context: this.context,\n param: this._oscillator.frequency,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Param_Param({\n context: this.context,\n param: this._oscillator.detune,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, ["frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n detune: 0,\n frequency: 440,\n type: "sine",\n });\n }\n /**\n * Start the oscillator node at the given time\n * @param time When to start the oscillator\n */\n start(time) {\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n this._startGain(computedTime);\n this._oscillator.start(computedTime);\n return this;\n }\n _stopSource(time) {\n this._oscillator.stop(time);\n }\n /**\n * Sets an arbitrary custom periodic waveform given a PeriodicWave.\n * @param periodicWave PeriodicWave should be created with context.createPeriodicWave\n */\n setPeriodicWave(periodicWave) {\n this._oscillator.setPeriodicWave(periodicWave);\n return this;\n }\n /**\n * The oscillator type. Either \'sine\', \'sawtooth\', \'square\', or \'triangle\'\n */\n get type() {\n return this._oscillator.type;\n }\n set type(type) {\n this._oscillator.type = type;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n if (this.state === "started") {\n this.stop();\n }\n this._oscillator.disconnect();\n this.frequency.dispose();\n this.detune.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneOscillatorNode.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/Oscillator.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Oscillator supports a number of features including\n * phase rotation, multiple oscillator types (see Oscillator.type),\n * and Transport syncing (see Oscillator.syncFrequency).\n *\n * @example\n * // make and start a 440hz sine tone\n * const osc = new Tone.Oscillator(440, "sine").toDestination().start();\n * @category Source\n */\nclass Oscillator_Oscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(Oscillator_Oscillator.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "Oscillator";\n /**\n * the main oscillator\n */\n this._oscillator = null;\n const options = Defaults_optionsFromArguments(Oscillator_Oscillator.getDefaults(), arguments, ["frequency", "type"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n Interface_readOnly(this, "frequency");\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, "detune");\n this._partials = options.partials;\n this._partialCount = options.partialCount;\n this._type = options.type;\n if (options.partialCount && options.type !== "custom") {\n this._type = this.baseType + options.partialCount.toString();\n }\n this.phase = options.phase;\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n partialCount: 0,\n partials: [],\n phase: 0,\n type: "sine",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n const computedTime = this.toSeconds(time);\n // new oscillator with previous values\n const oscillator = new ToneOscillatorNode_ToneOscillatorNode({\n context: this.context,\n onended: () => this.onstop(this),\n });\n this._oscillator = oscillator;\n if (this._wave) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n else {\n this._oscillator.type = this._type;\n }\n // connect the control signal to the oscillator frequency & detune\n this._oscillator.connect(this.output);\n this.frequency.connect(this._oscillator.frequency);\n this.detune.connect(this._oscillator.detune);\n // start the oscillator\n this._oscillator.start(computedTime);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n const computedTime = this.toSeconds(time);\n if (this._oscillator) {\n this._oscillator.stop(computedTime);\n }\n }\n /**\n * Restart the oscillator. Does not stop the oscillator, but instead\n * just cancels any scheduled \'stop\' from being invoked.\n */\n _restart(time) {\n const computedTime = this.toSeconds(time);\n this.log("restart", computedTime);\n if (this._oscillator) {\n this._oscillator.cancelStop();\n }\n this._state.cancel(computedTime);\n return this;\n }\n /**\n * Sync the signal to the Transport\'s bpm. Any changes to the transports bpm,\n * will also affect the oscillators frequency.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * osc.frequency.value = 440;\n * // the ratio between the bpm and the frequency will be maintained\n * osc.syncFrequency();\n * // double the tempo\n * Tone.Transport.bpm.value *= 2;\n * // the frequency of the oscillator is doubled to 880\n */\n syncFrequency() {\n this.context.transport.syncSignal(this.frequency);\n return this;\n }\n /**\n * Unsync the oscillator\'s frequency from the Transport.\n * See Oscillator.syncFrequency\n */\n unsyncFrequency() {\n this.context.transport.unsyncSignal(this.frequency);\n return this;\n }\n /**\n * Get a cached periodic wave. Avoids having to recompute\n * the oscillator values when they have already been computed\n * with the same values.\n */\n _getCachedPeriodicWave() {\n if (this._type === "custom") {\n const oscProps = Oscillator_Oscillator._periodicWaveCache.find(description => {\n return description.phase === this._phase &&\n deepEquals(description.partials, this._partials);\n });\n return oscProps;\n }\n else {\n const oscProps = Oscillator_Oscillator._periodicWaveCache.find(description => {\n return description.type === this._type &&\n description.phase === this._phase;\n });\n this._partialCount = oscProps ? oscProps.partialCount : this._partialCount;\n return oscProps;\n }\n }\n get type() {\n return this._type;\n }\n set type(type) {\n this._type = type;\n const isBasicType = ["sine", "square", "sawtooth", "triangle"].indexOf(type) !== -1;\n if (this._phase === 0 && isBasicType) {\n this._wave = undefined;\n this._partialCount = 0;\n // just go with the basic approach\n if (this._oscillator !== null) {\n // already tested that it\'s a basic type\n this._oscillator.type = type;\n }\n }\n else {\n // first check if the value is cached\n const cache = this._getCachedPeriodicWave();\n if (TypeCheck_isDefined(cache)) {\n const { partials, wave } = cache;\n this._wave = wave;\n this._partials = partials;\n if (this._oscillator !== null) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n }\n else {\n const [real, imag] = this._getRealImaginary(type, this._phase);\n const periodicWave = this.context.createPeriodicWave(real, imag);\n this._wave = periodicWave;\n if (this._oscillator !== null) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n // set the cache\n Oscillator_Oscillator._periodicWaveCache.push({\n imag,\n partialCount: this._partialCount,\n partials: this._partials,\n phase: this._phase,\n real,\n type: this._type,\n wave: this._wave,\n });\n if (Oscillator_Oscillator._periodicWaveCache.length > 100) {\n Oscillator_Oscillator._periodicWaveCache.shift();\n }\n }\n }\n }\n get baseType() {\n return this._type.replace(this.partialCount.toString(), "");\n }\n set baseType(baseType) {\n if (this.partialCount && this._type !== "custom" && baseType !== "custom") {\n this.type = baseType + this.partialCount;\n }\n else {\n this.type = baseType;\n }\n }\n get partialCount() {\n return this._partialCount;\n }\n set partialCount(p) {\n Debug_assertRange(p, 0);\n let type = this._type;\n const partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(this._type);\n if (partial) {\n type = partial[1];\n }\n if (this._type !== "custom") {\n if (p === 0) {\n this.type = type;\n }\n else {\n this.type = type + p.toString();\n }\n }\n else {\n // extend or shorten the partials array\n const fullPartials = new Float32Array(p);\n // copy over the partials array\n this._partials.forEach((v, i) => fullPartials[i] = v);\n this._partials = Array.from(fullPartials);\n this.type = this._type;\n }\n }\n /**\n * Returns the real and imaginary components based\n * on the oscillator type.\n * @returns [real: Float32Array, imaginary: Float32Array]\n */\n _getRealImaginary(type, phase) {\n const fftSize = 4096;\n let periodicWaveSize = fftSize / 2;\n const real = new Float32Array(periodicWaveSize);\n const imag = new Float32Array(periodicWaveSize);\n let partialCount = 1;\n if (type === "custom") {\n partialCount = this._partials.length + 1;\n this._partialCount = this._partials.length;\n periodicWaveSize = partialCount;\n // if the partial count is 0, don\'t bother doing any computation\n if (this._partials.length === 0) {\n return [real, imag];\n }\n }\n else {\n const partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(type);\n if (partial) {\n partialCount = parseInt(partial[2], 10) + 1;\n this._partialCount = parseInt(partial[2], 10);\n type = partial[1];\n partialCount = Math.max(partialCount, 2);\n periodicWaveSize = partialCount;\n }\n else {\n this._partialCount = 0;\n }\n this._partials = [];\n }\n for (let n = 1; n < periodicWaveSize; ++n) {\n const piFactor = 2 / (n * Math.PI);\n let b;\n switch (type) {\n case "sine":\n b = (n <= partialCount) ? 1 : 0;\n this._partials[n - 1] = b;\n break;\n case "square":\n b = (n & 1) ? 2 * piFactor : 0;\n this._partials[n - 1] = b;\n break;\n case "sawtooth":\n b = piFactor * ((n & 1) ? 1 : -1);\n this._partials[n - 1] = b;\n break;\n case "triangle":\n if (n & 1) {\n b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1);\n }\n else {\n b = 0;\n }\n this._partials[n - 1] = b;\n break;\n case "custom":\n b = this._partials[n - 1];\n break;\n default:\n throw new TypeError("Oscillator: invalid type: " + type);\n }\n if (b !== 0) {\n real[n] = -b * Math.sin(phase * n);\n imag[n] = b * Math.cos(phase * n);\n }\n else {\n real[n] = 0;\n imag[n] = 0;\n }\n }\n return [real, imag];\n }\n /**\n * Compute the inverse FFT for a given phase.\n */\n _inverseFFT(real, imag, phase) {\n let sum = 0;\n const len = real.length;\n for (let i = 0; i < len; i++) {\n sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase);\n }\n return sum;\n }\n /**\n * Returns the initial value of the oscillator when stopped.\n * E.g. a "sine" oscillator with phase = 90 would return an initial value of -1.\n */\n getInitialValue() {\n const [real, imag] = this._getRealImaginary(this._type, 0);\n let maxValue = 0;\n const twoPi = Math.PI * 2;\n const testPositions = 32;\n // check for peaks in 16 places\n for (let i = 0; i < testPositions; i++) {\n maxValue = Math.max(this._inverseFFT(real, imag, (i / testPositions) * twoPi), maxValue);\n }\n return Math_clamp(-this._inverseFFT(real, imag, this._phase) / maxValue, -1, 1);\n }\n get partials() {\n return this._partials.slice(0, this.partialCount);\n }\n set partials(partials) {\n this._partials = partials;\n this._partialCount = this._partials.length;\n if (partials.length) {\n this.type = "custom";\n }\n }\n get phase() {\n return this._phase * (180 / Math.PI);\n }\n set phase(phase) {\n this._phase = phase * Math.PI / 180;\n // reset the type\n this.type = this._type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n dispose() {\n super.dispose();\n if (this._oscillator !== null) {\n this._oscillator.dispose();\n }\n this._wave = undefined;\n this.frequency.dispose();\n this.detune.dispose();\n return this;\n }\n}\n/**\n * Cache the periodic waves to avoid having to redo computations\n */\nOscillator_Oscillator._periodicWaveCache = [];\n//# sourceMappingURL=Oscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/SignalOperator.js\n\n\n\n/**\n * A signal operator has an input and output and modifies the signal.\n */\nclass SignalOperator_SignalOperator extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(SignalOperator_SignalOperator.getDefaults(), arguments, ["context"])));\n }\n connect(destination, outputNum = 0, inputNum = 0) {\n Signal_connectSignal(this, destination, outputNum, inputNum);\n return this;\n }\n}\n//# sourceMappingURL=SignalOperator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/WaveShaper.js\n\n\n\n\n\n/**\n * Wraps the native Web Audio API\n * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // multiply the output of the signal by 2 using the waveshaper\'s function\n * const timesTwo = new Tone.WaveShaper((val) => val * 2, 2048).connect(osc.frequency);\n * const signal = new Tone.Signal(440).connect(timesTwo);\n * @category Signal\n */\nclass WaveShaper_WaveShaper extends SignalOperator_SignalOperator {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(WaveShaper_WaveShaper.getDefaults(), arguments, ["mapping", "length"])));\n this.name = "WaveShaper";\n /**\n * the waveshaper node\n */\n this._shaper = this.context.createWaveShaper();\n /**\n * The input to the waveshaper node.\n */\n this.input = this._shaper;\n /**\n * The output from the waveshaper node\n */\n this.output = this._shaper;\n const options = Defaults_optionsFromArguments(WaveShaper_WaveShaper.getDefaults(), arguments, ["mapping", "length"]);\n if (TypeCheck_isArray(options.mapping) || options.mapping instanceof Float32Array) {\n this.curve = Float32Array.from(options.mapping);\n }\n else if (isFunction(options.mapping)) {\n this.setMap(options.mapping, options.length);\n }\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n length: 1024,\n });\n }\n /**\n * Uses a mapping function to set the value of the curve.\n * @param mapping The function used to define the values.\n * The mapping function take two arguments:\n * the first is the value at the current position\n * which goes from -1 to 1 over the number of elements\n * in the curve array. The second argument is the array position.\n * @example\n * const shaper = new Tone.WaveShaper();\n * // map the input signal from [-1, 1] to [0, 10]\n * shaper.setMap((val, index) => (val + 1) * 5);\n */\n setMap(mapping, length = 1024) {\n const array = new Float32Array(length);\n for (let i = 0, len = length; i < len; i++) {\n const normalized = (i / (len - 1)) * 2 - 1;\n array[i] = mapping(normalized, i);\n }\n this.curve = array;\n return this;\n }\n /**\n * The array to set as the waveshaper curve. For linear curves\n * array length does not make much difference, but for complex curves\n * longer arrays will provide smoother interpolation.\n */\n get curve() {\n return this._shaper.curve;\n }\n set curve(mapping) {\n this._shaper.curve = mapping;\n }\n /**\n * Specifies what type of oversampling (if any) should be used when\n * applying the shaping curve. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n const isOverSampleType = ["none", "2x", "4x"].some(str => str.includes(oversampling));\n Debug_assert(isOverSampleType, "oversampling must be either \'none\', \'2x\', or \'4x\'");\n this._shaper.oversample = oversampling;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._shaper.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=WaveShaper.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/AudioToGain.js\n\n\n/**\n * AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1].\n * See [[GainToAudio]].\n * @category Signal\n */\nclass AudioToGain_AudioToGain extends SignalOperator_SignalOperator {\n constructor() {\n super(...arguments);\n this.name = "AudioToGain";\n /**\n * The node which converts the audio ranges\n */\n this._norm = new WaveShaper_WaveShaper({\n context: this.context,\n mapping: x => (x + 1) / 2,\n });\n /**\n * The AudioRange input [-1, 1]\n */\n this.input = this._norm;\n /**\n * The GainRange output [0, 1]\n */\n this.output = this._norm;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._norm.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AudioToGain.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Multiply.js\n\n\n\n/**\n * Multiply two incoming signals. Or, if a number is given in the constructor,\n * multiplies the incoming signal by that value.\n *\n * @example\n * // multiply two signals\n * const mult = new Tone.Multiply();\n * const sigA = new Tone.Signal(3);\n * const sigB = new Tone.Signal(4);\n * sigA.connect(mult);\n * sigB.connect(mult.factor);\n * // output of mult is 12.\n * @example\n * // multiply a signal and a number\n * const mult = new Tone.Multiply(10);\n * const sig = new Tone.Signal(2).connect(mult);\n * // the output of mult is 20.\n * @category Signal\n */\nclass Multiply_Multiply extends Signal_Signal {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(Multiply_Multiply.getDefaults(), arguments, ["value"])));\n this.name = "Multiply";\n /**\n * Indicates if the value should be overridden on connection\n */\n this.override = false;\n const options = Defaults_optionsFromArguments(Multiply_Multiply.getDefaults(), arguments, ["value"]);\n this._mult = this.input = this.output = new Gain_Gain({\n context: this.context,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n this.factor = this._param = this._mult.gain;\n this.factor.setValueAtTime(options.value, 0);\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._mult.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Multiply.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/AMOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * An amplitude modulated oscillator node. It is implemented with\n * two oscillators, one which modulators the other\'s amplitude\n * through a gain node.\n * ```\n * +-------------+ +----------+\n * | Carrier Osc +>------\x3e GainNode |\n * +-------------+ | +---\x3eOutput\n * +---\x3e gain |\n * +---------------+ | +----------+\n * | Modulator Osc +>---+\n * +---------------+\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst amOsc = new Tone.AMOscillator(30, "sine", "square").toDestination().start();\n * }, 0.2, 1);\n * @category Source\n */\nclass AMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));\n this.name = "AMOscillator";\n /**\n * convert the -1,1 output to 0,1\n */\n this._modulationScale = new AudioToGain_AudioToGain({ context: this.context });\n /**\n * the node where the modulation happens\n */\n this._modulationNode = new Gain_Gain({\n context: this.context,\n });\n const options = Defaults_optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);\n this._carrier = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: options.type,\n });\n this.frequency = this._carrier.frequency,\n this.detune = this._carrier.detune;\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n phase: options.phase,\n type: options.modulationType,\n });\n this.harmonicity = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n // connections\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n this._carrier.chain(this._modulationNode, this.output);\n Interface_readOnly(this, ["frequency", "detune", "harmonicity"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n harmonicity: 1,\n modulationType: "square",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._modulator.start(time);\n this._carrier.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n this._modulator.stop(time);\n this._carrier.stop(time);\n }\n _restart(time) {\n this._modulator.restart(time);\n this._carrier.restart(time);\n }\n /**\n * The type of the carrier oscillator\n */\n get type() {\n return this._carrier.type;\n }\n set type(type) {\n this._carrier.type = type;\n }\n get baseType() {\n return this._carrier.baseType;\n }\n set baseType(baseType) {\n this._carrier.baseType = baseType;\n }\n get partialCount() {\n return this._carrier.partialCount;\n }\n set partialCount(partialCount) {\n this._carrier.partialCount = partialCount;\n }\n /**\n * The type of the modulator oscillator\n */\n get modulationType() {\n return this._modulator.type;\n }\n set modulationType(type) {\n this._modulator.type = type;\n }\n get phase() {\n return this._carrier.phase;\n }\n set phase(phase) {\n this._carrier.phase = phase;\n this._modulator.phase = phase;\n }\n get partials() {\n return this._carrier.partials;\n }\n set partials(partials) {\n this._carrier.partials = partials;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this.harmonicity.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this._modulationNode.dispose();\n this._modulationScale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/FMOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * FMOscillator implements a frequency modulation synthesis\n * ```\n * +-------------+\n * +---------------+ +-------------+ | Carrier Osc |\n * | Modulator Osc +>-------\x3e GainNode | | +---\x3eOutput\n * +---------------+ | +>----\x3e frequency |\n * +--\x3e gain | +-------------+\n * | +-------------+\n * +-----------------+ |\n * | modulationIndex +>--+\n * +-----------------+\n * ```\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst fmOsc = new Tone.FMOscillator({\n * \t\tfrequency: 200,\n * \t\ttype: "square",\n * \t\tmodulationType: "triangle",\n * \t\tharmonicity: 0.2,\n * \t\tmodulationIndex: 3\n * \t}).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass FMOscillator_FMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(FMOscillator_FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));\n this.name = "FMOscillator";\n /**\n * the node where the modulation happens\n */\n this._modulationNode = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n const options = Defaults_optionsFromArguments(FMOscillator_FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);\n this._carrier = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: 0,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: options.type,\n });\n this.detune = this._carrier.detune;\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n phase: options.phase,\n type: options.modulationType,\n });\n this.harmonicity = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n this.modulationIndex = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.modulationIndex,\n });\n // connections\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.frequency.chain(this.modulationIndex, this._modulationNode);\n this._modulator.connect(this._modulationNode.gain);\n this._modulationNode.connect(this._carrier.frequency);\n this._carrier.connect(this.output);\n this.detune.connect(this._modulator.detune);\n Interface_readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n harmonicity: 1,\n modulationIndex: 2,\n modulationType: "square",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._modulator.start(time);\n this._carrier.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n this._modulator.stop(time);\n this._carrier.stop(time);\n }\n _restart(time) {\n this._modulator.restart(time);\n this._carrier.restart(time);\n return this;\n }\n get type() {\n return this._carrier.type;\n }\n set type(type) {\n this._carrier.type = type;\n }\n get baseType() {\n return this._carrier.baseType;\n }\n set baseType(baseType) {\n this._carrier.baseType = baseType;\n }\n get partialCount() {\n return this._carrier.partialCount;\n }\n set partialCount(partialCount) {\n this._carrier.partialCount = partialCount;\n }\n /**\n * The type of the modulator oscillator\n */\n get modulationType() {\n return this._modulator.type;\n }\n set modulationType(type) {\n this._modulator.type = type;\n }\n get phase() {\n return this._carrier.phase;\n }\n set phase(phase) {\n this._carrier.phase = phase;\n this._modulator.phase = phase;\n }\n get partials() {\n return this._carrier.partials;\n }\n set partials(partials) {\n this._carrier.partials = partials;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.harmonicity.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this._modulationNode.dispose();\n this.modulationIndex.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/PulseOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * PulseOscillator is an oscillator with control over pulse width,\n * also known as the duty cycle. At 50% duty cycle (width = 0) the wave is\n * a square wave.\n * [Read more](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/).\n * ```\n * width = -0.25 width = 0.0 width = 0.25\n *\n * +-----+ +-------+ + +-------+ +-+\n * | | | | | | |\n * | | | | | | |\n * +-+ +-------+ + +-------+ +-----+\n *\n *\n * width = -0.5 width = 0.5\n *\n * +---+ +-------+ +---+\n * | | | |\n * | | | |\n * +---+ +-------+ +---+\n *\n *\n * width = -0.75 width = 0.75\n *\n * +-+ +-------+ +-----+\n * | | | |\n * | | | |\n * +-----+ +-------+ +-+\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst pulse = new Tone.PulseOscillator(50, 0.4).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass PulseOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]));\n this.name = "PulseOscillator";\n /**\n * gate the width amount\n */\n this._widthGate = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * Threshold the signal to turn it into a square\n */\n this._thresh = new WaveShaper_WaveShaper({\n context: this.context,\n mapping: val => val <= 0 ? -1 : 1,\n });\n const options = Defaults_optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]);\n this.width = new Signal_Signal({\n context: this.context,\n units: "audioRange",\n value: options.width,\n });\n this._triangle = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: "triangle",\n });\n this.frequency = this._triangle.frequency;\n this.detune = this._triangle.detune;\n // connections\n this._triangle.chain(this._thresh, this.output);\n this.width.chain(this._widthGate, this._thresh);\n Interface_readOnly(this, ["width", "frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n phase: 0,\n type: "pulse",\n width: 0.2,\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._triangle.start(time);\n this._widthGate.gain.setValueAtTime(1, time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._triangle.stop(time);\n // the width is still connected to the output.\n // that needs to be stopped also\n this._widthGate.gain.cancelScheduledValues(time);\n this._widthGate.gain.setValueAtTime(0, time);\n }\n _restart(time) {\n this._triangle.restart(time);\n this._widthGate.gain.cancelScheduledValues(time);\n this._widthGate.gain.setValueAtTime(1, time);\n }\n /**\n * The phase of the oscillator in degrees.\n */\n get phase() {\n return this._triangle.phase;\n }\n set phase(phase) {\n this._triangle.phase = phase;\n }\n /**\n * The type of the oscillator. Always returns "pulse".\n */\n get type() {\n return "pulse";\n }\n /**\n * The baseType of the oscillator. Always returns "pulse".\n */\n get baseType() {\n return "pulse";\n }\n /**\n * The partials of the waveform. Cannot set partials for this waveform type\n */\n get partials() {\n return [];\n }\n /**\n * No partials for this waveform type.\n */\n get partialCount() {\n return 0;\n }\n /**\n * *Internal use* The carrier oscillator type is fed through the\n * waveshaper node to create the pulse. Using different carrier oscillators\n * changes oscillator\'s behavior.\n */\n set carrierType(type) {\n this._triangle.type = type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up method.\n */\n dispose() {\n super.dispose();\n this._triangle.dispose();\n this.width.dispose();\n this._widthGate.dispose();\n this._thresh.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PulseOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/FatOscillator.js\n\n\n\n\n\n\n\n\n/**\n * FatOscillator is an array of oscillators with detune spread between the oscillators\n * @example\n * const fatOsc = new Tone.FatOscillator("Ab3", "sawtooth", 40).toDestination().start();\n * @category Source\n */\nclass FatOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]));\n this.name = "FatOscillator";\n /**\n * The array of oscillators\n */\n this._oscillators = [];\n const options = Defaults_optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this._spread = options.spread;\n this._type = options.type;\n this._phase = options.phase;\n this._partials = options.partials;\n this._partialCount = options.partialCount;\n // set the count initially\n this.count = options.count;\n Interface_readOnly(this, ["frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n count: 3,\n spread: 20,\n type: "sawtooth",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._forEach(osc => osc.start(time));\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._forEach(osc => osc.stop(time));\n }\n _restart(time) {\n this._forEach(osc => osc.restart(time));\n }\n /**\n * Iterate over all of the oscillators\n */\n _forEach(iterator) {\n for (let i = 0; i < this._oscillators.length; i++) {\n iterator(this._oscillators[i], i);\n }\n }\n /**\n * The type of the oscillator\n */\n get type() {\n return this._type;\n }\n set type(type) {\n this._type = type;\n this._forEach(osc => osc.type = type);\n }\n /**\n * The detune spread between the oscillators. If "count" is\n * set to 3 oscillators and the "spread" is set to 40,\n * the three oscillators would be detuned like this: [-20, 0, 20]\n * for a total detune spread of 40 cents.\n * @example\n * const fatOsc = new Tone.FatOscillator().toDestination().start();\n * fatOsc.spread = 70;\n */\n get spread() {\n return this._spread;\n }\n set spread(spread) {\n this._spread = spread;\n if (this._oscillators.length > 1) {\n const start = -spread / 2;\n const step = spread / (this._oscillators.length - 1);\n this._forEach((osc, i) => osc.detune.value = start + step * i);\n }\n }\n /**\n * The number of detuned oscillators. Must be an integer greater than 1.\n * @example\n * const fatOsc = new Tone.FatOscillator("C#3", "sawtooth").toDestination().start();\n * // use 4 sawtooth oscillators\n * fatOsc.count = 4;\n */\n get count() {\n return this._oscillators.length;\n }\n set count(count) {\n Debug_assertRange(count, 1);\n if (this._oscillators.length !== count) {\n // dispose the previous oscillators\n this._forEach(osc => osc.dispose());\n this._oscillators = [];\n for (let i = 0; i < count; i++) {\n const osc = new Oscillator_Oscillator({\n context: this.context,\n volume: -6 - count * 1.1,\n type: this._type,\n phase: this._phase + (i / count) * 360,\n partialCount: this._partialCount,\n onstop: i === 0 ? () => this.onstop(this) : Interface_noOp,\n });\n if (this.type === "custom") {\n osc.partials = this._partials;\n }\n this.frequency.connect(osc.frequency);\n this.detune.connect(osc.detune);\n osc.detune.overridden = false;\n osc.connect(this.output);\n this._oscillators[i] = osc;\n }\n // set the spread\n this.spread = this._spread;\n if (this.state === "started") {\n this._forEach(osc => osc.start());\n }\n }\n }\n get phase() {\n return this._phase;\n }\n set phase(phase) {\n this._phase = phase;\n this._forEach((osc, i) => osc.phase = this._phase + (i / this.count) * 360);\n }\n get baseType() {\n return this._oscillators[0].baseType;\n }\n set baseType(baseType) {\n this._forEach(osc => osc.baseType = baseType);\n this._type = this._oscillators[0].type;\n }\n get partials() {\n return this._oscillators[0].partials;\n }\n set partials(partials) {\n this._partials = partials;\n this._partialCount = this._partials.length;\n if (partials.length) {\n this._type = "custom";\n this._forEach(osc => osc.partials = partials);\n }\n }\n get partialCount() {\n return this._oscillators[0].partialCount;\n }\n set partialCount(partialCount) {\n this._partialCount = partialCount;\n this._forEach(osc => osc.partialCount = partialCount);\n this._type = this._oscillators[0].type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this._forEach(osc => osc.dispose());\n return this;\n }\n}\n//# sourceMappingURL=FatOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/PWMOscillator.js\n\n\n\n\n\n\n\n\n/**\n * PWMOscillator modulates the width of a Tone.PulseOscillator\n * at the modulationFrequency. This has the effect of continuously\n * changing the timbre of the oscillator by altering the harmonics\n * generated.\n * @example\n * return Tone.Offline(() => {\n * \tconst pwm = new Tone.PWMOscillator(60, 0.3).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass PWMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]));\n this.name = "PWMOscillator";\n this.sourceType = "pwm";\n /**\n * Scale the oscillator so it doesn\'t go silent\n * at the extreme values.\n */\n this._scale = new Multiply_Multiply({\n context: this.context,\n value: 2,\n });\n const options = Defaults_optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]);\n this._pulse = new PulseOscillator({\n context: this.context,\n frequency: options.modulationFrequency,\n });\n // change the pulse oscillator type\n this._pulse.carrierType = "sine";\n this.modulationFrequency = this._pulse.frequency;\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n });\n this.frequency = this._modulator.frequency;\n this.detune = this._modulator.detune;\n // connections\n this._modulator.chain(this._scale, this._pulse.width);\n this._pulse.connect(this.output);\n Interface_readOnly(this, ["modulationFrequency", "frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n modulationFrequency: 0.4,\n phase: 0,\n type: "pwm",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._modulator.start(time);\n this._pulse.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._modulator.stop(time);\n this._pulse.stop(time);\n }\n /**\n * restart the oscillator\n */\n _restart(time) {\n this._modulator.restart(time);\n this._pulse.restart(time);\n }\n /**\n * The type of the oscillator. Always returns "pwm".\n */\n get type() {\n return "pwm";\n }\n /**\n * The baseType of the oscillator. Always returns "pwm".\n */\n get baseType() {\n return "pwm";\n }\n /**\n * The partials of the waveform. Cannot set partials for this waveform type\n */\n get partials() {\n return [];\n }\n /**\n * No partials for this waveform type.\n */\n get partialCount() {\n return 0;\n }\n /**\n * The phase of the oscillator in degrees.\n */\n get phase() {\n return this._modulator.phase;\n }\n set phase(phase) {\n this._modulator.phase = phase;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._pulse.dispose();\n this._scale.dispose();\n this._modulator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PWMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/OmniOscillator.js\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst OmniOscillatorSourceMap = {\n am: AMOscillator,\n fat: FatOscillator,\n fm: FMOscillator_FMOscillator,\n oscillator: Oscillator_Oscillator,\n pulse: PulseOscillator,\n pwm: PWMOscillator,\n};\n/**\n * OmniOscillator aggregates all of the oscillator types into one.\n * @example\n * return Tone.Offline(() => {\n * \tconst omniOsc = new Tone.OmniOscillator("C#4", "pwm").toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass OmniOscillator_OmniOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(OmniOscillator_OmniOscillator.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "OmniOscillator";\n const options = Defaults_optionsFromArguments(OmniOscillator_OmniOscillator.getDefaults(), arguments, ["frequency", "type"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, ["frequency", "detune"]);\n // set the options\n this.set(options);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), FMOscillator_FMOscillator.getDefaults(), AMOscillator.getDefaults(), FatOscillator.getDefaults(), PulseOscillator.getDefaults(), PWMOscillator.getDefaults());\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._oscillator.start(time);\n }\n /**\n * start the oscillator\n */\n _stop(time) {\n this._oscillator.stop(time);\n }\n _restart(time) {\n this._oscillator.restart(time);\n return this;\n }\n /**\n * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or\n * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator\n * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the\n * oscillator\'s class are accessible when the oscillator is set to that type, but throws an error\n * when it\'s not.\n * @example\n * const omniOsc = new Tone.OmniOscillator().toDestination().start();\n * omniOsc.type = "pwm";\n * // modulationFrequency is parameter which is available\n * // only when the type is "pwm".\n * omniOsc.modulationFrequency.value = 0.5;\n */\n get type() {\n let prefix = "";\n if (["am", "fm", "fat"].some(p => this._sourceType === p)) {\n prefix = this._sourceType;\n }\n return prefix + this._oscillator.type;\n }\n set type(type) {\n if (type.substr(0, 2) === "fm") {\n this._createNewOscillator("fm");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(2);\n }\n else if (type.substr(0, 2) === "am") {\n this._createNewOscillator("am");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(2);\n }\n else if (type.substr(0, 3) === "fat") {\n this._createNewOscillator("fat");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(3);\n }\n else if (type === "pwm") {\n this._createNewOscillator("pwm");\n this._oscillator = this._oscillator;\n }\n else if (type === "pulse") {\n this._createNewOscillator("pulse");\n }\n else {\n this._createNewOscillator("oscillator");\n this._oscillator = this._oscillator;\n this._oscillator.type = type;\n }\n }\n /**\n * The value is an empty array when the type is not "custom".\n * This is not available on "pwm" and "pulse" oscillator types.\n * See [[Oscillator.partials]]\n */\n get partials() {\n return this._oscillator.partials;\n }\n set partials(partials) {\n if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) {\n this._oscillator.partials = partials;\n }\n }\n get partialCount() {\n return this._oscillator.partialCount;\n }\n set partialCount(partialCount) {\n if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) {\n this._oscillator.partialCount = partialCount;\n }\n }\n set(props) {\n // make sure the type is set first\n if (Reflect.has(props, "type") && props.type) {\n this.type = props.type;\n }\n // then set the rest\n super.set(props);\n return this;\n }\n /**\n * connect the oscillator to the frequency and detune signals\n */\n _createNewOscillator(oscType) {\n if (oscType !== this._sourceType) {\n this._sourceType = oscType;\n const OscConstructor = OmniOscillatorSourceMap[oscType];\n // short delay to avoid clicks on the change\n const now = this.now();\n if (this._oscillator) {\n const oldOsc = this._oscillator;\n oldOsc.stop(now);\n // dispose the old one\n this.context.setTimeout(() => oldOsc.dispose(), this.blockTime);\n }\n this._oscillator = new OscConstructor({\n context: this.context,\n });\n this.frequency.connect(this._oscillator.frequency);\n this.detune.connect(this._oscillator.detune);\n this._oscillator.connect(this.output);\n this._oscillator.onstop = () => this.onstop(this);\n if (this.state === "started") {\n this._oscillator.start(now);\n }\n }\n }\n get phase() {\n return this._oscillator.phase;\n }\n set phase(phase) {\n this._oscillator.phase = phase;\n }\n /**\n * The source type of the oscillator.\n * @example\n * const omniOsc = new Tone.OmniOscillator(440, "fmsquare");\n * console.log(omniOsc.sourceType); // \'fm\'\n */\n get sourceType() {\n return this._sourceType;\n }\n set sourceType(sType) {\n // the basetype defaults to sine\n let baseType = "sine";\n if (this._oscillator.type !== "pwm" && this._oscillator.type !== "pulse") {\n baseType = this._oscillator.type;\n }\n // set the type\n if (sType === "fm") {\n this.type = "fm" + baseType;\n }\n else if (sType === "am") {\n this.type = "am" + baseType;\n }\n else if (sType === "fat") {\n this.type = "fat" + baseType;\n }\n else if (sType === "oscillator") {\n this.type = baseType;\n }\n else if (sType === "pulse") {\n this.type = "pulse";\n }\n else if (sType === "pwm") {\n this.type = "pwm";\n }\n }\n _getOscType(osc, sourceType) {\n return osc instanceof OmniOscillatorSourceMap[sourceType];\n }\n /**\n * The base type of the oscillator. See [[Oscillator.baseType]]\n * @example\n * const omniOsc = new Tone.OmniOscillator(440, "fmsquare4");\n * console.log(omniOsc.sourceType, omniOsc.baseType, omniOsc.partialCount);\n */\n get baseType() {\n return this._oscillator.baseType;\n }\n set baseType(baseType) {\n if (!this._getOscType(this._oscillator, "pulse") &&\n !this._getOscType(this._oscillator, "pwm") &&\n baseType !== "pulse" && baseType !== "pwm") {\n this._oscillator.baseType = baseType;\n }\n }\n /**\n * The width of the oscillator when sourceType === "pulse".\n * See [[PWMOscillator.width]]\n */\n get width() {\n if (this._getOscType(this._oscillator, "pulse")) {\n return this._oscillator.width;\n }\n else {\n return undefined;\n }\n }\n /**\n * The number of detuned oscillators when sourceType === "fat".\n * See [[FatOscillator.count]]\n */\n get count() {\n if (this._getOscType(this._oscillator, "fat")) {\n return this._oscillator.count;\n }\n else {\n return undefined;\n }\n }\n set count(count) {\n if (this._getOscType(this._oscillator, "fat") && TypeCheck_isNumber(count)) {\n this._oscillator.count = count;\n }\n }\n /**\n * The detune spread between the oscillators when sourceType === "fat".\n * See [[FatOscillator.count]]\n */\n get spread() {\n if (this._getOscType(this._oscillator, "fat")) {\n return this._oscillator.spread;\n }\n else {\n return undefined;\n }\n }\n set spread(spread) {\n if (this._getOscType(this._oscillator, "fat") && TypeCheck_isNumber(spread)) {\n this._oscillator.spread = spread;\n }\n }\n /**\n * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types.\n * See [[AMOscillator]] or [[FMOscillator]]\n */\n get modulationType() {\n if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) {\n return this._oscillator.modulationType;\n }\n else {\n return undefined;\n }\n }\n set modulationType(mType) {\n if ((this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) && TypeCheck_isString(mType)) {\n this._oscillator.modulationType = mType;\n }\n }\n /**\n * The modulation index when the sourceType === "fm"\n * See [[FMOscillator]].\n */\n get modulationIndex() {\n if (this._getOscType(this._oscillator, "fm")) {\n return this._oscillator.modulationIndex;\n }\n else {\n return undefined;\n }\n }\n /**\n * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n * See [[AMOscillator]] or [[FMOscillator]]\n */\n get harmonicity() {\n if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) {\n return this._oscillator.harmonicity;\n }\n else {\n return undefined;\n }\n }\n /**\n * The modulationFrequency Signal of the oscillator when sourceType === "pwm"\n * see [[PWMOscillator]]\n * @min 0.1\n * @max 5\n */\n get modulationFrequency() {\n if (this._getOscType(this._oscillator, "pwm")) {\n return this._oscillator.modulationFrequency;\n }\n else {\n return undefined;\n }\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n dispose() {\n super.dispose();\n this.detune.dispose();\n this.frequency.dispose();\n this._oscillator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=OmniOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Add.js\n\n\n\n\n/**\n * Add a signal and a number or two signals. When no value is\n * passed into the constructor, Tone.Add will sum input and `addend`\n * If a value is passed into the constructor, the it will be added to the input.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst add = new Tone.Add(2).toDestination();\n * \tadd.addend.setValueAtTime(1, 0.2);\n * \tconst signal = new Tone.Signal(2);\n * \t// add a signal and a scalar\n * \tsignal.connect(add);\n * \tsignal.setValueAtTime(1, 0.1);\n * }, 0.5, 1);\n * @category Signal\n */\nclass Add_Add extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Add_Add.getDefaults(), arguments, ["value"])));\n this.override = false;\n this.name = "Add";\n /**\n * the summing node\n */\n this._sum = new Gain({ context: this.context });\n this.input = this._sum;\n this.output = this._sum;\n /**\n * The value which is added to the input signal\n */\n this.addend = this._param;\n connectSeries(this._constantSource, this._sum);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._sum.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Add.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Scale.js\n\n\n\n\n/**\n * Performs a linear scaling on an input signal.\n * Scales a NormalRange input to between\n * outputMin and outputMax.\n *\n * @example\n * const scale = new Tone.Scale(50, 100);\n * const signal = new Tone.Signal(0.5).connect(scale);\n * // the output of scale equals 75\n * @category Signal\n */\nclass Scale_Scale extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Scale_Scale.getDefaults(), arguments, ["min", "max"])));\n this.name = "Scale";\n const options = optionsFromArguments(Scale_Scale.getDefaults(), arguments, ["min", "max"]);\n this._mult = this.input = new Multiply({\n context: this.context,\n value: options.max - options.min,\n });\n this._add = this.output = new Add({\n context: this.context,\n value: options.min,\n });\n this._min = options.min;\n this._max = options.max;\n this.input.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(SignalOperator.getDefaults(), {\n max: 1,\n min: 0,\n });\n }\n /**\n * The minimum output value. This number is output when the value input value is 0.\n */\n get min() {\n return this._min;\n }\n set min(min) {\n this._min = min;\n this._setRange();\n }\n /**\n * The maximum output value. This number is output when the value input value is 1.\n */\n get max() {\n return this._max;\n }\n set max(max) {\n this._max = max;\n this._setRange();\n }\n /**\n * set the values\n */\n _setRange() {\n this._add.value = this._min;\n this._mult.value = this._max - this._min;\n }\n dispose() {\n super.dispose();\n this._add.dispose();\n this._mult.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Scale.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Zero.js\n\n\n\n\n/**\n * Tone.Zero outputs 0\'s at audio-rate. The reason this has to be\n * it\'s own class is that many browsers optimize out Tone.Signal\n * with a value of 0 and will not process nodes further down the graph.\n * @category Signal\n */\nclass Zero_Zero extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Zero_Zero.getDefaults(), arguments)));\n this.name = "Zero";\n /**\n * The gain node which connects the constant source to the output\n */\n this._gain = new Gain({ context: this.context });\n /**\n * Only outputs 0\n */\n this.output = this._gain;\n /**\n * no input node\n */\n this.input = undefined;\n connect(this.context.getConstant(0), this._gain);\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n disconnect(this.context.getConstant(0), this._gain);\n return this;\n }\n}\n//# sourceMappingURL=Zero.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/LFO.js\n\n\n\n\n\n\n\n\n\n\n/**\n * LFO stands for low frequency oscillator. LFO produces an output signal\n * which can be attached to an AudioParam or Tone.Signal\n * in order to modulate that parameter with an oscillator. The LFO can\n * also be synced to the transport to start/stop and change when the tempo changes.\n * @example\n * return Tone.Offline(() => {\n * \tconst lfo = new Tone.LFO("4n", 400, 4000).start().toDestination();\n * }, 0.5, 1);\n * @category Source\n */\nclass LFO_LFO extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(LFO_LFO.getDefaults(), arguments, ["frequency", "min", "max"]));\n this.name = "LFO";\n /**\n * The value that the LFO outputs when it\'s stopped\n */\n this._stoppedValue = 0;\n /**\n * A private placeholder for the units\n */\n this._units = "number";\n /**\n * If the input value is converted using the [[units]]\n */\n this.convert = true;\n /**\n * Private methods borrowed from Param\n */\n // @ts-ignore\n this._fromType = Param.prototype._fromType;\n // @ts-ignore\n this._toType = Param.prototype._toType;\n // @ts-ignore\n this._is = Param.prototype._is;\n // @ts-ignore\n this._clampValue = Param.prototype._clampValue;\n const options = optionsFromArguments(LFO_LFO.getDefaults(), arguments, ["frequency", "min", "max"]);\n this._oscillator = new Oscillator(options);\n this.frequency = this._oscillator.frequency;\n this._amplitudeGain = new Gain({\n context: this.context,\n gain: options.amplitude,\n units: "normalRange",\n });\n this.amplitude = this._amplitudeGain.gain;\n this._stoppedSignal = new Signal({\n context: this.context,\n units: "audioRange",\n value: 0,\n });\n this._zeros = new Zero({ context: this.context });\n this._a2g = new AudioToGain({ context: this.context });\n this._scaler = this.output = new Scale({\n context: this.context,\n max: options.max,\n min: options.min,\n });\n this.units = options.units;\n this.min = options.min;\n this.max = options.max;\n // connect it up\n this._oscillator.chain(this._amplitudeGain, this._a2g, this._scaler);\n this._zeros.connect(this._a2g);\n this._stoppedSignal.connect(this._a2g);\n readOnly(this, ["amplitude", "frequency"]);\n this.phase = options.phase;\n }\n static getDefaults() {\n return Object.assign(Oscillator.getDefaults(), {\n amplitude: 1,\n frequency: "4n",\n max: 1,\n min: 0,\n type: "sine",\n units: "number",\n });\n }\n /**\n * Start the LFO.\n * @param time The time the LFO will start\n */\n start(time) {\n time = this.toSeconds(time);\n this._stoppedSignal.setValueAtTime(0, time);\n this._oscillator.start(time);\n return this;\n }\n /**\n * Stop the LFO.\n * @param time The time the LFO will stop\n */\n stop(time) {\n time = this.toSeconds(time);\n this._stoppedSignal.setValueAtTime(this._stoppedValue, time);\n this._oscillator.stop(time);\n return this;\n }\n /**\n * Sync the start/stop/pause to the transport\n * and the frequency to the bpm of the transport\n * @example\n * const lfo = new Tone.LFO("8n");\n * lfo.sync().start(0);\n * // the rate of the LFO will always be an eighth note, even as the tempo changes\n */\n sync() {\n this._oscillator.sync();\n this._oscillator.syncFrequency();\n return this;\n }\n /**\n * unsync the LFO from transport control\n */\n unsync() {\n this._oscillator.unsync();\n this._oscillator.unsyncFrequency();\n return this;\n }\n /**\n * After the oscillator waveform is updated, reset the `_stoppedSignal` value to match the updated waveform\n */\n _setStoppedValue() {\n this._stoppedValue = this._oscillator.getInitialValue();\n this._stoppedSignal.value = this._stoppedValue;\n }\n /**\n * The minimum output of the LFO.\n */\n get min() {\n return this._toType(this._scaler.min);\n }\n set min(min) {\n min = this._fromType(min);\n this._scaler.min = min;\n }\n /**\n * The maximum output of the LFO.\n */\n get max() {\n return this._toType(this._scaler.max);\n }\n set max(max) {\n max = this._fromType(max);\n this._scaler.max = max;\n }\n /**\n * The type of the oscillator: See [[Oscillator.type]]\n */\n get type() {\n return this._oscillator.type;\n }\n set type(type) {\n this._oscillator.type = type;\n this._setStoppedValue();\n }\n /**\n * The oscillator\'s partials array: See [[Oscillator.partials]]\n */\n get partials() {\n return this._oscillator.partials;\n }\n set partials(partials) {\n this._oscillator.partials = partials;\n this._setStoppedValue();\n }\n /**\n * The phase of the LFO.\n */\n get phase() {\n return this._oscillator.phase;\n }\n set phase(phase) {\n this._oscillator.phase = phase;\n this._setStoppedValue();\n }\n /**\n * The output units of the LFO.\n */\n get units() {\n return this._units;\n }\n set units(val) {\n const currentMin = this.min;\n const currentMax = this.max;\n // convert the min and the max\n this._units = val;\n this.min = currentMin;\n this.max = currentMax;\n }\n /**\n * Returns the playback state of the source, either "started" or "stopped".\n */\n get state() {\n return this._oscillator.state;\n }\n /**\n * @param node the destination to connect to\n * @param outputNum the optional output number\n * @param inputNum the input number\n */\n connect(node, outputNum, inputNum) {\n if (node instanceof Param || node instanceof Signal) {\n this.convert = node.convert;\n this.units = node.units;\n }\n connectSignal(this, node, outputNum, inputNum);\n return this;\n }\n dispose() {\n super.dispose();\n this._oscillator.dispose();\n this._stoppedSignal.dispose();\n this._zeros.dispose();\n this._scaler.dispose();\n this._a2g.dispose();\n this._amplitudeGain.dispose();\n this.amplitude.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LFO.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Decorator.js\n\n/**\n * Assert that the number is in the given range.\n */\nfunction range(min, max = Infinity) {\n const valueMap = new WeakMap();\n return function (target, propertyKey) {\n Reflect.defineProperty(target, propertyKey, {\n configurable: true,\n enumerable: true,\n get: function () {\n return valueMap.get(this);\n },\n set: function (newValue) {\n Debug_assertRange(newValue, min, max);\n valueMap.set(this, newValue);\n }\n });\n };\n}\n/**\n * Convert the time to seconds and assert that the time is in between the two\n * values when being set.\n */\nfunction timeRange(min, max = Infinity) {\n const valueMap = new WeakMap();\n return function (target, propertyKey) {\n Reflect.defineProperty(target, propertyKey, {\n configurable: true,\n enumerable: true,\n get: function () {\n return valueMap.get(this);\n },\n set: function (newValue) {\n Debug_assertRange(this.toSeconds(newValue), min, max);\n valueMap.set(this, newValue);\n }\n });\n };\n}\n//# sourceMappingURL=Decorator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/Player.js\n\n\n\n\n\n\n\n\n\n/**\n * Player is an audio file player with start, loop, and stop functions.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();\n * // play as soon as the buffer is loaded\n * player.autostart = true;\n * @category Source\n */\nclass Player_Player extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(Player_Player.getDefaults(), arguments, ["url", "onload"]));\n this.name = "Player";\n /**\n * All of the active buffer source nodes\n */\n this._activeSources = new Set();\n const options = Defaults_optionsFromArguments(Player_Player.getDefaults(), arguments, ["url", "onload"]);\n this._buffer = new ToneAudioBuffer_ToneAudioBuffer({\n onload: this._onload.bind(this, options.onload),\n onerror: options.onerror,\n reverse: options.reverse,\n url: options.url,\n });\n this.autostart = options.autostart;\n this._loop = options.loop;\n this._loopStart = options.loopStart;\n this._loopEnd = options.loopEnd;\n this._playbackRate = options.playbackRate;\n this.fadeIn = options.fadeIn;\n this.fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n autostart: false,\n fadeIn: 0,\n fadeOut: 0,\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n onload: Interface_noOp,\n onerror: Interface_noOp,\n playbackRate: 1,\n reverse: false,\n });\n }\n /**\n * Load the audio file as an audio buffer.\n * Decodes the audio asynchronously and invokes\n * the callback once the audio buffer loads.\n * Note: this does not need to be called if a url\n * was passed in to the constructor. Only use this\n * if you want to manually load a new url.\n * @param url The url of the buffer to load. Filetype support depends on the browser.\n */\n load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n yield this._buffer.load(url);\n this._onload();\n return this;\n });\n }\n /**\n * Internal callback when the buffer is loaded.\n */\n _onload(callback = Interface_noOp) {\n callback();\n if (this.autostart) {\n this.start();\n }\n }\n /**\n * Internal callback when the buffer is done playing.\n */\n _onSourceEnd(source) {\n // invoke the onstop function\n this.onstop(this);\n // delete the source from the active sources\n this._activeSources.delete(source);\n if (this._activeSources.size === 0 && !this._synced &&\n this._state.getValueAtTime(this.now()) === "started") {\n // remove the \'implicitEnd\' event and replace with an explicit end\n this._state.cancel(this.now());\n this._state.setStateAtTime("stopped", this.now());\n }\n }\n /**\n * Play the buffer at the given startTime. Optionally add an offset\n * and/or duration which will play the buffer from a position\n * within the buffer for the given duration.\n *\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset)\n */\n start(time, offset, duration) {\n super.start(time, offset, duration);\n return this;\n }\n /**\n * Internal start method\n */\n _start(startTime, offset, duration) {\n // if it\'s a loop the default offset is the loopStart point\n if (this._loop) {\n offset = Defaults_defaultArg(offset, this._loopStart);\n }\n else {\n // otherwise the default offset is 0\n offset = Defaults_defaultArg(offset, 0);\n }\n // compute the values in seconds\n const computedOffset = this.toSeconds(offset);\n // compute the duration which is either the passed in duration of the buffer.duration - offset\n const origDuration = duration;\n duration = Defaults_defaultArg(duration, Math.max(this._buffer.duration - computedOffset, 0));\n let computedDuration = this.toSeconds(duration);\n // scale it by the playback rate\n computedDuration = computedDuration / this._playbackRate;\n // get the start time\n startTime = this.toSeconds(startTime);\n // make the source\n const source = new ToneBufferSource_ToneBufferSource({\n url: this._buffer,\n context: this.context,\n fadeIn: this.fadeIn,\n fadeOut: this.fadeOut,\n loop: this._loop,\n loopEnd: this._loopEnd,\n loopStart: this._loopStart,\n onended: this._onSourceEnd.bind(this),\n playbackRate: this._playbackRate,\n }).connect(this.output);\n // set the looping properties\n if (!this._loop && !this._synced) {\n // cancel the previous stop\n this._state.cancel(startTime + computedDuration);\n // if it\'s not looping, set the state change at the end of the sample\n this._state.setStateAtTime("stopped", startTime + computedDuration, {\n implicitEnd: true,\n });\n }\n // add it to the array of active sources\n this._activeSources.add(source);\n // start it\n if (this._loop && TypeCheck_isUndef(origDuration)) {\n source.start(startTime, computedOffset);\n }\n else {\n // subtract the fade out time\n source.start(startTime, computedOffset, computedDuration - this.toSeconds(this.fadeOut));\n }\n }\n /**\n * Stop playback.\n */\n _stop(time) {\n const computedTime = this.toSeconds(time);\n this._activeSources.forEach(source => source.stop(computedTime));\n }\n /**\n * Stop and then restart the player from the beginning (or offset)\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given,\n * \t\t\t\t\tit will default to the full length of the sample (minus any offset)\n */\n restart(time, offset, duration) {\n super.restart(time, offset, duration);\n return this;\n }\n _restart(time, offset, duration) {\n this._stop(time);\n this._start(time, offset, duration);\n }\n /**\n * Seek to a specific time in the player\'s buffer. If the\n * source is no longer playing at that time, it will stop.\n * @param offset The time to seek to.\n * @param when The time for the seek event to occur.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3", () => {\n * \tplayer.start();\n * \t// seek to the offset in 1 second from now\n * \tplayer.seek(0.4, "+1");\n * }).toDestination();\n */\n seek(offset, when) {\n const computedTime = this.toSeconds(when);\n if (this._state.getValueAtTime(computedTime) === "started") {\n const computedOffset = this.toSeconds(offset);\n // if it\'s currently playing, stop it\n this._stop(computedTime);\n // restart it at the given time\n this._start(computedTime, computedOffset);\n }\n return this;\n }\n /**\n * Set the loop start and end. Will only loop if loop is set to true.\n * @param loopStart The loop start time\n * @param loopEnd The loop end time\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/malevoices_aa2_F3.mp3").toDestination();\n * // loop between the given points\n * player.setLoopPoints(0.2, 0.3);\n * player.loop = true;\n * player.autostart = true;\n */\n setLoopPoints(loopStart, loopEnd) {\n this.loopStart = loopStart;\n this.loopEnd = loopEnd;\n return this;\n }\n /**\n * If loop is true, the loop will start at this position.\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(loopStart) {\n this._loopStart = loopStart;\n if (this.buffer.loaded) {\n Debug_assertRange(this.toSeconds(loopStart), 0, this.buffer.duration);\n }\n // get the current source\n this._activeSources.forEach(source => {\n source.loopStart = loopStart;\n });\n }\n /**\n * If loop is true, the loop will end at this position.\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(loopEnd) {\n this._loopEnd = loopEnd;\n if (this.buffer.loaded) {\n Debug_assertRange(this.toSeconds(loopEnd), 0, this.buffer.duration);\n }\n // get the current source\n this._activeSources.forEach(source => {\n source.loopEnd = loopEnd;\n });\n }\n /**\n * The audio buffer belonging to the player.\n */\n get buffer() {\n return this._buffer;\n }\n set buffer(buffer) {\n this._buffer.set(buffer);\n }\n /**\n * If the buffer should loop once it\'s over.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/breakbeat.mp3").toDestination();\n * player.loop = true;\n * player.autostart = true;\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n // if no change, do nothing\n if (this._loop === loop) {\n return;\n }\n this._loop = loop;\n // set the loop of all of the sources\n this._activeSources.forEach(source => {\n source.loop = loop;\n });\n if (loop) {\n // remove the next stopEvent\n const stopEvent = this._state.getNextState("stopped", this.now());\n if (stopEvent) {\n this._state.cancel(stopEvent.time);\n }\n }\n }\n /**\n * Normal speed is 1. The pitch will change with the playback rate.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/femalevoices_aa2_A5.mp3").toDestination();\n * // play at 1/4 speed\n * player.playbackRate = 0.25;\n * // play as soon as the buffer is loaded\n * player.autostart = true;\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n const now = this.now();\n // cancel the stop event since it\'s at a different time now\n const stopEvent = this._state.getNextState("stopped", now);\n if (stopEvent && stopEvent.implicitEnd) {\n this._state.cancel(stopEvent.time);\n this._activeSources.forEach(source => source.cancelStop());\n }\n // set all the sources\n this._activeSources.forEach(source => {\n source.playbackRate.setValueAtTime(rate, now);\n });\n }\n /**\n * If the buffer should be reversed\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/chime_1.mp3").toDestination();\n * player.autostart = true;\n * player.reverse = true;\n */\n get reverse() {\n return this._buffer.reverse;\n }\n set reverse(rev) {\n this._buffer.reverse = rev;\n }\n /**\n * If the buffer is loaded\n */\n get loaded() {\n return this._buffer.loaded;\n }\n dispose() {\n super.dispose();\n // disconnect all of the players\n this._activeSources.forEach(source => source.dispose());\n this._activeSources.clear();\n this._buffer.dispose();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Player_Player.prototype, "fadeIn", void 0);\n__decorate([\n timeRange(0)\n], Player_Player.prototype, "fadeOut", void 0);\n//# sourceMappingURL=Player.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/Players.js\n\n\n\n\n\n\n\n\n/**\n * Players combines multiple [[Player]] objects.\n * @category Source\n */\nclass Players extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls"));\n this.name = "Players";\n /**\n * Players has no input.\n */\n this.input = undefined;\n /**\n * The container of all of the players\n */\n this._players = new Map();\n const options = optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls");\n /**\n * The output volume node\n */\n this._volume = this.output = new Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n readOnly(this, "volume");\n this._buffers = new ToneAudioBuffers({\n urls: options.urls,\n onload: options.onload,\n baseUrl: options.baseUrl,\n onerror: options.onerror\n });\n // mute initially\n this.mute = options.mute;\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n baseUrl: "",\n fadeIn: 0,\n fadeOut: 0,\n mute: false,\n onload: noOp,\n onerror: noOp,\n urls: {},\n volume: 0,\n });\n }\n /**\n * Mute the output.\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n /**\n * The fadeIn time of the envelope applied to the source.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(fadeIn) {\n this._fadeIn = fadeIn;\n this._players.forEach(player => {\n player.fadeIn = fadeIn;\n });\n }\n /**\n * The fadeOut time of the each of the sources.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(fadeOut) {\n this._fadeOut = fadeOut;\n this._players.forEach(player => {\n player.fadeOut = fadeOut;\n });\n }\n /**\n * The state of the players object. Returns "started" if any of the players are playing.\n */\n get state() {\n const playing = Array.from(this._players).some(([_, player]) => player.state === "started");\n return playing ? "started" : "stopped";\n }\n /**\n * True if the buffers object has a buffer by that name.\n * @param name The key or index of the buffer.\n */\n has(name) {\n return this._buffers.has(name);\n }\n /**\n * Get a player by name.\n * @param name The players name as defined in the constructor object or `add` method.\n */\n player(name) {\n assert(this.has(name), `No Player with the name ${name} exists on this object`);\n if (!this._players.has(name)) {\n const player = new Player({\n context: this.context,\n fadeIn: this._fadeIn,\n fadeOut: this._fadeOut,\n url: this._buffers.get(name),\n }).connect(this.output);\n this._players.set(name, player);\n }\n return this._players.get(name);\n }\n /**\n * If all the buffers are loaded or not\n */\n get loaded() {\n return this._buffers.loaded;\n }\n /**\n * Add a player by name and url to the Players\n * @param name A unique name to give the player\n * @param url Either the url of the bufer or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n */\n add(name, url, callback) {\n assert(!this._buffers.has(name), "A buffer with that name already exists on this object");\n this._buffers.add(name, url, callback);\n return this;\n }\n /**\n * Stop all of the players at the given time\n * @param time The time to stop all of the players.\n */\n stopAll(time) {\n this._players.forEach(player => player.stop(time));\n return this;\n }\n dispose() {\n super.dispose();\n this._volume.dispose();\n this.volume.dispose();\n this._players.forEach(player => player.dispose());\n this._buffers.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Players.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/GrainPlayer.js\n\n\n\n\n\n\n\n\n/**\n * GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis).\n * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the\n * amount of time each small chunk of audio is played for and the overlap is the\n * amount of crossfading transition time between successive grains.\n * @category Source\n */\nclass GrainPlayer extends (/* unused pure expression or super */ null && (Source)) {\n constructor() {\n super(optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]));\n this.name = "GrainPlayer";\n /**\n * Internal loopStart value\n */\n this._loopStart = 0;\n /**\n * Internal loopStart value\n */\n this._loopEnd = 0;\n /**\n * All of the currently playing BufferSources\n */\n this._activeSources = [];\n const options = optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]);\n this.buffer = new ToneAudioBuffer({\n onload: options.onload,\n onerror: options.onerror,\n reverse: options.reverse,\n url: options.url,\n });\n this._clock = new Clock({\n context: this.context,\n callback: this._tick.bind(this),\n frequency: 1 / options.grainSize\n });\n this._playbackRate = options.playbackRate;\n this._grainSize = options.grainSize;\n this._overlap = options.overlap;\n this.detune = options.detune;\n // setup\n this.overlap = options.overlap;\n this.loop = options.loop;\n this.playbackRate = options.playbackRate;\n this.grainSize = options.grainSize;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this.reverse = options.reverse;\n this._clock.on("stop", this._onstop.bind(this));\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n onload: noOp,\n onerror: noOp,\n overlap: 0.1,\n grainSize: 0.2,\n playbackRate: 1,\n detune: 0,\n loop: false,\n loopStart: 0,\n loopEnd: 0,\n reverse: false\n });\n }\n /**\n * Internal start method\n */\n _start(time, offset, duration) {\n offset = defaultArg(offset, 0);\n offset = this.toSeconds(offset);\n time = this.toSeconds(time);\n const grainSize = 1 / this._clock.frequency.getValueAtTime(time);\n this._clock.start(time, offset / grainSize);\n if (duration) {\n this.stop(time + this.toSeconds(duration));\n }\n }\n /**\n * Stop and then restart the player from the beginning (or offset)\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given,\n * \t\t\t\t\tit will default to the full length of the sample (minus any offset)\n */\n restart(time, offset, duration) {\n super.restart(time, offset, duration);\n return this;\n }\n _restart(time, offset, duration) {\n this._stop(time);\n this._start(time, offset, duration);\n }\n /**\n * Internal stop method\n */\n _stop(time) {\n this._clock.stop(time);\n }\n /**\n * Invoked when the clock is stopped\n */\n _onstop(time) {\n // stop the players\n this._activeSources.forEach((source) => {\n source.fadeOut = 0;\n source.stop(time);\n });\n this.onstop(this);\n }\n /**\n * Invoked on each clock tick. scheduled a new grain at this time.\n */\n _tick(time) {\n // check if it should stop looping\n const ticks = this._clock.getTicksAtTime(time);\n const offset = ticks * this._grainSize;\n this.log("offset", offset);\n if (!this.loop && offset > this.buffer.duration) {\n this.stop(time);\n return;\n }\n // at the beginning of the file, the fade in should be 0\n const fadeIn = offset < this._overlap ? 0 : this._overlap;\n // create a buffer source\n const source = new ToneBufferSource({\n context: this.context,\n url: this.buffer,\n fadeIn: fadeIn,\n fadeOut: this._overlap,\n loop: this.loop,\n loopStart: this._loopStart,\n loopEnd: this._loopEnd,\n // compute the playbackRate based on the detune\n playbackRate: intervalToFrequencyRatio(this.detune / 100)\n }).connect(this.output);\n source.start(time, this._grainSize * ticks);\n source.stop(time + this._grainSize / this.playbackRate);\n // add it to the active sources\n this._activeSources.push(source);\n // remove it when it\'s done\n source.onended = () => {\n const index = this._activeSources.indexOf(source);\n if (index !== -1) {\n this._activeSources.splice(index, 1);\n }\n };\n }\n /**\n * The playback rate of the sample\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n assertRange(rate, 0.001);\n this._playbackRate = rate;\n this.grainSize = this._grainSize;\n }\n /**\n * The loop start time.\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(time) {\n if (this.buffer.loaded) {\n assertRange(this.toSeconds(time), 0, this.buffer.duration);\n }\n this._loopStart = this.toSeconds(time);\n }\n /**\n * The loop end time.\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(time) {\n if (this.buffer.loaded) {\n assertRange(this.toSeconds(time), 0, this.buffer.duration);\n }\n this._loopEnd = this.toSeconds(time);\n }\n /**\n * The direction the buffer should play in\n */\n get reverse() {\n return this.buffer.reverse;\n }\n set reverse(rev) {\n this.buffer.reverse = rev;\n }\n /**\n * The size of each chunk of audio that the\n * buffer is chopped into and played back at.\n */\n get grainSize() {\n return this._grainSize;\n }\n set grainSize(size) {\n this._grainSize = this.toSeconds(size);\n this._clock.frequency.setValueAtTime(this._playbackRate / this._grainSize, this.now());\n }\n /**\n * The duration of the cross-fade between successive grains.\n */\n get overlap() {\n return this._overlap;\n }\n set overlap(time) {\n const computedTime = this.toSeconds(time);\n assertRange(computedTime, 0);\n this._overlap = computedTime;\n }\n /**\n * If all the buffer is loaded\n */\n get loaded() {\n return this.buffer.loaded;\n }\n dispose() {\n super.dispose();\n this.buffer.dispose();\n this._clock.dispose();\n this._activeSources.forEach((source) => source.dispose());\n return this;\n }\n}\n//# sourceMappingURL=GrainPlayer.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Abs.js\n\n\n/**\n * Return the absolute value of an incoming signal.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst abs = new Tone.Abs().toDestination();\n * \tconst signal = new Tone.Signal(1);\n * \tsignal.rampTo(-1, 0.5);\n * \tsignal.connect(abs);\n * }, 0.5, 1);\n * @category Signal\n */\nclass Abs_Abs extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "Abs";\n /**\n * The node which converts the audio ranges\n */\n this._abs = new WaveShaper({\n context: this.context,\n mapping: val => {\n if (Math.abs(val) < 0.001) {\n return 0;\n }\n else {\n return Math.abs(val);\n }\n },\n });\n /**\n * The AudioRange input [-1, 1]\n */\n this.input = this._abs;\n /**\n * The output range [0, 1]\n */\n this.output = this._abs;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._abs.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Abs.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GainToAudio.js\n\n\n/**\n * GainToAudio converts an input in NormalRange [0,1] to AudioRange [-1,1].\n * See [[AudioToGain]].\n * @category Signal\n */\nclass GainToAudio_GainToAudio extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "GainToAudio";\n /**\n * The node which converts the audio ranges\n */\n this._norm = new WaveShaper({\n context: this.context,\n mapping: x => Math.abs(x) * 2 - 1,\n });\n /**\n * The NormalRange input [0, 1]\n */\n this.input = this._norm;\n /**\n * The AudioRange output [-1, 1]\n */\n this.output = this._norm;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._norm.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GainToAudio.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Negate.js\n\n\n/**\n * Negate the incoming signal. i.e. an input signal of 10 will output -10\n *\n * @example\n * const neg = new Tone.Negate();\n * const sig = new Tone.Signal(-2).connect(neg);\n * // output of neg is positive 2.\n * @category Signal\n */\nclass Negate_Negate extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "Negate";\n /**\n * negation is done by multiplying by -1\n */\n this._multiply = new Multiply({\n context: this.context,\n value: -1,\n });\n /**\n * The input and output are equal to the multiply node\n */\n this.input = this._multiply;\n this.output = this._multiply;\n }\n /**\n * clean up\n * @returns {Negate} this\n */\n dispose() {\n super.dispose();\n this._multiply.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Negate.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Subtract.js\n\n\n\n\n\n/**\n * Subtract the signal connected to the input is subtracted from the signal connected\n * The subtrahend.\n *\n * @example\n * // subtract a scalar from a signal\n * const sub = new Tone.Subtract(1);\n * const sig = new Tone.Signal(4).connect(sub);\n * // the output of sub is 3.\n * @example\n * // subtract two signals\n * const sub = new Tone.Subtract();\n * const sigA = new Tone.Signal(10);\n * const sigB = new Tone.Signal(2.5);\n * sigA.connect(sub);\n * sigB.connect(sub.subtrahend);\n * // output of sub is 7.5\n * @category Signal\n */\nclass Subtract_Subtract extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Subtract_Subtract.getDefaults(), arguments, ["value"])));\n this.override = false;\n this.name = "Subtract";\n /**\n * the summing node\n */\n this._sum = new Gain({ context: this.context });\n this.input = this._sum;\n this.output = this._sum;\n /**\n * Negate the input of the second input before connecting it to the summing node.\n */\n this._neg = new Negate({ context: this.context });\n /**\n * The value which is subtracted from the main signal\n */\n this.subtrahend = this._param;\n connectSeries(this._constantSource, this._neg, this._sum);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._neg.dispose();\n this._sum.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Subtract.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GreaterThanZero.js\n\n\n\n\n/**\n * GreaterThanZero outputs 1 when the input is strictly greater than zero\n * @example\n * return Tone.Offline(() => {\n * \tconst gt0 = new Tone.GreaterThanZero().toDestination();\n * \tconst sig = new Tone.Signal(0.5).connect(gt0);\n * \tsig.setValueAtTime(-1, 0.05);\n * }, 0.1, 1);\n * @category Signal\n */\nclass GreaterThanZero_GreaterThanZero extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(GreaterThanZero_GreaterThanZero.getDefaults(), arguments)));\n this.name = "GreaterThanZero";\n this._thresh = this.output = new WaveShaper({\n context: this.context,\n length: 127,\n mapping: (val) => {\n if (val <= 0) {\n return 0;\n }\n else {\n return 1;\n }\n },\n });\n this._scale = this.input = new Multiply({\n context: this.context,\n value: 10000\n });\n // connections\n this._scale.connect(this._thresh);\n }\n dispose() {\n super.dispose();\n this._scale.dispose();\n this._thresh.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GreaterThanZero.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GreaterThan.js\n\n\n\n\n\n/**\n * Output 1 if the signal is greater than the value, otherwise outputs 0.\n * can compare two signals or a signal and a number.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst gt = new Tone.GreaterThan(2).toDestination();\n * \tconst sig = new Tone.Signal(4).connect(gt);\n * }, 0.1, 1);\n * @category Signal\n */\nclass GreaterThan_GreaterThan extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(GreaterThan_GreaterThan.getDefaults(), arguments, ["value"])));\n this.name = "GreaterThan";\n this.override = false;\n const options = optionsFromArguments(GreaterThan_GreaterThan.getDefaults(), arguments, ["value"]);\n this._subtract = this.input = new Subtract({\n context: this.context,\n value: options.value\n });\n this._gtz = this.output = new GreaterThanZero({ context: this.context });\n this.comparator = this._param = this._subtract.subtrahend;\n readOnly(this, "comparator");\n // connect\n this._subtract.connect(this._gtz);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._gtz.dispose();\n this._subtract.dispose();\n this.comparator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GreaterThan.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Pow.js\n\n\n\n/**\n * Pow applies an exponent to the incoming signal. The incoming signal must be AudioRange [-1, 1]\n *\n * @example\n * const pow = new Tone.Pow(2);\n * const sig = new Tone.Signal(0.5).connect(pow);\n * // output of pow is 0.25.\n * @category Signal\n */\nclass Pow_Pow extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Pow_Pow.getDefaults(), arguments, ["value"])));\n this.name = "Pow";\n const options = optionsFromArguments(Pow_Pow.getDefaults(), arguments, ["value"]);\n this._exponentScaler = this.input = this.output = new WaveShaper({\n context: this.context,\n mapping: this._expFunc(options.value),\n length: 8192,\n });\n this._exponent = options.value;\n }\n static getDefaults() {\n return Object.assign(SignalOperator.getDefaults(), {\n value: 1,\n });\n }\n /**\n * the function which maps the waveshaper\n * @param exponent exponent value\n */\n _expFunc(exponent) {\n return (val) => {\n return Math.pow(Math.abs(val), exponent);\n };\n }\n /**\n * The value of the exponent.\n */\n get value() {\n return this._exponent;\n }\n set value(exponent) {\n this._exponent = exponent;\n this._exponentScaler.setMap(this._expFunc(this._exponent));\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._exponentScaler.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Pow.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/ScaleExp.js\n\n\n\n/**\n * Performs an exponential scaling on an input signal.\n * Scales a NormalRange value [0,1] exponentially\n * to the output range of outputMin to outputMax.\n * @example\n * const scaleExp = new Tone.ScaleExp(0, 100, 2);\n * const signal = new Tone.Signal(0.5).connect(scaleExp);\n * @category Signal\n */\nclass ScaleExp_ScaleExp extends (/* unused pure expression or super */ null && (Scale)) {\n constructor() {\n super(Object.assign(optionsFromArguments(ScaleExp_ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"])));\n this.name = "ScaleExp";\n const options = optionsFromArguments(ScaleExp_ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"]);\n this.input = this._exp = new Pow({\n context: this.context,\n value: options.exponent,\n });\n this._exp.connect(this._mult);\n }\n static getDefaults() {\n return Object.assign(Scale.getDefaults(), {\n exponent: 1,\n });\n }\n /**\n * Instead of interpolating linearly between the [[min]] and\n * [[max]] values, setting the exponent will interpolate between\n * the two values with an exponential curve.\n */\n get exponent() {\n return this._exp.value;\n }\n set exponent(exp) {\n this._exp.value = exp;\n }\n dispose() {\n super.dispose();\n this._exp.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ScaleExp.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/SyncedSignal.js\n\n\n\n\n/**\n * Adds the ability to synchronize the signal to the [[Transport]]\n */\nclass SyncedSignal extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]));\n this.name = "SyncedSignal";\n /**\n * Don\'t override when something is connected to the input\n */\n this.override = false;\n const options = optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]);\n this._lastVal = options.value;\n this._synced = this.context.transport.scheduleRepeat(this._onTick.bind(this), "1i");\n this._syncedCallback = this._anchorValue.bind(this);\n this.context.transport.on("start", this._syncedCallback);\n this.context.transport.on("pause", this._syncedCallback);\n this.context.transport.on("stop", this._syncedCallback);\n // disconnect the constant source from the output and replace it with another one\n this._constantSource.disconnect();\n this._constantSource.stop(0);\n // create a new one\n this._constantSource = this.output = new ToneConstantSource({\n context: this.context,\n offset: options.value,\n units: options.units,\n }).start(0);\n this.setValueAtTime(options.value, 0);\n }\n /**\n * Callback which is invoked every tick.\n */\n _onTick(time) {\n const val = super.getValueAtTime(this.context.transport.seconds);\n // approximate ramp curves with linear ramps\n if (this._lastVal !== val) {\n this._lastVal = val;\n this._constantSource.offset.setValueAtTime(val, time);\n }\n }\n /**\n * Anchor the value at the start and stop of the Transport\n */\n _anchorValue(time) {\n const val = super.getValueAtTime(this.context.transport.seconds);\n this._lastVal = val;\n this._constantSource.offset.cancelAndHoldAtTime(time);\n this._constantSource.offset.setValueAtTime(val, time);\n }\n getValueAtTime(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n return super.getValueAtTime(computedTime);\n }\n setValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.setValueAtTime(value, computedTime);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.linearRampToValueAtTime(value, computedTime);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.exponentialRampToValueAtTime(value, computedTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.setTargetAtTime(value, computedTime, timeConstant);\n return this;\n }\n cancelScheduledValues(startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.cancelScheduledValues(computedTime);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n duration = this.toSeconds(duration);\n super.setValueCurveAtTime(values, computedTime, duration, scaling);\n return this;\n }\n cancelAndHoldAtTime(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.cancelAndHoldAtTime(computedTime);\n return this;\n }\n setRampPoint(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.setRampPoint(computedTime);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.exponentialRampTo(value, rampTime, computedTime);\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.linearRampTo(value, rampTime, computedTime);\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.targetRampTo(value, rampTime, computedTime);\n return this;\n }\n dispose() {\n super.dispose();\n this.context.transport.clear(this._synced);\n this.context.transport.off("start", this._syncedCallback);\n this.context.transport.off("pause", this._syncedCallback);\n this.context.transport.off("stop", this._syncedCallback);\n this._constantSource.dispose();\n return this;\n }\n}\n//# sourceMappingURL=SyncedSignal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/Envelope.js\n\n\n\n\n\n\n\n\n/**\n * Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope)\n * envelope generator. Envelope outputs a signal which\n * can be connected to an AudioParam or Tone.Signal.\n * ```\n * /\\\n * / \\\n * / \\\n * / \\\n * / \\___________\n * / \\\n * / \\\n * / \\\n * / \\\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\tattack: 0.1,\n * \t\tdecay: 0.2,\n * \t\tsustain: 0.5,\n * \t\trelease: 0.8,\n * \t}).toDestination();\n * \tenv.triggerAttackRelease(0.5);\n * }, 1.5, 1);\n * @category Component\n */\nclass Envelope_Envelope extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Envelope_Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "Envelope";\n /**\n * the signal which is output.\n */\n this._sig = new Signal_Signal({\n context: this.context,\n value: 0,\n });\n /**\n * The output signal of the envelope\n */\n this.output = this._sig;\n /**\n * Envelope has no input\n */\n this.input = undefined;\n const options = Defaults_optionsFromArguments(Envelope_Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]);\n this.attack = options.attack;\n this.decay = options.decay;\n this.sustain = options.sustain;\n this.release = options.release;\n this.attackCurve = options.attackCurve;\n this.releaseCurve = options.releaseCurve;\n this.decayCurve = options.decayCurve;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n attack: 0.01,\n attackCurve: "linear",\n decay: 0.1,\n decayCurve: "exponential",\n release: 1,\n releaseCurve: "exponential",\n sustain: 0.5,\n });\n }\n /**\n * Read the current value of the envelope. Useful for\n * synchronizing visual output to the envelope.\n */\n get value() {\n return this.getValueAtTime(this.now());\n }\n /**\n * Get the curve\n * @param curve\n * @param direction In/Out\n * @return The curve name\n */\n _getCurve(curve, direction) {\n if (TypeCheck_isString(curve)) {\n return curve;\n }\n else {\n // look up the name in the curves array\n let curveName;\n for (curveName in EnvelopeCurves) {\n if (EnvelopeCurves[curveName][direction] === curve) {\n return curveName;\n }\n }\n // return the custom curve\n return curve;\n }\n }\n /**\n * Assign a the curve to the given name using the direction\n * @param name\n * @param direction In/Out\n * @param curve\n */\n _setCurve(name, direction, curve) {\n // check if it\'s a valid type\n if (TypeCheck_isString(curve) && Reflect.has(EnvelopeCurves, curve)) {\n const curveDef = EnvelopeCurves[curve];\n if (TypeCheck_isObject(curveDef)) {\n if (name !== "_decayCurve") {\n this[name] = curveDef[direction];\n }\n }\n else {\n this[name] = curveDef;\n }\n }\n else if (TypeCheck_isArray(curve) && name !== "_decayCurve") {\n this[name] = curve;\n }\n else {\n throw new Error("Envelope: invalid curve: " + curve);\n }\n }\n /**\n * The shape of the attack.\n * Can be any of these strings:\n * * "linear"\n * * "exponential"\n * * "sine"\n * * "cosine"\n * * "bounce"\n * * "ripple"\n * * "step"\n *\n * Can also be an array which describes the curve. Values\n * in the array are evenly subdivided and linearly\n * interpolated over the duration of the attack.\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope(0.4).toDestination();\n * \tenv.attackCurve = "linear";\n * \tenv.triggerAttack();\n * }, 1, 1);\n */\n get attackCurve() {\n return this._getCurve(this._attackCurve, "In");\n }\n set attackCurve(curve) {\n this._setCurve("_attackCurve", "In", curve);\n }\n /**\n * The shape of the release. See the attack curve types.\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\trelease: 0.8\n * \t}).toDestination();\n * \tenv.triggerAttack();\n * \t// release curve could also be defined by an array\n * \tenv.releaseCurve = [1, 0.3, 0.4, 0.2, 0.7, 0];\n * \tenv.triggerRelease(0.2);\n * }, 1, 1);\n */\n get releaseCurve() {\n return this._getCurve(this._releaseCurve, "Out");\n }\n set releaseCurve(curve) {\n this._setCurve("_releaseCurve", "Out", curve);\n }\n /**\n * The shape of the decay either "linear" or "exponential"\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\tsustain: 0.1,\n * \t\tdecay: 0.5\n * \t}).toDestination();\n * \tenv.decayCurve = "linear";\n * \tenv.triggerAttack();\n * }, 1, 1);\n */\n get decayCurve() {\n return this._decayCurve;\n }\n set decayCurve(curve) {\n Debug_assert(["linear", "exponential"].some(c => c === curve), `Invalid envelope curve: ${curve}`);\n this._decayCurve = curve;\n }\n /**\n * Trigger the attack/decay portion of the ADSR envelope.\n * @param time When the attack should start.\n * @param velocity The velocity of the envelope scales the vales.\n * number between 0-1\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator().connect(env).start();\n * // trigger the attack 0.5 seconds from now with a velocity of 0.2\n * env.triggerAttack("+0.5", 0.2);\n */\n triggerAttack(time, velocity = 1) {\n this.log("triggerAttack", time, velocity);\n time = this.toSeconds(time);\n const originalAttack = this.toSeconds(this.attack);\n let attack = originalAttack;\n const decay = this.toSeconds(this.decay);\n // check if it\'s not a complete attack\n const currentValue = this.getValueAtTime(time);\n if (currentValue > 0) {\n // subtract the current value from the attack time\n const attackRate = 1 / attack;\n const remainingDistance = 1 - currentValue;\n // the attack is now the remaining time\n attack = remainingDistance / attackRate;\n }\n // attack\n if (attack < this.sampleTime) {\n this._sig.cancelScheduledValues(time);\n // case where the attack time is 0 should set instantly\n this._sig.setValueAtTime(velocity, time);\n }\n else if (this._attackCurve === "linear") {\n this._sig.linearRampTo(velocity, attack, time);\n }\n else if (this._attackCurve === "exponential") {\n this._sig.targetRampTo(velocity, attack, time);\n }\n else {\n this._sig.cancelAndHoldAtTime(time);\n let curve = this._attackCurve;\n // find the starting position in the curve\n for (let i = 1; i < curve.length; i++) {\n // the starting index is between the two values\n if (curve[i - 1] <= currentValue && currentValue <= curve[i]) {\n curve = this._attackCurve.slice(i);\n // the first index is the current value\n curve[0] = currentValue;\n break;\n }\n }\n this._sig.setValueCurveAtTime(curve, time, attack, velocity);\n }\n // decay\n if (decay && this.sustain < 1) {\n const decayValue = velocity * this.sustain;\n const decayStart = time + attack;\n this.log("decay", decayStart);\n if (this._decayCurve === "linear") {\n this._sig.linearRampToValueAtTime(decayValue, decay + decayStart);\n }\n else {\n this._sig.exponentialApproachValueAtTime(decayValue, decayStart, decay);\n }\n }\n return this;\n }\n /**\n * Triggers the release of the envelope.\n * @param time When the release portion of the envelope should start.\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator({\n * \ttype: "sawtooth"\n * }).connect(env).start();\n * env.triggerAttack();\n * // trigger the release half a second after the attack\n * env.triggerRelease("+0.5");\n */\n triggerRelease(time) {\n this.log("triggerRelease", time);\n time = this.toSeconds(time);\n const currentValue = this.getValueAtTime(time);\n if (currentValue > 0) {\n const release = this.toSeconds(this.release);\n if (release < this.sampleTime) {\n this._sig.setValueAtTime(0, time);\n }\n else if (this._releaseCurve === "linear") {\n this._sig.linearRampTo(0, release, time);\n }\n else if (this._releaseCurve === "exponential") {\n this._sig.targetRampTo(0, release, time);\n }\n else {\n Debug_assert(TypeCheck_isArray(this._releaseCurve), "releaseCurve must be either \'linear\', \'exponential\' or an array");\n this._sig.cancelAndHoldAtTime(time);\n this._sig.setValueCurveAtTime(this._releaseCurve, time, release, currentValue);\n }\n }\n return this;\n }\n /**\n * Get the scheduled value at the given time. This will\n * return the unconverted (raw) value.\n * @example\n * const env = new Tone.Envelope(0.5, 1, 0.4, 2);\n * env.triggerAttackRelease(2);\n * setInterval(() => console.log(env.getValueAtTime(Tone.now())), 100);\n */\n getValueAtTime(time) {\n return this._sig.getValueAtTime(time);\n }\n /**\n * triggerAttackRelease is shorthand for triggerAttack, then waiting\n * some duration, then triggerRelease.\n * @param duration The duration of the sustain.\n * @param time When the attack should be triggered.\n * @param velocity The velocity of the envelope.\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator().connect(env).start();\n * // trigger the release 0.5 seconds after the attack\n * env.triggerAttackRelease(0.5);\n */\n triggerAttackRelease(duration, time, velocity = 1) {\n time = this.toSeconds(time);\n this.triggerAttack(time, velocity);\n this.triggerRelease(time + this.toSeconds(duration));\n return this;\n }\n /**\n * Cancels all scheduled envelope changes after the given time.\n */\n cancel(after) {\n this._sig.cancelScheduledValues(this.toSeconds(after));\n return this;\n }\n /**\n * Connect the envelope to a destination node.\n */\n connect(destination, outputNumber = 0, inputNumber = 0) {\n Signal_connectSignal(this, destination, outputNumber, inputNumber);\n return this;\n }\n /**\n * Render the envelope curve to an array of the given length.\n * Good for visualizing the envelope curve. Rescales the duration of the\n * envelope to fit the length.\n */\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const duration = length / this.context.sampleRate;\n const context = new OfflineContext_OfflineContext(1, duration, this.context.sampleRate);\n // normalize the ADSR for the given duration with 20% sustain time\n const attackPortion = this.toSeconds(this.attack) + this.toSeconds(this.decay);\n const envelopeDuration = attackPortion + this.toSeconds(this.release);\n const sustainTime = envelopeDuration * 0.1;\n const totalDuration = envelopeDuration + sustainTime;\n // @ts-ignore\n const clone = new this.constructor(Object.assign(this.get(), {\n attack: duration * this.toSeconds(this.attack) / totalDuration,\n decay: duration * this.toSeconds(this.decay) / totalDuration,\n release: duration * this.toSeconds(this.release) / totalDuration,\n context\n }));\n clone._sig.toDestination();\n clone.triggerAttackRelease(duration * (attackPortion + sustainTime) / totalDuration, 0);\n const buffer = yield context.render();\n return buffer.getChannelData(0);\n });\n }\n dispose() {\n super.dispose();\n this._sig.dispose();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "attack", void 0);\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "decay", void 0);\n__decorate([\n range(0, 1)\n], Envelope_Envelope.prototype, "sustain", void 0);\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "release", void 0);\n/**\n * Generate some complex envelope curves.\n */\nconst EnvelopeCurves = (() => {\n const curveLen = 128;\n let i;\n let k;\n // cosine curve\n const cosineCurve = [];\n for (i = 0; i < curveLen; i++) {\n cosineCurve[i] = Math.sin((i / (curveLen - 1)) * (Math.PI / 2));\n }\n // ripple curve\n const rippleCurve = [];\n const rippleCurveFreq = 6.4;\n for (i = 0; i < curveLen - 1; i++) {\n k = (i / (curveLen - 1));\n const sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1;\n rippleCurve[i] = sineWave / 10 + k * 0.83;\n }\n rippleCurve[curveLen - 1] = 1;\n // stairs curve\n const stairsCurve = [];\n const steps = 5;\n for (i = 0; i < curveLen; i++) {\n stairsCurve[i] = Math.ceil((i / (curveLen - 1)) * steps) / steps;\n }\n // in-out easing curve\n const sineCurve = [];\n for (i = 0; i < curveLen; i++) {\n k = i / (curveLen - 1);\n sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k));\n }\n // a bounce curve\n const bounceCurve = [];\n for (i = 0; i < curveLen; i++) {\n k = i / (curveLen - 1);\n const freq = Math.pow(k, 3) * 4 + 0.2;\n const val = Math.cos(freq * Math.PI * 2 * k);\n bounceCurve[i] = Math.abs(val * (1 - k));\n }\n /**\n * Invert a value curve to make it work for the release\n */\n function invertCurve(curve) {\n const out = new Array(curve.length);\n for (let j = 0; j < curve.length; j++) {\n out[j] = 1 - curve[j];\n }\n return out;\n }\n /**\n * reverse the curve\n */\n function reverseCurve(curve) {\n return curve.slice(0).reverse();\n }\n /**\n * attack and release curve arrays\n */\n return {\n bounce: {\n In: invertCurve(bounceCurve),\n Out: bounceCurve,\n },\n cosine: {\n In: cosineCurve,\n Out: reverseCurve(cosineCurve),\n },\n exponential: "exponential",\n linear: "linear",\n ripple: {\n In: rippleCurve,\n Out: invertCurve(rippleCurve),\n },\n sine: {\n In: sineCurve,\n Out: invertCurve(sineCurve),\n },\n step: {\n In: stairsCurve,\n Out: invertCurve(stairsCurve),\n },\n };\n})();\n//# sourceMappingURL=Envelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Instrument.js\n\n\n\n\n/**\n * Base-class for all instruments\n */\nclass Instrument_Instrument extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Instrument_Instrument.getDefaults(), arguments));\n /**\n * Keep track of all events scheduled to the transport\n * when the instrument is \'synced\'\n */\n this._scheduledEvents = [];\n /**\n * If the instrument is currently synced\n */\n this._synced = false;\n this._original_triggerAttack = this.triggerAttack;\n this._original_triggerRelease = this.triggerRelease;\n const options = Defaults_optionsFromArguments(Instrument_Instrument.getDefaults(), arguments);\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n Interface_readOnly(this, "volume");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n volume: 0,\n });\n }\n /**\n * Sync the instrument to the Transport. All subsequent calls of\n * [[triggerAttack]] and [[triggerRelease]] will be scheduled along the transport.\n * @example\n * const fmSynth = new Tone.FMSynth().toDestination();\n * fmSynth.volume.value = -6;\n * fmSynth.sync();\n * // schedule 3 notes when the transport first starts\n * fmSynth.triggerAttackRelease("C4", "8n", 0);\n * fmSynth.triggerAttackRelease("E4", "8n", "8n");\n * fmSynth.triggerAttackRelease("G4", "8n", "4n");\n * // start the transport to hear the notes\n * Tone.Transport.start();\n */\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 0);\n }\n return this;\n }\n /**\n * set _sync\n */\n _syncState() {\n let changed = false;\n if (!this._synced) {\n this._synced = true;\n changed = true;\n }\n return changed;\n }\n /**\n * Wrap the given method so that it can be synchronized\n * @param method Which method to wrap and sync\n * @param timePosition What position the time argument appears in\n */\n _syncMethod(method, timePosition) {\n const originalMethod = this["_original_" + method] = this[method];\n this[method] = (...args) => {\n const time = args[timePosition];\n const id = this.context.transport.schedule((t) => {\n args[timePosition] = t;\n originalMethod.apply(this, args);\n }, time);\n this._scheduledEvents.push(id);\n };\n }\n /**\n * Unsync the instrument from the Transport\n */\n unsync() {\n this._scheduledEvents.forEach(id => this.context.transport.clear(id));\n this._scheduledEvents = [];\n if (this._synced) {\n this._synced = false;\n this.triggerAttack = this._original_triggerAttack;\n this.triggerRelease = this._original_triggerRelease;\n }\n return this;\n }\n /**\n * Trigger the attack and then the release after the duration.\n * @param note The note to trigger.\n * @param duration How long the note should be held for before\n * triggering the release. This value must be greater than 0.\n * @param time When the note should be triggered.\n * @param velocity The velocity the note should be triggered at.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // trigger "C4" for the duration of an 8th note\n * synth.triggerAttackRelease("C4", "8n");\n */\n triggerAttackRelease(note, duration, time, velocity) {\n const computedTime = this.toSeconds(time);\n const computedDuration = this.toSeconds(duration);\n this.triggerAttack(note, computedTime, velocity);\n this.triggerRelease(computedTime + computedDuration);\n return this;\n }\n /**\n * clean up\n * @returns {Instrument} this\n */\n dispose() {\n super.dispose();\n this._volume.dispose();\n this.unsync();\n this._scheduledEvents = [];\n return this;\n }\n}\n//# sourceMappingURL=Instrument.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Monophonic.js\n\n\n\n\n\n\n/**\n * Abstract base class for other monophonic instruments to extend.\n */\nclass Monophonic_Monophonic extends Instrument_Instrument {\n constructor() {\n super(Defaults_optionsFromArguments(Monophonic_Monophonic.getDefaults(), arguments));\n const options = Defaults_optionsFromArguments(Monophonic_Monophonic.getDefaults(), arguments);\n this.portamento = options.portamento;\n this.onsilence = options.onsilence;\n }\n static getDefaults() {\n return Object.assign(Instrument_Instrument.getDefaults(), {\n detune: 0,\n onsilence: Interface_noOp,\n portamento: 0,\n });\n }\n /**\n * Trigger the attack of the note optionally with a given velocity.\n * @param note The note to trigger.\n * @param time When the note should start.\n * @param velocity The velocity scaler determines how "loud" the note will be triggered.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // trigger the note a half second from now at half velocity\n * synth.triggerAttack("C4", "+0.5", 0.5);\n */\n triggerAttack(note, time, velocity = 1) {\n this.log("triggerAttack", note, time, velocity);\n const seconds = this.toSeconds(time);\n this._triggerEnvelopeAttack(seconds, velocity);\n this.setNote(note, seconds);\n return this;\n }\n /**\n * Trigger the release portion of the envelope\n * @param time If no time is given, the release happens immediatly\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttack("C4");\n * // trigger the release a second from now\n * synth.triggerRelease("+1");\n */\n triggerRelease(time) {\n this.log("triggerRelease", time);\n const seconds = this.toSeconds(time);\n this._triggerEnvelopeRelease(seconds);\n return this;\n }\n /**\n * Set the note at the given time. If no time is given, the note\n * will set immediately.\n * @param note The note to change to.\n * @param time The time when the note should be set.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttack("C4");\n * // change to F#6 in one quarter note from now.\n * synth.setNote("F#6", "+4n");\n */\n setNote(note, time) {\n const computedTime = this.toSeconds(time);\n const computedFrequency = note instanceof Frequency_FrequencyClass ? note.toFrequency() : note;\n if (this.portamento > 0 && this.getLevelAtTime(computedTime) > 0.05) {\n const portTime = this.toSeconds(this.portamento);\n this.frequency.exponentialRampTo(computedFrequency, portTime, computedTime);\n }\n else {\n this.frequency.setValueAtTime(computedFrequency, computedTime);\n }\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Monophonic_Monophonic.prototype, "portamento", void 0);\n//# sourceMappingURL=Monophonic.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/AmplitudeEnvelope.js\n\n\n\n/**\n * AmplitudeEnvelope is a Tone.Envelope connected to a gain node.\n * Unlike Tone.Envelope, which outputs the envelope\'s value, AmplitudeEnvelope accepts\n * an audio signal as the input and will apply the envelope to the amplitude\n * of the signal.\n * Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope).\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst ampEnv = new Tone.AmplitudeEnvelope({\n * \t\tattack: 0.1,\n * \t\tdecay: 0.2,\n * \t\tsustain: 1.0,\n * \t\trelease: 0.8\n * \t}).toDestination();\n * \t// create an oscillator and connect it\n * \tconst osc = new Tone.Oscillator().connect(ampEnv).start();\n * \t// trigger the envelopes attack and release "8t" apart\n * \tampEnv.triggerAttackRelease("8t");\n * }, 1.5, 1);\n * @category Component\n */\nclass AmplitudeEnvelope_AmplitudeEnvelope extends Envelope_Envelope {\n constructor() {\n super(Defaults_optionsFromArguments(AmplitudeEnvelope_AmplitudeEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "AmplitudeEnvelope";\n this._gainNode = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n this.output = this._gainNode;\n this.input = this._gainNode;\n this._sig.connect(this._gainNode.gain);\n this.output = this._gainNode;\n this.input = this._gainNode;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._gainNode.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AmplitudeEnvelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Synth.js\n\n\n\n\n\n\n\n\n/**\n * Synth is composed simply of a [[OmniOscillator]] routed through an [[AmplitudeEnvelope]].\n * ```\n * +----------------+ +-------------------+\n * | OmniOscillator +>--\x3e AmplitudeEnvelope +>--\x3e Output\n * +----------------+ +-------------------+\n * ```\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttackRelease("C4", "8n");\n * @category Instrument\n */\nclass Synth_Synth extends Monophonic_Monophonic {\n constructor() {\n super(Defaults_optionsFromArguments(Synth_Synth.getDefaults(), arguments));\n this.name = "Synth";\n const options = Defaults_optionsFromArguments(Synth_Synth.getDefaults(), arguments);\n this.oscillator = new OmniOscillator_OmniOscillator(Object.assign({\n context: this.context,\n detune: options.detune,\n onstop: () => this.onsilence(this),\n }, options.oscillator));\n this.frequency = this.oscillator.frequency;\n this.detune = this.oscillator.detune;\n this.envelope = new AmplitudeEnvelope_AmplitudeEnvelope(Object.assign({\n context: this.context,\n }, options.envelope));\n // connect the oscillators to the output\n this.oscillator.chain(this.envelope, this.output);\n Interface_readOnly(this, ["oscillator", "frequency", "detune", "envelope"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic_Monophonic.getDefaults(), {\n envelope: Object.assign(Defaults_omitFromObject(Envelope_Envelope.getDefaults(), Object.keys(ToneAudioNode_ToneAudioNode.getDefaults())), {\n attack: 0.005,\n decay: 0.1,\n release: 1,\n sustain: 0.3,\n }),\n oscillator: Object.assign(Defaults_omitFromObject(OmniOscillator_OmniOscillator.getDefaults(), [...Object.keys(Source_Source.getDefaults()), "frequency", "detune"]), {\n type: "triangle",\n }),\n });\n }\n /**\n * start the attack portion of the envelope\n * @param time the time the attack should start\n * @param velocity the velocity of the note (0-1)\n */\n _triggerEnvelopeAttack(time, velocity) {\n // the envelopes\n this.envelope.triggerAttack(time, velocity);\n this.oscillator.start(time);\n // if there is no release portion, stop the oscillator\n if (this.envelope.sustain === 0) {\n const computedAttack = this.toSeconds(this.envelope.attack);\n const computedDecay = this.toSeconds(this.envelope.decay);\n this.oscillator.stop(time + computedAttack + computedDecay);\n }\n }\n /**\n * start the release portion of the envelope\n * @param time the time the release should start\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this.oscillator.stop(time + this.toSeconds(this.envelope.release));\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this.oscillator.dispose();\n this.envelope.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Synth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/ModulationSynth.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Base class for both AM and FM synths\n */\nclass ModulationSynth_ModulationSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(ModulationSynth_ModulationSynth.getDefaults(), arguments));\n this.name = "ModulationSynth";\n const options = optionsFromArguments(ModulationSynth_ModulationSynth.getDefaults(), arguments);\n this._carrier = new Synth({\n context: this.context,\n oscillator: options.oscillator,\n envelope: options.envelope,\n onsilence: () => this.onsilence(this),\n volume: -10,\n });\n this._modulator = new Synth({\n context: this.context,\n oscillator: options.modulation,\n envelope: options.modulationEnvelope,\n volume: -10,\n });\n this.oscillator = this._carrier.oscillator;\n this.envelope = this._carrier.envelope;\n this.modulation = this._modulator.oscillator;\n this.modulationEnvelope = this._modulator.envelope;\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n });\n this.detune = new Signal({\n context: this.context,\n value: options.detune,\n units: "cents"\n });\n this.harmonicity = new Multiply({\n context: this.context,\n value: options.harmonicity,\n minValue: 0,\n });\n this._modulationNode = new Gain({\n context: this.context,\n gain: 0,\n });\n readOnly(this, ["frequency", "harmonicity", "oscillator", "envelope", "modulation", "modulationEnvelope", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic.getDefaults(), {\n harmonicity: 3,\n oscillator: Object.assign(omitFromObject(OmniOscillator.getDefaults(), [\n ...Object.keys(Source.getDefaults()),\n "frequency",\n "detune"\n ]), {\n type: "sine"\n }),\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.01,\n decay: 0.01,\n sustain: 1,\n release: 0.5\n }),\n modulation: Object.assign(omitFromObject(OmniOscillator.getDefaults(), [\n ...Object.keys(Source.getDefaults()),\n "frequency",\n "detune"\n ]), {\n type: "square"\n }),\n modulationEnvelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.5,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n })\n });\n }\n /**\n * Trigger the attack portion of the note\n */\n _triggerEnvelopeAttack(time, velocity) {\n // @ts-ignore\n this._carrier._triggerEnvelopeAttack(time, velocity);\n // @ts-ignore\n this._modulator._triggerEnvelopeAttack(time, velocity);\n }\n /**\n * Trigger the release portion of the note\n */\n _triggerEnvelopeRelease(time) {\n // @ts-ignore\n this._carrier._triggerEnvelopeRelease(time);\n // @ts-ignore\n this._modulator._triggerEnvelopeRelease(time);\n return this;\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n dispose() {\n super.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this.harmonicity.dispose();\n this._modulationNode.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ModulationSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/AMSynth.js\n\n\n\n/**\n * AMSynth uses the output of one Tone.Synth to modulate the\n * amplitude of another Tone.Synth. The harmonicity (the ratio between\n * the two signals) affects the timbre of the output signal greatly.\n * Read more about Amplitude Modulation Synthesis on\n * [SoundOnSound](https://web.archive.org/web/20160404103653/http://www.soundonsound.com:80/sos/mar00/articles/synthsecrets.htm).\n *\n * @example\n * const synth = new Tone.AMSynth().toDestination();\n * synth.triggerAttackRelease("C4", "4n");\n *\n * @category Instrument\n */\nclass AMSynth extends (/* unused pure expression or super */ null && (ModulationSynth)) {\n constructor() {\n super(optionsFromArguments(AMSynth.getDefaults(), arguments));\n this.name = "AMSynth";\n this._modulationScale = new AudioToGain({\n context: this.context,\n });\n // control the two voices frequency\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.detune.fan(this._carrier.detune, this._modulator.detune);\n this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n this._carrier.chain(this._modulationNode, this.output);\n }\n dispose() {\n super.dispose();\n this._modulationScale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AMSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/BiquadFilter.js\n\n\n\n\n/**\n * Thin wrapper around the native Web Audio [BiquadFilterNode](https://webaudio.github.io/web-audio-api/#biquadfilternode).\n * BiquadFilter is similar to [[Filter]] but doesn\'t have the option to set the "rolloff" value.\n * @category Component\n */\nclass BiquadFilter_BiquadFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(BiquadFilter_BiquadFilter.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "BiquadFilter";\n const options = optionsFromArguments(BiquadFilter_BiquadFilter.getDefaults(), arguments, ["frequency", "type"]);\n this._filter = this.context.createBiquadFilter();\n this.input = this.output = this._filter;\n this.Q = new Param({\n context: this.context,\n units: "number",\n value: options.Q,\n param: this._filter.Q,\n });\n this.frequency = new Param({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n param: this._filter.frequency,\n });\n this.detune = new Param({\n context: this.context,\n units: "cents",\n value: options.detune,\n param: this._filter.detune,\n });\n this.gain = new Param({\n context: this.context,\n units: "decibels",\n convert: false,\n value: options.gain,\n param: this._filter.gain,\n });\n this.type = options.type;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n type: "lowpass",\n frequency: 350,\n detune: 0,\n gain: 0,\n });\n }\n /**\n * The type of this BiquadFilterNode. For a complete list of types and their attributes, see the\n * [Web Audio API](https://webaudio.github.io/web-audio-api/#dom-biquadfiltertype-lowpass)\n */\n get type() {\n return this._filter.type;\n }\n set type(type) {\n const types = ["lowpass", "highpass", "bandpass",\n "lowshelf", "highshelf", "notch", "allpass", "peaking"];\n assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`);\n this._filter.type = type;\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n // start with all 1s\n const freqValues = new Float32Array(len);\n for (let i = 0; i < len; i++) {\n const norm = Math.pow(i / len, 2);\n const freq = norm * (20000 - 20) + 20;\n freqValues[i] = freq;\n }\n const magValues = new Float32Array(len);\n const phaseValues = new Float32Array(len);\n // clone the filter to remove any connections which may be changing the value\n const filterClone = this.context.createBiquadFilter();\n filterClone.type = this.type;\n filterClone.Q.value = this.Q.value;\n filterClone.frequency.value = this.frequency.value;\n filterClone.gain.value = this.gain.value;\n filterClone.getFrequencyResponse(freqValues, magValues, phaseValues);\n return magValues;\n }\n dispose() {\n super.dispose();\n this._filter.disconnect();\n this.Q.dispose();\n this.frequency.dispose();\n this.gain.dispose();\n this.detune.dispose();\n return this;\n }\n}\n//# sourceMappingURL=BiquadFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/Filter.js\n\n\n\n\n\n\n\n\n/**\n * Tone.Filter is a filter which allows for all of the same native methods\n * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface).\n * Tone.Filter has the added ability to set the filter rolloff at -12\n * (default), -24 and -48.\n * @example\n * const filter = new Tone.Filter(1500, "highpass").toDestination();\n * filter.frequency.rampTo(20000, 10);\n * const noise = new Tone.Noise().connect(filter).start();\n * @category Component\n */\nclass Filter_Filter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Filter_Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]));\n this.name = "Filter";\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this._filters = [];\n const options = optionsFromArguments(Filter_Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]);\n this._filters = [];\n this.Q = new Signal({\n context: this.context,\n units: "positive",\n value: options.Q,\n });\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this.gain = new Signal({\n context: this.context,\n units: "decibels",\n convert: false,\n value: options.gain,\n });\n this._type = options.type;\n this.rolloff = options.rolloff;\n readOnly(this, ["detune", "frequency", "gain", "Q"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n detune: 0,\n frequency: 350,\n gain: 0,\n rolloff: -12,\n type: "lowpass",\n });\n }\n /**\n * The type of the filter. Types: "lowpass", "highpass",\n * "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking".\n */\n get type() {\n return this._type;\n }\n set type(type) {\n const types = ["lowpass", "highpass", "bandpass",\n "lowshelf", "highshelf", "notch", "allpass", "peaking"];\n assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`);\n this._type = type;\n this._filters.forEach(filter => filter.type = type);\n }\n /**\n * The rolloff of the filter which is the drop in db\n * per octave. Implemented internally by cascading filters.\n * Only accepts the values -12, -24, -48 and -96.\n */\n get rolloff() {\n return this._rolloff;\n }\n set rolloff(rolloff) {\n const rolloffNum = isNumber(rolloff) ? rolloff : parseInt(rolloff, 10);\n const possibilities = [-12, -24, -48, -96];\n let cascadingCount = possibilities.indexOf(rolloffNum);\n // check the rolloff is valid\n assert(cascadingCount !== -1, `rolloff can only be ${possibilities.join(", ")}`);\n cascadingCount += 1;\n this._rolloff = rolloffNum;\n this.input.disconnect();\n this._filters.forEach(filter => filter.disconnect());\n this._filters = new Array(cascadingCount);\n for (let count = 0; count < cascadingCount; count++) {\n const filter = new BiquadFilter({\n context: this.context,\n });\n filter.type = this._type;\n this.frequency.connect(filter.frequency);\n this.detune.connect(filter.detune);\n this.Q.connect(filter.Q);\n this.gain.connect(filter.gain);\n this._filters[count] = filter;\n }\n this._internalChannels = this._filters;\n connectSeries(this.input, ...this._internalChannels, this.output);\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n const filterClone = new BiquadFilter({\n frequency: this.frequency.value,\n gain: this.gain.value,\n Q: this.Q.value,\n type: this._type,\n detune: this.detune.value,\n });\n // start with all 1s\n const totalResponse = new Float32Array(len).map(() => 1);\n this._filters.forEach(() => {\n const response = filterClone.getFrequencyResponse(len);\n response.forEach((val, i) => totalResponse[i] *= val);\n });\n filterClone.dispose();\n return totalResponse;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._filters.forEach(filter => {\n filter.dispose();\n });\n writable(this, ["detune", "frequency", "gain", "Q"]);\n this.frequency.dispose();\n this.Q.dispose();\n this.detune.dispose();\n this.gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Filter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/FrequencyEnvelope.js\n\n\n\n\n\n/**\n * FrequencyEnvelope is an [[Envelope]] which ramps between [[baseFrequency]]\n * and [[octaves]]. It can also have an optional [[exponent]] to adjust the curve\n * which it ramps.\n * @example\n * const oscillator = new Tone.Oscillator().toDestination().start();\n * const freqEnv = new Tone.FrequencyEnvelope({\n * \tattack: 0.2,\n * \tbaseFrequency: "C2",\n * \toctaves: 4\n * });\n * freqEnv.connect(oscillator.frequency);\n * freqEnv.triggerAttack();\n * @category Component\n */\nclass FrequencyEnvelope_FrequencyEnvelope extends (/* unused pure expression or super */ null && (Envelope)) {\n constructor() {\n super(optionsFromArguments(FrequencyEnvelope_FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "FrequencyEnvelope";\n const options = optionsFromArguments(FrequencyEnvelope_FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]);\n this._octaves = options.octaves;\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._exponent = this.input = new Pow({\n context: this.context,\n value: options.exponent\n });\n this._scale = this.output = new Scale({\n context: this.context,\n min: this._baseFrequency,\n max: this._baseFrequency * Math.pow(2, this._octaves),\n });\n this._sig.chain(this._exponent, this._scale);\n }\n static getDefaults() {\n return Object.assign(Envelope.getDefaults(), {\n baseFrequency: 200,\n exponent: 1,\n octaves: 4,\n });\n }\n /**\n * The envelope\'s minimum output value. This is the value which it\n * starts at.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(min) {\n const freq = this.toFrequency(min);\n assertRange(freq, 0);\n this._baseFrequency = freq;\n this._scale.min = this._baseFrequency;\n // update the max value when the min changes\n this.octaves = this._octaves;\n }\n /**\n * The number of octaves above the baseFrequency that the\n * envelope will scale to.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n this._scale.max = this._baseFrequency * Math.pow(2, octaves);\n }\n /**\n * The envelope\'s exponent value.\n */\n get exponent() {\n return this._exponent.value;\n }\n set exponent(exponent) {\n this._exponent.value = exponent;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._exponent.dispose();\n this._scale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FrequencyEnvelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MonoSynth.js\n\n\n\n\n\n\n\n\n\n\n/**\n * MonoSynth is composed of one `oscillator`, one `filter`, and two `envelopes`.\n * The amplitude of the Oscillator and the cutoff frequency of the\n * Filter are controlled by Envelopes.\n * <img src="https://docs.google.com/drawings/d/1gaY1DF9_Hzkodqf8JI1Cg2VZfwSElpFQfI94IQwad38/pub?w=924&h=240">\n * @example\n * const synth = new Tone.MonoSynth({\n * \toscillator: {\n * \t\ttype: "square"\n * \t},\n * \tenvelope: {\n * \t\tattack: 0.1\n * \t}\n * }).toDestination();\n * synth.triggerAttackRelease("C4", "8n");\n * @category Instrument\n */\nclass MonoSynth_MonoSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(MonoSynth_MonoSynth.getDefaults(), arguments));\n this.name = "MonoSynth";\n const options = optionsFromArguments(MonoSynth_MonoSynth.getDefaults(), arguments);\n this.oscillator = new OmniOscillator(Object.assign(options.oscillator, {\n context: this.context,\n detune: options.detune,\n onstop: () => this.onsilence(this),\n }));\n this.frequency = this.oscillator.frequency;\n this.detune = this.oscillator.detune;\n this.filter = new Filter(Object.assign(options.filter, { context: this.context }));\n this.filterEnvelope = new FrequencyEnvelope(Object.assign(options.filterEnvelope, { context: this.context }));\n this.envelope = new AmplitudeEnvelope(Object.assign(options.envelope, { context: this.context }));\n // connect the oscillators to the output\n this.oscillator.chain(this.filter, this.envelope, this.output);\n // connect the filter envelope\n this.filterEnvelope.connect(this.filter.frequency);\n readOnly(this, ["oscillator", "frequency", "detune", "filter", "filterEnvelope", "envelope"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.005,\n decay: 0.1,\n release: 1,\n sustain: 0.9,\n }),\n filter: Object.assign(omitFromObject(Filter.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n Q: 1,\n rolloff: -12,\n type: "lowpass",\n }),\n filterEnvelope: Object.assign(omitFromObject(FrequencyEnvelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.6,\n baseFrequency: 200,\n decay: 0.2,\n exponent: 2,\n octaves: 3,\n release: 2,\n sustain: 0.5,\n }),\n oscillator: Object.assign(omitFromObject(OmniOscillator.getDefaults(), Object.keys(Source.getDefaults())), {\n type: "sawtooth",\n }),\n });\n }\n /**\n * start the attack portion of the envelope\n * @param time the time the attack should start\n * @param velocity the velocity of the note (0-1)\n */\n _triggerEnvelopeAttack(time, velocity = 1) {\n this.envelope.triggerAttack(time, velocity);\n this.filterEnvelope.triggerAttack(time);\n this.oscillator.start(time);\n if (this.envelope.sustain === 0) {\n const computedAttack = this.toSeconds(this.envelope.attack);\n const computedDecay = this.toSeconds(this.envelope.decay);\n this.oscillator.stop(time + computedAttack + computedDecay);\n }\n }\n /**\n * start the release portion of the envelope\n * @param time the time the release should start\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this.filterEnvelope.triggerRelease(time);\n this.oscillator.stop(time + this.toSeconds(this.envelope.release));\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n dispose() {\n super.dispose();\n this.oscillator.dispose();\n this.envelope.dispose();\n this.filterEnvelope.dispose();\n this.filter.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MonoSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/DuoSynth.js\n\n\n\n\n\n\n\n\n/**\n * DuoSynth is a monophonic synth composed of two [[MonoSynths]] run in parallel with control over the\n * frequency ratio between the two voices and vibrato effect.\n * @example\n * const duoSynth = new Tone.DuoSynth().toDestination();\n * duoSynth.triggerAttackRelease("C4", "2n");\n * @category Instrument\n */\nclass DuoSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(DuoSynth.getDefaults(), arguments));\n this.name = "DuoSynth";\n const options = optionsFromArguments(DuoSynth.getDefaults(), arguments);\n this.voice0 = new MonoSynth(Object.assign(options.voice0, {\n context: this.context,\n onsilence: () => this.onsilence(this)\n }));\n this.voice1 = new MonoSynth(Object.assign(options.voice1, {\n context: this.context,\n }));\n this.harmonicity = new Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n this._vibrato = new LFO({\n frequency: options.vibratoRate,\n context: this.context,\n min: -50,\n max: 50\n });\n // start the vibrato immediately\n this._vibrato.start();\n this.vibratoRate = this._vibrato.frequency;\n this._vibratoGain = new Gain({\n context: this.context,\n units: "normalRange",\n gain: options.vibratoAmount\n });\n this.vibratoAmount = this._vibratoGain.gain;\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: 440\n });\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune\n });\n // control the two voices frequency\n this.frequency.connect(this.voice0.frequency);\n this.frequency.chain(this.harmonicity, this.voice1.frequency);\n this._vibrato.connect(this._vibratoGain);\n this._vibratoGain.fan(this.voice0.detune, this.voice1.detune);\n this.detune.fan(this.voice0.detune, this.voice1.detune);\n this.voice0.connect(this.output);\n this.voice1.connect(this.output);\n readOnly(this, ["voice0", "voice1", "frequency", "vibratoAmount", "vibratoRate"]);\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.voice0.envelope.getValueAtTime(time) + this.voice1.envelope.getValueAtTime(time);\n }\n static getDefaults() {\n return deepMerge(Monophonic.getDefaults(), {\n vibratoAmount: 0.5,\n vibratoRate: 5,\n harmonicity: 1.5,\n voice0: deepMerge(omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), {\n filterEnvelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n },\n envelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n }\n }),\n voice1: deepMerge(omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), {\n filterEnvelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n },\n envelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n }\n }),\n });\n }\n /**\n * Trigger the attack portion of the note\n */\n _triggerEnvelopeAttack(time, velocity) {\n // @ts-ignore\n this.voice0._triggerEnvelopeAttack(time, velocity);\n // @ts-ignore\n this.voice1._triggerEnvelopeAttack(time, velocity);\n }\n /**\n * Trigger the release portion of the note\n */\n _triggerEnvelopeRelease(time) {\n // @ts-ignore\n this.voice0._triggerEnvelopeRelease(time);\n // @ts-ignore\n this.voice1._triggerEnvelopeRelease(time);\n return this;\n }\n dispose() {\n super.dispose();\n this.voice0.dispose();\n this.voice1.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this._vibrato.dispose();\n this.vibratoRate.dispose();\n this._vibratoGain.dispose();\n this.harmonicity.dispose();\n return this;\n }\n}\n//# sourceMappingURL=DuoSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/FMSynth.js\n\n\n\n/**\n * FMSynth is composed of two Tone.Synths where one Tone.Synth modulates\n * the frequency of a second Tone.Synth. A lot of spectral content\n * can be explored using the modulationIndex parameter. Read more about\n * frequency modulation synthesis on Sound On Sound: [Part 1](https://web.archive.org/web/20160403123704/http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm), [Part 2](https://web.archive.org/web/20160403115835/http://www.soundonsound.com/sos/may00/articles/synth.htm).\n *\n * @example\n * const fmSynth = new Tone.FMSynth().toDestination();\n * fmSynth.triggerAttackRelease("C5", "4n");\n *\n * @category Instrument\n */\nclass FMSynth extends (/* unused pure expression or super */ null && (ModulationSynth)) {\n constructor() {\n super(optionsFromArguments(FMSynth.getDefaults(), arguments));\n this.name = "FMSynth";\n const options = optionsFromArguments(FMSynth.getDefaults(), arguments);\n this.modulationIndex = new Multiply({\n context: this.context,\n value: options.modulationIndex,\n });\n // control the two voices frequency\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.frequency.chain(this.modulationIndex, this._modulationNode);\n this.detune.fan(this._carrier.detune, this._modulator.detune);\n this._modulator.connect(this._modulationNode.gain);\n this._modulationNode.connect(this._carrier.frequency);\n this._carrier.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(ModulationSynth.getDefaults(), {\n modulationIndex: 10,\n });\n }\n dispose() {\n super.dispose();\n this.modulationIndex.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FMSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MetalSynth.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Inharmonic ratio of frequencies based on the Roland TR-808\n * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model\n */\nconst inharmRatios = (/* unused pure expression or super */ null && ([1.0, 1.483, 1.932, 2.546, 2.630, 3.897]));\n/**\n * A highly inharmonic and spectrally complex source with a highpass filter\n * and amplitude envelope which is good for making metallophone sounds.\n * Based on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic).\n * Inspiration from [Sound on Sound](https://shorturl.at/rSZ12).\n * @category Instrument\n */\nclass MetalSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(MetalSynth.getDefaults(), arguments));\n this.name = "MetalSynth";\n /**\n * The array of FMOscillators\n */\n this._oscillators = [];\n /**\n * The frequency multipliers\n */\n this._freqMultipliers = [];\n const options = optionsFromArguments(MetalSynth.getDefaults(), arguments);\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n });\n this._amplitude = new Gain({\n context: this.context,\n gain: 0,\n }).connect(this.output);\n this._highpass = new Filter({\n // Q: -3.0102999566398125,\n Q: 0,\n context: this.context,\n type: "highpass",\n }).connect(this._amplitude);\n for (let i = 0; i < inharmRatios.length; i++) {\n const osc = new FMOscillator({\n context: this.context,\n harmonicity: options.harmonicity,\n modulationIndex: options.modulationIndex,\n modulationType: "square",\n onstop: i === 0 ? () => this.onsilence(this) : noOp,\n type: "square",\n });\n osc.connect(this._highpass);\n this._oscillators[i] = osc;\n const mult = new Multiply({\n context: this.context,\n value: inharmRatios[i],\n });\n this._freqMultipliers[i] = mult;\n this.frequency.chain(mult, osc.frequency);\n this.detune.connect(osc.detune);\n }\n this._filterFreqScaler = new Scale({\n context: this.context,\n max: 7000,\n min: this.toFrequency(options.resonance),\n });\n this.envelope = new Envelope({\n attack: options.envelope.attack,\n attackCurve: "linear",\n context: this.context,\n decay: options.envelope.decay,\n release: options.envelope.release,\n sustain: 0,\n });\n this.envelope.chain(this._filterFreqScaler, this._highpass.frequency);\n this.envelope.connect(this._amplitude.gain);\n // set the octaves\n this._octaves = options.octaves;\n this.octaves = options.octaves;\n }\n static getDefaults() {\n return deepMerge(Monophonic.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.001,\n decay: 1.4,\n release: 0.2,\n }),\n harmonicity: 5.1,\n modulationIndex: 32,\n octaves: 1.5,\n resonance: 4000,\n });\n }\n /**\n * Trigger the attack.\n * @param time When the attack should be triggered.\n * @param velocity The velocity that the envelope should be triggered at.\n */\n _triggerEnvelopeAttack(time, velocity = 1) {\n this.envelope.triggerAttack(time, velocity);\n this._oscillators.forEach(osc => osc.start(time));\n if (this.envelope.sustain === 0) {\n this._oscillators.forEach(osc => {\n osc.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));\n });\n }\n return this;\n }\n /**\n * Trigger the release of the envelope.\n * @param time When the release should be triggered.\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this._oscillators.forEach(osc => osc.stop(time + this.toSeconds(this.envelope.release)));\n return this;\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n /**\n * The modulationIndex of the oscillators which make up the source.\n * see [[FMOscillator.modulationIndex]]\n * @min 1\n * @max 100\n */\n get modulationIndex() {\n return this._oscillators[0].modulationIndex.value;\n }\n set modulationIndex(val) {\n this._oscillators.forEach(osc => (osc.modulationIndex.value = val));\n }\n /**\n * The harmonicity of the oscillators which make up the source.\n * see Tone.FMOscillator.harmonicity\n * @min 0.1\n * @max 10\n */\n get harmonicity() {\n return this._oscillators[0].harmonicity.value;\n }\n set harmonicity(val) {\n this._oscillators.forEach(osc => (osc.harmonicity.value = val));\n }\n /**\n * The lower level of the highpass filter which is attached to the envelope.\n * This value should be between [0, 7000]\n * @min 0\n * @max 7000\n */\n get resonance() {\n return this._filterFreqScaler.min;\n }\n set resonance(val) {\n this._filterFreqScaler.min = this.toFrequency(val);\n this.octaves = this._octaves;\n }\n /**\n * The number of octaves above the "resonance" frequency\n * that the filter ramps during the attack/decay envelope\n * @min 0\n * @max 8\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(val) {\n this._octaves = val;\n this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, val);\n }\n dispose() {\n super.dispose();\n this._oscillators.forEach(osc => osc.dispose());\n this._freqMultipliers.forEach(freqMult => freqMult.dispose());\n this.frequency.dispose();\n this.detune.dispose();\n this._filterFreqScaler.dispose();\n this._amplitude.dispose();\n this.envelope.dispose();\n this._highpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MetalSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MembraneSynth.js\n\n\n\n\n\n\n\n/**\n * MembraneSynth makes kick and tom sounds using a single oscillator\n * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator\n * is routed through a Tone.AmplitudeEnvelope to the output. The drum\n * quality of the sound comes from the frequency envelope applied\n * during MembraneSynth.triggerAttack(note). The frequency envelope\n * starts at <code>note * .octaves</code> and ramps to <code>note</code>\n * over the duration of <code>.pitchDecay</code>.\n * @example\n * const synth = new Tone.MembraneSynth().toDestination();\n * synth.triggerAttackRelease("C2", "8n");\n * @category Instrument\n */\nclass MembraneSynth extends Synth_Synth {\n constructor() {\n super(Defaults_optionsFromArguments(MembraneSynth.getDefaults(), arguments));\n this.name = "MembraneSynth";\n /**\n * Portamento is ignored in this synth. use pitch decay instead.\n */\n this.portamento = 0;\n const options = Defaults_optionsFromArguments(MembraneSynth.getDefaults(), arguments);\n this.pitchDecay = options.pitchDecay;\n this.octaves = options.octaves;\n Interface_readOnly(this, ["oscillator", "envelope"]);\n }\n static getDefaults() {\n return Defaults_deepMerge(Monophonic_Monophonic.getDefaults(), Synth_Synth.getDefaults(), {\n envelope: {\n attack: 0.001,\n attackCurve: "exponential",\n decay: 0.4,\n release: 1.4,\n sustain: 0.01,\n },\n octaves: 10,\n oscillator: {\n type: "sine",\n },\n pitchDecay: 0.05,\n });\n }\n setNote(note, time) {\n const seconds = this.toSeconds(time);\n const hertz = this.toFrequency(note instanceof Frequency_FrequencyClass ? note.toFrequency() : note);\n const maxNote = hertz * this.octaves;\n this.oscillator.frequency.setValueAtTime(maxNote, seconds);\n this.oscillator.frequency.exponentialRampToValueAtTime(hertz, seconds + this.toSeconds(this.pitchDecay));\n return this;\n }\n dispose() {\n super.dispose();\n return this;\n }\n}\n__decorate([\n range(0)\n], MembraneSynth.prototype, "octaves", void 0);\n__decorate([\n timeRange(0)\n], MembraneSynth.prototype, "pitchDecay", void 0);\n//# sourceMappingURL=MembraneSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/NoiseSynth.js\n\n\n\n\n\n\n\n/**\n * Tone.NoiseSynth is composed of [[Noise]] through an [[AmplitudeEnvelope]].\n * ```\n * +-------+ +-------------------+\n * | Noise +>--\x3e AmplitudeEnvelope +>--\x3e Output\n * +-------+ +-------------------+\n * ```\n * @example\n * const noiseSynth = new Tone.NoiseSynth().toDestination();\n * noiseSynth.triggerAttackRelease("8n", 0.05);\n * @category Instrument\n */\nclass NoiseSynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(NoiseSynth.getDefaults(), arguments));\n this.name = "NoiseSynth";\n const options = optionsFromArguments(NoiseSynth.getDefaults(), arguments);\n this.noise = new Noise(Object.assign({\n context: this.context,\n }, options.noise));\n this.envelope = new AmplitudeEnvelope(Object.assign({\n context: this.context,\n }, options.envelope));\n // connect the noise to the output\n this.noise.chain(this.envelope, this.output);\n }\n static getDefaults() {\n return Object.assign(Instrument.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n decay: 0.1,\n sustain: 0.0,\n }),\n noise: Object.assign(omitFromObject(Noise.getDefaults(), Object.keys(Source.getDefaults())), {\n type: "white",\n }),\n });\n }\n /**\n * Start the attack portion of the envelopes. Unlike other\n * instruments, Tone.NoiseSynth doesn\'t have a note.\n * @example\n * const noiseSynth = new Tone.NoiseSynth().toDestination();\n * noiseSynth.triggerAttack();\n */\n triggerAttack(time, velocity = 1) {\n time = this.toSeconds(time);\n // the envelopes\n this.envelope.triggerAttack(time, velocity);\n // start the noise\n this.noise.start(time);\n if (this.envelope.sustain === 0) {\n this.noise.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));\n }\n return this;\n }\n /**\n * Start the release portion of the envelopes.\n */\n triggerRelease(time) {\n time = this.toSeconds(time);\n this.envelope.triggerRelease(time);\n this.noise.stop(time + this.toSeconds(this.envelope.release));\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 0);\n this._syncMethod("triggerRelease", 0);\n }\n return this;\n }\n triggerAttackRelease(duration, time, velocity = 1) {\n time = this.toSeconds(time);\n duration = this.toSeconds(duration);\n this.triggerAttack(time, velocity);\n this.triggerRelease(time + duration);\n return this;\n }\n dispose() {\n super.dispose();\n this.noise.dispose();\n this.envelope.dispose();\n return this;\n }\n}\n//# sourceMappingURL=NoiseSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/WorkletGlobalScope.js\n/**\n * All of the classes or functions which are loaded into the AudioWorkletGlobalScope\n */\nconst workletContext = new Set();\n/**\n * Add a class to the AudioWorkletGlobalScope\n */\nfunction addToWorklet(classOrFunction) {\n workletContext.add(classOrFunction);\n}\n/**\n * Register a processor in the AudioWorkletGlobalScope with the given name\n */\nfunction registerProcessor(name, classDesc) {\n const processor = /* javascript */ `registerProcessor("${name}", ${classDesc})`;\n workletContext.add(processor);\n}\n/**\n * Get all of the modules which have been registered to the AudioWorkletGlobalScope\n */\nfunction WorkletGlobalScope_getWorkletGlobalScope() {\n return Array.from(workletContext).join("\\n");\n}\n//# sourceMappingURL=WorkletGlobalScope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/ToneAudioWorklet.js\n\n\n\nclass ToneAudioWorklet_ToneAudioWorklet extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "ToneAudioWorklet";\n /**\n * The constructor options for the node\n */\n this.workletOptions = {};\n /**\n * Callback which is invoked when there is an error in the processing\n */\n this.onprocessorerror = noOp;\n const blobUrl = URL.createObjectURL(new Blob([getWorkletGlobalScope()], { type: "text/javascript" }));\n const name = this._audioWorkletName();\n this._dummyGain = this.context.createGain();\n this._dummyParam = this._dummyGain.gain;\n // Register the processor\n this.context.addAudioWorkletModule(blobUrl, name).then(() => {\n // create the worklet when it\'s read\n if (!this.disposed) {\n this._worklet = this.context.createAudioWorkletNode(name, this.workletOptions);\n this._worklet.onprocessorerror = this.onprocessorerror.bind(this);\n this.onReady(this._worklet);\n }\n });\n }\n dispose() {\n super.dispose();\n this._dummyGain.disconnect();\n if (this._worklet) {\n this._worklet.port.postMessage("dispose");\n this._worklet.disconnect();\n }\n return this;\n }\n}\n//# sourceMappingURL=ToneAudioWorklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/ToneAudioWorkletProcessor.worklet.js\n\nconst toneAudioWorkletProcessor = /* javascript */ `\n\t/**\n\t * The base AudioWorkletProcessor for use in Tone.js. Works with the [[ToneAudioWorklet]]. \n\t */\n\tclass ToneAudioWorkletProcessor extends AudioWorkletProcessor {\n\n\t\tconstructor(options) {\n\t\t\t\n\t\t\tsuper(options);\n\t\t\t/**\n\t\t\t * If the processor was disposed or not. Keep alive until it\'s disposed.\n\t\t\t */\n\t\t\tthis.disposed = false;\n\t\t \t/** \n\t\t\t * The number of samples in the processing block\n\t\t\t */\n\t\t\tthis.blockSize = 128;\n\t\t\t/**\n\t\t\t * the sample rate\n\t\t\t */\n\t\t\tthis.sampleRate = sampleRate;\n\n\t\t\tthis.port.onmessage = (event) => {\n\t\t\t\t// when it receives a dispose \n\t\t\t\tif (event.data === "dispose") {\n\t\t\t\t\tthis.disposed = true;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n`;\naddToWorklet(toneAudioWorkletProcessor);\n//# sourceMappingURL=ToneAudioWorkletProcessor.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/SingleIOProcessor.worklet.js\n\n\nconst singleIOProcess = /* javascript */ `\n\t/**\n\t * Abstract class for a single input/output processor. \n\t * has a \'generate\' function which processes one sample at a time\n\t */\n\tclass SingleIOProcessor extends ToneAudioWorkletProcessor {\n\n\t\tconstructor(options) {\n\t\t\tsuper(Object.assign(options, {\n\t\t\t\tnumberOfInputs: 1,\n\t\t\t\tnumberOfOutputs: 1\n\t\t\t}));\n\t\t\t/**\n\t\t\t * Holds the name of the parameter and a single value of that\n\t\t\t * parameter at the current sample\n\t\t\t * @type { [name: string]: number }\n\t\t\t */\n\t\t\tthis.params = {}\n\t\t}\n\n\t\t/**\n\t\t * Generate an output sample from the input sample and parameters\n\t\t * @abstract\n\t\t * @param input number\n\t\t * @param channel number\n\t\t * @param parameters { [name: string]: number }\n\t\t * @returns number\n\t\t */\n\t\tgenerate(){}\n\n\t\t/**\n\t\t * Update the private params object with the \n\t\t * values of the parameters at the given index\n\t\t * @param parameters { [name: string]: Float32Array },\n\t\t * @param index number\n\t\t */\n\t\tupdateParams(parameters, index) {\n\t\t\tfor (const paramName in parameters) {\n\t\t\t\tconst param = parameters[paramName];\n\t\t\t\tif (param.length > 1) {\n\t\t\t\t\tthis.params[paramName] = parameters[paramName][index];\n\t\t\t\t} else {\n\t\t\t\t\tthis.params[paramName] = parameters[paramName][0];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Process a single frame of the audio\n\t\t * @param inputs Float32Array[][]\n\t\t * @param outputs Float32Array[][]\n\t\t */\n\t\tprocess(inputs, outputs, parameters) {\n\t\t\tconst input = inputs[0];\n\t\t\tconst output = outputs[0];\n\t\t\t// get the parameter values\n\t\t\tconst channelCount = Math.max(input && input.length || 0, output.length);\n\t\t\tfor (let sample = 0; sample < this.blockSize; sample++) {\n\t\t\t\tthis.updateParams(parameters, sample);\n\t\t\t\tfor (let channel = 0; channel < channelCount; channel++) {\n\t\t\t\t\tconst inputSample = input && input.length ? input[channel][sample] : 0;\n\t\t\t\t\toutput[channel][sample] = this.generate(inputSample, channel, this.params);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn !this.disposed;\n\t\t}\n\t};\n`;\naddToWorklet(singleIOProcess);\n//# sourceMappingURL=SingleIOProcessor.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/DelayLine.worklet.js\n\nconst delayLine = /* javascript */ `\n\t/**\n\t * A multichannel buffer for use within an AudioWorkletProcessor as a delay line\n\t */\n\tclass DelayLine {\n\t\t\n\t\tconstructor(size, channels) {\n\t\t\tthis.buffer = [];\n\t\t\tthis.writeHead = []\n\t\t\tthis.size = size;\n\n\t\t\t// create the empty channels\n\t\t\tfor (let i = 0; i < channels; i++) {\n\t\t\t\tthis.buffer[i] = new Float32Array(this.size);\n\t\t\t\tthis.writeHead[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Push a value onto the end\n\t\t * @param channel number\n\t\t * @param value number\n\t\t */\n\t\tpush(channel, value) {\n\t\t\tthis.writeHead[channel] += 1;\n\t\t\tif (this.writeHead[channel] > this.size) {\n\t\t\t\tthis.writeHead[channel] = 0;\n\t\t\t}\n\t\t\tthis.buffer[channel][this.writeHead[channel]] = value;\n\t\t}\n\n\t\t/**\n\t\t * Get the recorded value of the channel given the delay\n\t\t * @param channel number\n\t\t * @param delay number delay samples\n\t\t */\n\t\tget(channel, delay) {\n\t\t\tlet readHead = this.writeHead[channel] - Math.floor(delay);\n\t\t\tif (readHead < 0) {\n\t\t\t\treadHead += this.size;\n\t\t\t}\n\t\t\treturn this.buffer[channel][readHead];\n\t\t}\n\t}\n`;\naddToWorklet(delayLine);\n//# sourceMappingURL=DelayLine.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/FeedbackCombFilter.worklet.js\n\n\n\nconst FeedbackCombFilter_worklet_workletName = "feedback-comb-filter";\nconst feedbackCombFilter = /* javascript */ `\n\tclass FeedbackCombFilterWorklet extends SingleIOProcessor {\n\n\t\tconstructor(options) {\n\t\t\tsuper(options);\n\t\t\tthis.delayLine = new DelayLine(this.sampleRate, options.channelCount || 2);\n\t\t}\n\n\t\tstatic get parameterDescriptors() {\n\t\t\treturn [{\n\t\t\t\tname: "delayTime",\n\t\t\t\tdefaultValue: 0.1,\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 1,\n\t\t\t\tautomationRate: "k-rate"\n\t\t\t}, {\n\t\t\t\tname: "feedback",\n\t\t\t\tdefaultValue: 0.5,\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 0.9999,\n\t\t\t\tautomationRate: "k-rate"\n\t\t\t}];\n\t\t}\n\n\t\tgenerate(input, channel, parameters) {\n\t\t\tconst delayedSample = this.delayLine.get(channel, parameters.delayTime * this.sampleRate);\n\t\t\tthis.delayLine.push(channel, input + delayedSample * parameters.feedback);\n\t\t\treturn delayedSample;\n\t\t}\n\t}\n`;\nregisterProcessor(FeedbackCombFilter_worklet_workletName, feedbackCombFilter);\n//# sourceMappingURL=FeedbackCombFilter.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/FeedbackCombFilter.js\n\n\n\n\n\n\n\n/**\n * Comb filters are basic building blocks for physical modeling. Read more\n * about comb filters on [CCRMA\'s website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html).\n *\n * This comb filter is implemented with the AudioWorkletNode which allows it to have feedback delays less than the\n * Web Audio processing block of 128 samples. There is a polyfill for browsers that don\'t yet support the\n * AudioWorkletNode, but it will add some latency and have slower performance than the AudioWorkletNode.\n * @category Component\n */\nclass FeedbackCombFilter_FeedbackCombFilter extends (/* unused pure expression or super */ null && (ToneAudioWorklet)) {\n constructor() {\n super(optionsFromArguments(FeedbackCombFilter_FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]));\n this.name = "FeedbackCombFilter";\n const options = optionsFromArguments(FeedbackCombFilter_FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]);\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this.delayTime = new Param({\n context: this.context,\n value: options.delayTime,\n units: "time",\n minValue: 0,\n maxValue: 1,\n param: this._dummyParam,\n swappable: true,\n });\n this.resonance = new Param({\n context: this.context,\n value: options.resonance,\n units: "normalRange",\n param: this._dummyParam,\n swappable: true,\n });\n readOnly(this, ["resonance", "delayTime"]);\n }\n _audioWorkletName() {\n return workletName;\n }\n /**\n * The default parameters\n */\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n delayTime: 0.1,\n resonance: 0.5,\n });\n }\n onReady(node) {\n connectSeries(this.input, node, this.output);\n const delayTime = node.parameters.get("delayTime");\n ;\n this.delayTime.setParam(delayTime);\n const feedback = node.parameters.get("feedback");\n ;\n this.resonance.setParam(feedback);\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.delayTime.dispose();\n this.resonance.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackCombFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/OnePoleFilter.js\n\n\n\n/**\n * A one pole filter with 6db-per-octave rolloff. Either "highpass" or "lowpass".\n * Note that changing the type or frequency may result in a discontinuity which\n * can sound like a click or pop.\n * References:\n * * http://www.earlevel.com/main/2012/12/15/a-one-pole-filter/\n * * http://www.dspguide.com/ch19/2.htm\n * * https://github.com/vitaliy-bobrov/js-rocks/blob/master/src/app/audio/effects/one-pole-filters.ts\n * @category Component\n */\nclass OnePoleFilter_OnePoleFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(OnePoleFilter_OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "OnePoleFilter";\n const options = optionsFromArguments(OnePoleFilter_OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]);\n this._frequency = options.frequency;\n this._type = options.type;\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this._createFilter();\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n frequency: 880,\n type: "lowpass"\n });\n }\n /**\n * Create a filter and dispose the old one\n */\n _createFilter() {\n const oldFilter = this._filter;\n const freq = this.toFrequency(this._frequency);\n const t = 1 / (2 * Math.PI * freq);\n if (this._type === "lowpass") {\n const a0 = 1 / (t * this.context.sampleRate);\n const b1 = a0 - 1;\n this._filter = this.context.createIIRFilter([a0, 0], [1, b1]);\n }\n else {\n const b1 = 1 / (t * this.context.sampleRate) - 1;\n this._filter = this.context.createIIRFilter([1, -1], [1, b1]);\n }\n this.input.chain(this._filter, this.output);\n if (oldFilter) {\n // dispose it on the next block\n this.context.setTimeout(() => {\n if (!this.disposed) {\n this.input.disconnect(oldFilter);\n oldFilter.disconnect();\n }\n }, this.blockTime);\n }\n }\n /**\n * The frequency value.\n */\n get frequency() {\n return this._frequency;\n }\n set frequency(fq) {\n this._frequency = fq;\n this._createFilter();\n }\n /**\n * The OnePole Filter type, either "highpass" or "lowpass"\n */\n get type() {\n return this._type;\n }\n set type(t) {\n this._type = t;\n this._createFilter();\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n const freqValues = new Float32Array(len);\n for (let i = 0; i < len; i++) {\n const norm = Math.pow(i / len, 2);\n const freq = norm * (20000 - 20) + 20;\n freqValues[i] = freq;\n }\n const magValues = new Float32Array(len);\n const phaseValues = new Float32Array(len);\n this._filter.getFrequencyResponse(freqValues, magValues, phaseValues);\n return magValues;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this._filter.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=OnePoleFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/LowpassCombFilter.js\n\n\n\n\n/**\n * A lowpass feedback comb filter. It is similar to\n * [[FeedbackCombFilter]], but includes a lowpass filter.\n * @category Component\n */\nclass LowpassCombFilter_LowpassCombFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(LowpassCombFilter_LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]));\n this.name = "LowpassCombFilter";\n const options = optionsFromArguments(LowpassCombFilter_LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]);\n this._combFilter = this.output = new FeedbackCombFilter({\n context: this.context,\n delayTime: options.delayTime,\n resonance: options.resonance,\n });\n this.delayTime = this._combFilter.delayTime;\n this.resonance = this._combFilter.resonance;\n this._lowpass = this.input = new OnePoleFilter({\n context: this.context,\n frequency: options.dampening,\n type: "lowpass",\n });\n // connections\n this._lowpass.connect(this._combFilter);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n dampening: 3000,\n delayTime: 0.1,\n resonance: 0.5,\n });\n }\n /**\n * The dampening control of the feedback\n */\n get dampening() {\n return this._lowpass.frequency;\n }\n set dampening(fq) {\n this._lowpass.frequency = fq;\n }\n dispose() {\n super.dispose();\n this._combFilter.dispose();\n this._lowpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LowpassCombFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/PluckSynth.js\n\n\n\n\n\n/**\n * Karplus-String string synthesis.\n * @example\n * const plucky = new Tone.PluckSynth().toDestination();\n * plucky.triggerAttack("C4", "+0.5");\n * plucky.triggerAttack("C3", "+1");\n * plucky.triggerAttack("C2", "+1.5");\n * plucky.triggerAttack("C1", "+2");\n * @category Instrument\n */\nclass PluckSynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(PluckSynth.getDefaults(), arguments));\n this.name = "PluckSynth";\n const options = optionsFromArguments(PluckSynth.getDefaults(), arguments);\n this._noise = new Noise({\n context: this.context,\n type: "pink"\n });\n this.attackNoise = options.attackNoise;\n this._lfcf = new LowpassCombFilter({\n context: this.context,\n dampening: options.dampening,\n resonance: options.resonance,\n });\n this.resonance = options.resonance;\n this.release = options.release;\n this._noise.connect(this._lfcf);\n this._lfcf.connect(this.output);\n }\n static getDefaults() {\n return deepMerge(Instrument.getDefaults(), {\n attackNoise: 1,\n dampening: 4000,\n resonance: 0.7,\n release: 1,\n });\n }\n /**\n * The dampening control. i.e. the lowpass filter frequency of the comb filter\n * @min 0\n * @max 7000\n */\n get dampening() {\n return this._lfcf.dampening;\n }\n set dampening(fq) {\n this._lfcf.dampening = fq;\n }\n triggerAttack(note, time) {\n const freq = this.toFrequency(note);\n time = this.toSeconds(time);\n const delayAmount = 1 / freq;\n this._lfcf.delayTime.setValueAtTime(delayAmount, time);\n this._noise.start(time);\n this._noise.stop(time + delayAmount * this.attackNoise);\n this._lfcf.resonance.cancelScheduledValues(time);\n this._lfcf.resonance.setValueAtTime(this.resonance, time);\n return this;\n }\n /**\n * Ramp down the [[resonance]] to 0 over the duration of the release time.\n */\n triggerRelease(time) {\n this._lfcf.resonance.linearRampTo(0, this.release, time);\n return this;\n }\n dispose() {\n super.dispose();\n this._noise.dispose();\n this._lfcf.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PluckSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/PolySynth.js\n\n\n\n\n\n\n/**\n * PolySynth handles voice creation and allocation for any\n * instruments passed in as the second paramter. PolySynth is\n * not a synthesizer by itself, it merely manages voices of\n * one of the other types of synths, allowing any of the\n * monophonic synthesizers to be polyphonic.\n *\n * @example\n * const synth = new Tone.PolySynth().toDestination();\n * // set the attributes across all the voices using \'set\'\n * synth.set({ detune: -1200 });\n * // play a chord\n * synth.triggerAttackRelease(["C4", "E4", "A4"], 1);\n * @category Instrument\n */\nclass PolySynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]));\n this.name = "PolySynth";\n /**\n * The voices which are not currently in use\n */\n this._availableVoices = [];\n /**\n * The currently active voices\n */\n this._activeVoices = [];\n /**\n * All of the allocated voices for this synth.\n */\n this._voices = [];\n /**\n * The GC timeout. Held so that it could be cancelled when the node is disposed.\n */\n this._gcTimeout = -1;\n /**\n * A moving average of the number of active voices\n */\n this._averageActiveVoices = 0;\n const options = optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]);\n // check against the old API (pre 14.3.0)\n assert(!isNumber(options.voice), "DEPRECATED: The polyphony count is no longer the first argument.");\n const defaults = options.voice.getDefaults();\n this.options = Object.assign(defaults, options.options);\n this.voice = options.voice;\n this.maxPolyphony = options.maxPolyphony;\n // create the first voice\n this._dummyVoice = this._getNextAvailableVoice();\n // remove it from the voices list\n const index = this._voices.indexOf(this._dummyVoice);\n this._voices.splice(index, 1);\n // kick off the GC interval\n this._gcTimeout = this.context.setInterval(this._collectGarbage.bind(this), 1);\n }\n static getDefaults() {\n return Object.assign(Instrument.getDefaults(), {\n maxPolyphony: 32,\n options: {},\n voice: Synth,\n });\n }\n /**\n * The number of active voices.\n */\n get activeVoices() {\n return this._activeVoices.length;\n }\n /**\n * Invoked when the source is done making sound, so that it can be\n * readded to the pool of available voices\n */\n _makeVoiceAvailable(voice) {\n this._availableVoices.push(voice);\n // remove the midi note from \'active voices\'\n const activeVoiceIndex = this._activeVoices.findIndex((e) => e.voice === voice);\n this._activeVoices.splice(activeVoiceIndex, 1);\n }\n /**\n * Get an available voice from the pool of available voices.\n * If one is not available and the maxPolyphony limit is reached,\n * steal a voice, otherwise return null.\n */\n _getNextAvailableVoice() {\n // if there are available voices, return the first one\n if (this._availableVoices.length) {\n return this._availableVoices.shift();\n }\n else if (this._voices.length < this.maxPolyphony) {\n // otherwise if there is still more maxPolyphony, make a new voice\n const voice = new this.voice(Object.assign(this.options, {\n context: this.context,\n onsilence: this._makeVoiceAvailable.bind(this),\n }));\n voice.connect(this.output);\n this._voices.push(voice);\n return voice;\n }\n else {\n warn("Max polyphony exceeded. Note dropped.");\n }\n }\n /**\n * Occasionally check if there are any allocated voices which can be cleaned up.\n */\n _collectGarbage() {\n this._averageActiveVoices = Math.max(this._averageActiveVoices * 0.95, this.activeVoices);\n if (this._availableVoices.length && this._voices.length > Math.ceil(this._averageActiveVoices + 1)) {\n // take off an available note\n const firstAvail = this._availableVoices.shift();\n const index = this._voices.indexOf(firstAvail);\n this._voices.splice(index, 1);\n if (!this.context.isOffline) {\n firstAvail.dispose();\n }\n }\n }\n /**\n * Internal method which triggers the attack\n */\n _triggerAttack(notes, time, velocity) {\n notes.forEach(note => {\n const midiNote = new MidiClass(this.context, note).toMidi();\n const voice = this._getNextAvailableVoice();\n if (voice) {\n voice.triggerAttack(note, time, velocity);\n this._activeVoices.push({\n midi: midiNote, voice, released: false,\n });\n this.log("triggerAttack", note, time);\n }\n });\n }\n /**\n * Internal method which triggers the release\n */\n _triggerRelease(notes, time) {\n notes.forEach(note => {\n const midiNote = new MidiClass(this.context, note).toMidi();\n const event = this._activeVoices.find(({ midi, released }) => midi === midiNote && !released);\n if (event) {\n // trigger release on that note\n event.voice.triggerRelease(time);\n // mark it as released\n event.released = true;\n this.log("triggerRelease", note, time);\n }\n });\n }\n /**\n * Schedule the attack/release events. If the time is in the future, then it should set a timeout\n * to wait for just-in-time scheduling\n */\n _scheduleEvent(type, notes, time, velocity) {\n assert(!this.disposed, "Synth was already disposed");\n // if the notes are greater than this amount of time in the future, they should be scheduled with setTimeout\n if (time <= this.now()) {\n // do it immediately\n if (type === "attack") {\n this._triggerAttack(notes, time, velocity);\n }\n else {\n this._triggerRelease(notes, time);\n }\n }\n else {\n // schedule it to start in the future\n this.context.setTimeout(() => {\n this._scheduleEvent(type, notes, time, velocity);\n }, time - this.now());\n }\n }\n /**\n * Trigger the attack portion of the note\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param time The start time of the note.\n * @param velocity The velocity of the note.\n * @example\n * const synth = new Tone.PolySynth(Tone.FMSynth).toDestination();\n * // trigger a chord immediately with a velocity of 0.2\n * synth.triggerAttack(["Ab3", "C4", "F5"], Tone.now(), 0.2);\n */\n triggerAttack(notes, time, velocity) {\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n const computedTime = this.toSeconds(time);\n this._scheduleEvent("attack", notes, computedTime, velocity);\n return this;\n }\n /**\n * Trigger the release of the note. Unlike monophonic instruments,\n * a note (or array of notes) needs to be passed in as the first argument.\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param time When the release will be triggered.\n * @example\n * @example\n * const poly = new Tone.PolySynth(Tone.AMSynth).toDestination();\n * poly.triggerAttack(["Ab3", "C4", "F5"]);\n * // trigger the release of the given notes.\n * poly.triggerRelease(["Ab3", "C4"], "+1");\n * poly.triggerRelease("F5", "+3");\n */\n triggerRelease(notes, time) {\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n const computedTime = this.toSeconds(time);\n this._scheduleEvent("release", notes, computedTime);\n return this;\n }\n /**\n * Trigger the attack and release after the specified duration\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param duration the duration of the note\n * @param time if no time is given, defaults to now\n * @param velocity the velocity of the attack (0-1)\n * @example\n * const poly = new Tone.PolySynth(Tone.AMSynth).toDestination();\n * // can pass in an array of durations as well\n * poly.triggerAttackRelease(["Eb3", "G4", "Bb4", "D5"], [4, 3, 2, 1]);\n */\n triggerAttackRelease(notes, duration, time, velocity) {\n const computedTime = this.toSeconds(time);\n this.triggerAttack(notes, computedTime, velocity);\n if (isArray(duration)) {\n assert(isArray(notes), "If the duration is an array, the notes must also be an array");\n notes = notes;\n for (let i = 0; i < notes.length; i++) {\n const d = duration[Math.min(i, duration.length - 1)];\n const durationSeconds = this.toSeconds(d);\n assert(durationSeconds > 0, "The duration must be greater than 0");\n this.triggerRelease(notes[i], computedTime + durationSeconds);\n }\n }\n else {\n const durationSeconds = this.toSeconds(duration);\n assert(durationSeconds > 0, "The duration must be greater than 0");\n this.triggerRelease(notes, computedTime + durationSeconds);\n }\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 1);\n }\n return this;\n }\n /**\n * Set a member/attribute of the voices\n * @example\n * const poly = new Tone.PolySynth().toDestination();\n * // set all of the voices using an options object for the synth type\n * poly.set({\n * \tenvelope: {\n * \t\tattack: 0.25\n * \t}\n * });\n * poly.triggerAttackRelease("Bb3", 0.2);\n */\n set(options) {\n // remove options which are controlled by the PolySynth\n const sanitizedOptions = omitFromObject(options, ["onsilence", "context"]);\n // store all of the options\n this.options = deepMerge(this.options, sanitizedOptions);\n this._voices.forEach(voice => voice.set(sanitizedOptions));\n this._dummyVoice.set(sanitizedOptions);\n return this;\n }\n get() {\n return this._dummyVoice.get();\n }\n /**\n * Trigger the release portion of all the currently active voices immediately.\n * Useful for silencing the synth.\n */\n releaseAll(time) {\n const computedTime = this.toSeconds(time);\n this._activeVoices.forEach(({ voice }) => {\n voice.triggerRelease(computedTime);\n });\n return this;\n }\n dispose() {\n super.dispose();\n this._dummyVoice.dispose();\n this._voices.forEach(v => v.dispose());\n this._activeVoices = [];\n this._availableVoices = [];\n this.context.clearInterval(this._gcTimeout);\n return this;\n }\n}\n//# sourceMappingURL=PolySynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Sampler.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Pass in an object which maps the note\'s pitch or midi value to the url,\n * then you can trigger the attack and release of that note like other instruments.\n * By automatically repitching the samples, it is possible to play pitches which\n * were not explicitly included which can save loading time.\n *\n * For sample or buffer playback where repitching is not necessary,\n * use [[Player]].\n * @example\n * const sampler = new Tone.Sampler({\n * \turls: {\n * \t\tA1: "A1.mp3",\n * \t\tA2: "A2.mp3",\n * \t},\n * \tbaseUrl: "https://tonejs.github.io/audio/casio/",\n * \tonload: () => {\n * \t\tsampler.triggerAttackRelease(["C1", "E1", "G1", "B1"], 0.5);\n * \t}\n * }).toDestination();\n * @category Instrument\n */\nclass Sampler extends Instrument_Instrument {\n constructor() {\n super(Defaults_optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls"));\n this.name = "Sampler";\n /**\n * The object of all currently playing BufferSources\n */\n this._activeSources = new Map();\n const options = Defaults_optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls");\n const urlMap = {};\n Object.keys(options.urls).forEach((note) => {\n const noteNumber = parseInt(note, 10);\n Debug_assert(isNote(note)\n || (TypeCheck_isNumber(noteNumber) && isFinite(noteNumber)), `url key is neither a note or midi pitch: ${note}`);\n if (isNote(note)) {\n // convert the note name to MIDI\n const mid = new Frequency_FrequencyClass(this.context, note).toMidi();\n urlMap[mid] = options.urls[note];\n }\n else if (TypeCheck_isNumber(noteNumber) && isFinite(noteNumber)) {\n // otherwise if it\'s numbers assume it\'s midi\n urlMap[noteNumber] = options.urls[noteNumber];\n }\n });\n this._buffers = new ToneAudioBuffers_ToneAudioBuffers({\n urls: urlMap,\n onload: options.onload,\n baseUrl: options.baseUrl,\n onerror: options.onerror,\n });\n this.attack = options.attack;\n this.release = options.release;\n this.curve = options.curve;\n // invoke the callback if it\'s already loaded\n if (this._buffers.loaded) {\n // invoke onload deferred\n Promise.resolve().then(options.onload);\n }\n }\n static getDefaults() {\n return Object.assign(Instrument_Instrument.getDefaults(), {\n attack: 0,\n baseUrl: "",\n curve: "exponential",\n onload: Interface_noOp,\n onerror: Interface_noOp,\n release: 0.1,\n urls: {},\n });\n }\n /**\n * Returns the difference in steps between the given midi note at the closets sample.\n */\n _findClosest(midi) {\n // searches within 8 octaves of the given midi note\n const MAX_INTERVAL = 96;\n let interval = 0;\n while (interval < MAX_INTERVAL) {\n // check above and below\n if (this._buffers.has(midi + interval)) {\n return -interval;\n }\n else if (this._buffers.has(midi - interval)) {\n return interval;\n }\n interval++;\n }\n throw new Error(`No available buffers for note: ${midi}`);\n }\n /**\n * @param notes\tThe note to play, or an array of notes.\n * @param time When to play the note\n * @param velocity The velocity to play the sample back.\n */\n triggerAttack(notes, time, velocity = 1) {\n this.log("triggerAttack", notes, time, velocity);\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n notes.forEach(note => {\n const midiFloat = ftomf(new Frequency_FrequencyClass(this.context, note).toFrequency());\n const midi = Math.round(midiFloat);\n const remainder = midiFloat - midi;\n // find the closest note pitch\n const difference = this._findClosest(midi);\n const closestNote = midi - difference;\n const buffer = this._buffers.get(closestNote);\n const playbackRate = Conversions_intervalToFrequencyRatio(difference + remainder);\n // play that note\n const source = new ToneBufferSource_ToneBufferSource({\n url: buffer,\n context: this.context,\n curve: this.curve,\n fadeIn: this.attack,\n fadeOut: this.release,\n playbackRate,\n }).connect(this.output);\n source.start(time, 0, buffer.duration / playbackRate, velocity);\n // add it to the active sources\n if (!TypeCheck_isArray(this._activeSources.get(midi))) {\n this._activeSources.set(midi, []);\n }\n this._activeSources.get(midi).push(source);\n // remove it when it\'s done\n source.onended = () => {\n if (this._activeSources && this._activeSources.has(midi)) {\n const sources = this._activeSources.get(midi);\n const index = sources.indexOf(source);\n if (index !== -1) {\n sources.splice(index, 1);\n }\n }\n };\n });\n return this;\n }\n /**\n * @param notes\tThe note to release, or an array of notes.\n * @param time \tWhen to release the note.\n */\n triggerRelease(notes, time) {\n this.log("triggerRelease", notes, time);\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n notes.forEach(note => {\n const midi = new Frequency_FrequencyClass(this.context, note).toMidi();\n // find the note\n if (this._activeSources.has(midi) && this._activeSources.get(midi).length) {\n const sources = this._activeSources.get(midi);\n time = this.toSeconds(time);\n sources.forEach(source => {\n source.stop(time);\n });\n this._activeSources.set(midi, []);\n }\n });\n return this;\n }\n /**\n * Release all currently active notes.\n * @param time \tWhen to release the notes.\n */\n releaseAll(time) {\n const computedTime = this.toSeconds(time);\n this._activeSources.forEach(sources => {\n while (sources.length) {\n const source = sources.shift();\n source.stop(computedTime);\n }\n });\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 1);\n }\n return this;\n }\n /**\n * Invoke the attack phase, then after the duration, invoke the release.\n * @param notes\tThe note to play and release, or an array of notes.\n * @param duration The time the note should be held\n * @param time When to start the attack\n * @param velocity The velocity of the attack\n */\n triggerAttackRelease(notes, duration, time, velocity = 1) {\n const computedTime = this.toSeconds(time);\n this.triggerAttack(notes, computedTime, velocity);\n if (TypeCheck_isArray(duration)) {\n Debug_assert(TypeCheck_isArray(notes), "notes must be an array when duration is array");\n notes.forEach((note, index) => {\n const d = duration[Math.min(index, duration.length - 1)];\n this.triggerRelease(note, computedTime + this.toSeconds(d));\n });\n }\n else {\n this.triggerRelease(notes, computedTime + this.toSeconds(duration));\n }\n return this;\n }\n /**\n * Add a note to the sampler.\n * @param note The buffer\'s pitch.\n * @param url Either the url of the buffer, or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n */\n add(note, url, callback) {\n Debug_assert(isNote(note) || isFinite(note), `note must be a pitch or midi: ${note}`);\n if (isNote(note)) {\n // convert the note name to MIDI\n const mid = new Frequency_FrequencyClass(this.context, note).toMidi();\n this._buffers.add(mid, url, callback);\n }\n else {\n // otherwise if it\'s numbers assume it\'s midi\n this._buffers.add(note, url, callback);\n }\n return this;\n }\n /**\n * If the buffers are loaded or not\n */\n get loaded() {\n return this._buffers.loaded;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._buffers.dispose();\n this._activeSources.forEach(sources => {\n sources.forEach(source => source.dispose());\n });\n this._activeSources.clear();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Sampler.prototype, "attack", void 0);\n__decorate([\n timeRange(0)\n], Sampler.prototype, "release", void 0);\n//# sourceMappingURL=Sampler.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/index.js\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/ToneEvent.js\n\n\n\n\n\n\n\n/**\n * ToneEvent abstracts away this.context.transport.schedule and provides a schedulable\n * callback for a single or repeatable events along the timeline.\n *\n * @example\n * const synth = new Tone.PolySynth().toDestination();\n * const chordEvent = new Tone.ToneEvent(((time, chord) => {\n * \t// the chord as well as the exact time of the event\n * \t// are passed in as arguments to the callback function\n * \tsynth.triggerAttackRelease(chord, 0.5, time);\n * }), ["D4", "E4", "F4"]);\n * // start the chord at the beginning of the transport timeline\n * chordEvent.start();\n * // loop it every measure for 8 measures\n * chordEvent.loop = 8;\n * chordEvent.loopEnd = "1m";\n * @category Event\n */\nclass ToneEvent_ToneEvent extends (/* unused pure expression or super */ null && (ToneWithContext)) {\n constructor() {\n super(optionsFromArguments(ToneEvent_ToneEvent.getDefaults(), arguments, ["callback", "value"]));\n this.name = "ToneEvent";\n /**\n * Tracks the scheduled events\n */\n this._state = new StateTimeline("stopped");\n /**\n * A delay time from when the event is scheduled to start\n */\n this._startOffset = 0;\n const options = optionsFromArguments(ToneEvent_ToneEvent.getDefaults(), arguments, ["callback", "value"]);\n this._loop = options.loop;\n this.callback = options.callback;\n this.value = options.value;\n this._loopStart = this.toTicks(options.loopStart);\n this._loopEnd = this.toTicks(options.loopEnd);\n this._playbackRate = options.playbackRate;\n this._probability = options.probability;\n this._humanize = options.humanize;\n this.mute = options.mute;\n this._playbackRate = options.playbackRate;\n this._state.increasing = true;\n // schedule the events for the first time\n this._rescheduleEvents();\n }\n static getDefaults() {\n return Object.assign(ToneWithContext.getDefaults(), {\n callback: noOp,\n humanize: false,\n loop: false,\n loopEnd: "1m",\n loopStart: 0,\n mute: false,\n playbackRate: 1,\n probability: 1,\n value: null,\n });\n }\n /**\n * Reschedule all of the events along the timeline\n * with the updated values.\n * @param after Only reschedules events after the given time.\n */\n _rescheduleEvents(after = -1) {\n // if no argument is given, schedules all of the events\n this._state.forEachFrom(after, event => {\n let duration;\n if (event.state === "started") {\n if (event.id !== -1) {\n this.context.transport.clear(event.id);\n }\n const startTick = event.time + Math.round(this.startOffset / this._playbackRate);\n if (this._loop === true || isNumber(this._loop) && this._loop > 1) {\n duration = Infinity;\n if (isNumber(this._loop)) {\n duration = (this._loop) * this._getLoopDuration();\n }\n const nextEvent = this._state.getAfter(startTick);\n if (nextEvent !== null) {\n duration = Math.min(duration, nextEvent.time - startTick);\n }\n if (duration !== Infinity) {\n // schedule a stop since it\'s finite duration\n this._state.setStateAtTime("stopped", startTick + duration + 1, { id: -1 });\n duration = new TicksClass(this.context, duration);\n }\n const interval = new TicksClass(this.context, this._getLoopDuration());\n event.id = this.context.transport.scheduleRepeat(this._tick.bind(this), interval, new TicksClass(this.context, startTick), duration);\n }\n else {\n event.id = this.context.transport.schedule(this._tick.bind(this), new TicksClass(this.context, startTick));\n }\n }\n });\n }\n /**\n * Returns the playback state of the note, either "started" or "stopped".\n */\n get state() {\n return this._state.getValueAtTime(this.context.transport.ticks);\n }\n /**\n * The start from the scheduled start time.\n */\n get startOffset() {\n return this._startOffset;\n }\n set startOffset(offset) {\n this._startOffset = offset;\n }\n /**\n * The probability of the notes being triggered.\n */\n get probability() {\n return this._probability;\n }\n set probability(prob) {\n this._probability = prob;\n }\n /**\n * If set to true, will apply small random variation\n * to the callback time. If the value is given as a time, it will randomize\n * by that amount.\n * @example\n * const event = new Tone.ToneEvent();\n * event.humanize = true;\n */\n get humanize() {\n return this._humanize;\n }\n set humanize(variation) {\n this._humanize = variation;\n }\n /**\n * Start the note at the given time.\n * @param time When the event should start.\n */\n start(time) {\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) === "stopped") {\n this._state.add({\n id: -1,\n state: "started",\n time: ticks,\n });\n this._rescheduleEvents(ticks);\n }\n return this;\n }\n /**\n * Stop the Event at the given time.\n * @param time When the event should stop.\n */\n stop(time) {\n this.cancel(time);\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) === "started") {\n this._state.setStateAtTime("stopped", ticks, { id: -1 });\n const previousEvent = this._state.getBefore(ticks);\n let reschedulTime = ticks;\n if (previousEvent !== null) {\n reschedulTime = previousEvent.time;\n }\n this._rescheduleEvents(reschedulTime);\n }\n return this;\n }\n /**\n * Cancel all scheduled events greater than or equal to the given time\n * @param time The time after which events will be cancel.\n */\n cancel(time) {\n time = defaultArg(time, -Infinity);\n const ticks = this.toTicks(time);\n this._state.forEachFrom(ticks, event => {\n this.context.transport.clear(event.id);\n });\n this._state.cancel(ticks);\n return this;\n }\n /**\n * The callback function invoker. Also\n * checks if the Event is done playing\n * @param time The time of the event in seconds\n */\n _tick(time) {\n const ticks = this.context.transport.getTicksAtTime(time);\n if (!this.mute && this._state.getValueAtTime(ticks) === "started") {\n if (this.probability < 1 && Math.random() > this.probability) {\n return;\n }\n if (this.humanize) {\n let variation = 0.02;\n if (!isBoolean(this.humanize)) {\n variation = this.toSeconds(this.humanize);\n }\n time += (Math.random() * 2 - 1) * variation;\n }\n this.callback(time, this.value);\n }\n }\n /**\n * Get the duration of the loop.\n */\n _getLoopDuration() {\n return Math.round((this._loopEnd - this._loopStart) / this._playbackRate);\n }\n /**\n * If the note should loop or not\n * between ToneEvent.loopStart and\n * ToneEvent.loopEnd. If set to true,\n * the event will loop indefinitely,\n * if set to a number greater than 1\n * it will play a specific number of\n * times, if set to false, 0 or 1, the\n * part will only play once.\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this._rescheduleEvents();\n }\n /**\n * The playback rate of the note. Defaults to 1.\n * @example\n * const note = new Tone.ToneEvent();\n * note.loop = true;\n * // repeat the note twice as fast\n * note.playbackRate = 2;\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n this._rescheduleEvents();\n }\n /**\n * The loopEnd point is the time the event will loop\n * if ToneEvent.loop is true.\n */\n get loopEnd() {\n return new TicksClass(this.context, this._loopEnd).toSeconds();\n }\n set loopEnd(loopEnd) {\n this._loopEnd = this.toTicks(loopEnd);\n if (this._loop) {\n this._rescheduleEvents();\n }\n }\n /**\n * The time when the loop should start.\n */\n get loopStart() {\n return new TicksClass(this.context, this._loopStart).toSeconds();\n }\n set loopStart(loopStart) {\n this._loopStart = this.toTicks(loopStart);\n if (this._loop) {\n this._rescheduleEvents();\n }\n }\n /**\n * The current progress of the loop interval.\n * Returns 0 if the event is not started yet or\n * it is not set to loop.\n */\n get progress() {\n if (this._loop) {\n const ticks = this.context.transport.ticks;\n const lastEvent = this._state.get(ticks);\n if (lastEvent !== null && lastEvent.state === "started") {\n const loopDuration = this._getLoopDuration();\n const progress = (ticks - lastEvent.time) % loopDuration;\n return progress / loopDuration;\n }\n else {\n return 0;\n }\n }\n else {\n return 0;\n }\n }\n dispose() {\n super.dispose();\n this.cancel();\n this._state.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Loop.js\n\n\n\n\n/**\n * Loop creates a looped callback at the\n * specified interval. The callback can be\n * started, stopped and scheduled along\n * the Transport\'s timeline.\n * @example\n * const loop = new Tone.Loop((time) => {\n * \t// triggered every eighth note.\n * \tconsole.log(time);\n * }, "8n").start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Loop_Loop extends (/* unused pure expression or super */ null && (ToneWithContext)) {\n constructor() {\n super(optionsFromArguments(Loop_Loop.getDefaults(), arguments, ["callback", "interval"]));\n this.name = "Loop";\n const options = optionsFromArguments(Loop_Loop.getDefaults(), arguments, ["callback", "interval"]);\n this._event = new ToneEvent({\n context: this.context,\n callback: this._tick.bind(this),\n loop: true,\n loopEnd: options.interval,\n playbackRate: options.playbackRate,\n probability: options.probability\n });\n this.callback = options.callback;\n // set the iterations\n this.iterations = options.iterations;\n }\n static getDefaults() {\n return Object.assign(ToneWithContext.getDefaults(), {\n interval: "4n",\n callback: noOp,\n playbackRate: 1,\n iterations: Infinity,\n probability: 1,\n mute: false,\n humanize: false\n });\n }\n /**\n * Start the loop at the specified time along the Transport\'s timeline.\n * @param time When to start the Loop.\n */\n start(time) {\n this._event.start(time);\n return this;\n }\n /**\n * Stop the loop at the given time.\n * @param time When to stop the Loop.\n */\n stop(time) {\n this._event.stop(time);\n return this;\n }\n /**\n * Cancel all scheduled events greater than or equal to the given time\n * @param time The time after which events will be cancel.\n */\n cancel(time) {\n this._event.cancel(time);\n return this;\n }\n /**\n * Internal function called when the notes should be called\n * @param time The time the event occurs\n */\n _tick(time) {\n this.callback(time);\n }\n /**\n * The state of the Loop, either started or stopped.\n */\n get state() {\n return this._event.state;\n }\n /**\n * The progress of the loop as a value between 0-1. 0, when the loop is stopped or done iterating.\n */\n get progress() {\n return this._event.progress;\n }\n /**\n * The time between successive callbacks.\n * @example\n * const loop = new Tone.Loop();\n * loop.interval = "8n"; // loop every 8n\n */\n get interval() {\n return this._event.loopEnd;\n }\n set interval(interval) {\n this._event.loopEnd = interval;\n }\n /**\n * The playback rate of the loop. The normal playback rate is 1 (no change).\n * A `playbackRate` of 2 would be twice as fast.\n */\n get playbackRate() {\n return this._event.playbackRate;\n }\n set playbackRate(rate) {\n this._event.playbackRate = rate;\n }\n /**\n * Random variation +/-0.01s to the scheduled time.\n * Or give it a time value which it will randomize by.\n */\n get humanize() {\n return this._event.humanize;\n }\n set humanize(variation) {\n this._event.humanize = variation;\n }\n /**\n * The probably of the callback being invoked.\n */\n get probability() {\n return this._event.probability;\n }\n set probability(prob) {\n this._event.probability = prob;\n }\n /**\n * Muting the Loop means that no callbacks are invoked.\n */\n get mute() {\n return this._event.mute;\n }\n set mute(mute) {\n this._event.mute = mute;\n }\n /**\n * The number of iterations of the loop. The default value is `Infinity` (loop forever).\n */\n get iterations() {\n if (this._event.loop === true) {\n return Infinity;\n }\n else {\n return this._event.loop;\n }\n }\n set iterations(iters) {\n if (iters === Infinity) {\n this._event.loop = true;\n }\n else {\n this._event.loop = iters;\n }\n }\n dispose() {\n super.dispose();\n this._event.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Loop.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Part.js\n\n\n\n\n\n\n/**\n * Part is a collection ToneEvents which can be started/stopped and looped as a single unit.\n *\n * @example\n * const synth = new Tone.Synth().toDestination();\n * const part = new Tone.Part(((time, note) => {\n * \t// the notes given as the second element in the array\n * \t// will be passed in as the second argument\n * \tsynth.triggerAttackRelease(note, "8n", time);\n * }), [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]);\n * Tone.Transport.start();\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // use an array of objects as long as the object has a "time" attribute\n * const part = new Tone.Part(((time, value) => {\n * \t// the value is an object which contains both the note and the velocity\n * \tsynth.triggerAttackRelease(value.note, "8n", time, value.velocity);\n * }), [{ time: 0, note: "C3", velocity: 0.9 },\n * \t{ time: "0:2", note: "C4", velocity: 0.5 }\n * ]).start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Part_Part extends (/* unused pure expression or super */ null && (ToneEvent)) {\n constructor() {\n super(optionsFromArguments(Part_Part.getDefaults(), arguments, ["callback", "events"]));\n this.name = "Part";\n /**\n * Tracks the scheduled events\n */\n this._state = new StateTimeline("stopped");\n /**\n * The events that belong to this part\n */\n this._events = new Set();\n const options = optionsFromArguments(Part_Part.getDefaults(), arguments, ["callback", "events"]);\n // make sure things are assigned in the right order\n this._state.increasing = true;\n // add the events\n options.events.forEach(event => {\n if (isArray(event)) {\n this.add(event[0], event[1]);\n }\n else {\n this.add(event);\n }\n });\n }\n static getDefaults() {\n return Object.assign(ToneEvent.getDefaults(), {\n events: [],\n });\n }\n /**\n * Start the part at the given time.\n * @param time When to start the part.\n * @param offset The offset from the start of the part to begin playing at.\n */\n start(time, offset) {\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) !== "started") {\n offset = defaultArg(offset, this._loop ? this._loopStart : 0);\n if (this._loop) {\n offset = defaultArg(offset, this._loopStart);\n }\n else {\n offset = defaultArg(offset, 0);\n }\n const computedOffset = this.toTicks(offset);\n this._state.add({\n id: -1,\n offset: computedOffset,\n state: "started",\n time: ticks,\n });\n this._forEach(event => {\n this._startNote(event, ticks, computedOffset);\n });\n }\n return this;\n }\n /**\n * Start the event in the given event at the correct time given\n * the ticks and offset and looping.\n * @param event\n * @param ticks\n * @param offset\n */\n _startNote(event, ticks, offset) {\n ticks -= offset;\n if (this._loop) {\n if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) {\n if (event.startOffset < offset) {\n // start it on the next loop\n ticks += this._getLoopDuration();\n }\n event.start(new TicksClass(this.context, ticks));\n }\n else if (event.startOffset < this._loopStart && event.startOffset >= offset) {\n event.loop = false;\n event.start(new TicksClass(this.context, ticks));\n }\n }\n else if (event.startOffset >= offset) {\n event.start(new TicksClass(this.context, ticks));\n }\n }\n get startOffset() {\n return this._startOffset;\n }\n set startOffset(offset) {\n this._startOffset = offset;\n this._forEach(event => {\n event.startOffset += this._startOffset;\n });\n }\n /**\n * Stop the part at the given time.\n * @param time When to stop the part.\n */\n stop(time) {\n const ticks = this.toTicks(time);\n this._state.cancel(ticks);\n this._state.setStateAtTime("stopped", ticks);\n this._forEach(event => {\n event.stop(time);\n });\n return this;\n }\n /**\n * Get/Set an Event\'s value at the given time.\n * If a value is passed in and no event exists at\n * the given time, one will be created with that value.\n * If two events are at the same time, the first one will\n * be returned.\n * @example\n * const part = new Tone.Part();\n * part.at("1m"); // returns the part at the first measure\n * part.at("2m", "C2"); // set the value at "2m" to C2.\n * // if an event didn\'t exist at that time, it will be created.\n * @param time The time of the event to get or set.\n * @param value If a value is passed in, the value of the event at the given time will be set to it.\n */\n at(time, value) {\n const timeInTicks = new TransportTimeClass(this.context, time).toTicks();\n const tickTime = new TicksClass(this.context, 1).toSeconds();\n const iterator = this._events.values();\n let result = iterator.next();\n while (!result.done) {\n const event = result.value;\n if (Math.abs(timeInTicks - event.startOffset) < tickTime) {\n if (isDefined(value)) {\n event.value = value;\n }\n return event;\n }\n result = iterator.next();\n }\n // if there was no event at that time, create one\n if (isDefined(value)) {\n this.add(time, value);\n // return the new event\n return this.at(time);\n }\n else {\n return null;\n }\n }\n add(time, value) {\n // extract the parameters\n if (time instanceof Object && Reflect.has(time, "time")) {\n value = time;\n time = value.time;\n }\n const ticks = this.toTicks(time);\n let event;\n if (value instanceof ToneEvent) {\n event = value;\n event.callback = this._tick.bind(this);\n }\n else {\n event = new ToneEvent({\n callback: this._tick.bind(this),\n context: this.context,\n value,\n });\n }\n // the start offset\n event.startOffset = ticks;\n // initialize the values\n event.set({\n humanize: this.humanize,\n loop: this.loop,\n loopEnd: this.loopEnd,\n loopStart: this.loopStart,\n playbackRate: this.playbackRate,\n probability: this.probability,\n });\n this._events.add(event);\n // start the note if it should be played right now\n this._restartEvent(event);\n return this;\n }\n /**\n * Restart the given event\n */\n _restartEvent(event) {\n this._state.forEach((stateEvent) => {\n if (stateEvent.state === "started") {\n this._startNote(event, stateEvent.time, stateEvent.offset);\n }\n else {\n // stop the note\n event.stop(new TicksClass(this.context, stateEvent.time));\n }\n });\n }\n remove(time, value) {\n // extract the parameters\n if (isObject(time) && time.hasOwnProperty("time")) {\n value = time;\n time = value.time;\n }\n time = this.toTicks(time);\n this._events.forEach(event => {\n if (event.startOffset === time) {\n if (isUndef(value) || (isDefined(value) && event.value === value)) {\n this._events.delete(event);\n event.dispose();\n }\n }\n });\n return this;\n }\n /**\n * Remove all of the notes from the group.\n */\n clear() {\n this._forEach(event => event.dispose());\n this._events.clear();\n return this;\n }\n /**\n * Cancel scheduled state change events: i.e. "start" and "stop".\n * @param after The time after which to cancel the scheduled events.\n */\n cancel(after) {\n this._forEach(event => event.cancel(after));\n this._state.cancel(this.toTicks(after));\n return this;\n }\n /**\n * Iterate over all of the events\n */\n _forEach(callback) {\n if (this._events) {\n this._events.forEach(event => {\n if (event instanceof Part_Part) {\n event._forEach(callback);\n }\n else {\n callback(event);\n }\n });\n }\n return this;\n }\n /**\n * Set the attribute of all of the events\n * @param attr the attribute to set\n * @param value The value to set it to\n */\n _setAll(attr, value) {\n this._forEach(event => {\n event[attr] = value;\n });\n }\n /**\n * Internal tick method\n * @param time The time of the event in seconds\n */\n _tick(time, value) {\n if (!this.mute) {\n this.callback(time, value);\n }\n }\n /**\n * Determine if the event should be currently looping\n * given the loop boundries of this Part.\n * @param event The event to test\n */\n _testLoopBoundries(event) {\n if (this._loop && (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd)) {\n event.cancel(0);\n }\n else if (event.state === "stopped") {\n // reschedule it if it\'s stopped\n this._restartEvent(event);\n }\n }\n get probability() {\n return this._probability;\n }\n set probability(prob) {\n this._probability = prob;\n this._setAll("probability", prob);\n }\n get humanize() {\n return this._humanize;\n }\n set humanize(variation) {\n this._humanize = variation;\n this._setAll("humanize", variation);\n }\n /**\n * If the part should loop or not\n * between Part.loopStart and\n * Part.loopEnd. If set to true,\n * the part will loop indefinitely,\n * if set to a number greater than 1\n * it will play a specific number of\n * times, if set to false, 0 or 1, the\n * part will only play once.\n * @example\n * const part = new Tone.Part();\n * // loop the part 8 times\n * part.loop = 8;\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this._forEach(event => {\n event.loopStart = this.loopStart;\n event.loopEnd = this.loopEnd;\n event.loop = loop;\n this._testLoopBoundries(event);\n });\n }\n /**\n * The loopEnd point determines when it will\n * loop if Part.loop is true.\n */\n get loopEnd() {\n return new TicksClass(this.context, this._loopEnd).toSeconds();\n }\n set loopEnd(loopEnd) {\n this._loopEnd = this.toTicks(loopEnd);\n if (this._loop) {\n this._forEach(event => {\n event.loopEnd = loopEnd;\n this._testLoopBoundries(event);\n });\n }\n }\n /**\n * The loopStart point determines when it will\n * loop if Part.loop is true.\n */\n get loopStart() {\n return new TicksClass(this.context, this._loopStart).toSeconds();\n }\n set loopStart(loopStart) {\n this._loopStart = this.toTicks(loopStart);\n if (this._loop) {\n this._forEach(event => {\n event.loopStart = this.loopStart;\n this._testLoopBoundries(event);\n });\n }\n }\n /**\n * The playback rate of the part\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n this._setAll("playbackRate", rate);\n }\n /**\n * The number of scheduled notes in the part.\n */\n get length() {\n return this._events.size;\n }\n dispose() {\n super.dispose();\n this.clear();\n return this;\n }\n}\n//# sourceMappingURL=Part.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/PatternGenerator.js\n\n\n/**\n * Start at the first value and go up to the last\n */\nfunction* upPatternGen(values) {\n let index = 0;\n while (index < values.length) {\n index = clampToArraySize(index, values);\n yield values[index];\n index++;\n }\n}\n/**\n * Start at the last value and go down to 0\n */\nfunction* downPatternGen(values) {\n let index = values.length - 1;\n while (index >= 0) {\n index = clampToArraySize(index, values);\n yield values[index];\n index--;\n }\n}\n/**\n * Infinitely yield the generator\n */\nfunction* infiniteGen(values, gen) {\n while (true) {\n yield* gen(values);\n }\n}\n/**\n * Make sure that the index is in the given range\n */\nfunction clampToArraySize(index, values) {\n return clamp(index, 0, values.length - 1);\n}\n/**\n * Alternate between two generators\n */\nfunction* alternatingGenerator(values, directionUp) {\n let index = directionUp ? 0 : values.length - 1;\n while (true) {\n index = clampToArraySize(index, values);\n yield values[index];\n if (directionUp) {\n index++;\n if (index >= values.length - 1) {\n directionUp = false;\n }\n }\n else {\n index--;\n if (index <= 0) {\n directionUp = true;\n }\n }\n }\n}\n/**\n * Starting from the bottom move up 2, down 1\n */\nfunction* jumpUp(values) {\n let index = 0;\n let stepIndex = 0;\n while (index < values.length) {\n index = clampToArraySize(index, values);\n yield values[index];\n stepIndex++;\n index += (stepIndex % 2 ? 2 : -1);\n }\n}\n/**\n * Starting from the top move down 2, up 1\n */\nfunction* jumpDown(values) {\n let index = values.length - 1;\n let stepIndex = 0;\n while (index >= 0) {\n index = clampToArraySize(index, values);\n yield values[index];\n stepIndex++;\n index += (stepIndex % 2 ? -2 : 1);\n }\n}\n/**\n * Choose a random index each time\n */\nfunction* randomGen(values) {\n while (true) {\n const randomIndex = Math.floor(Math.random() * values.length);\n yield values[randomIndex];\n }\n}\n/**\n * Randomly go through all of the values once before choosing a new random order\n */\nfunction* randomOnce(values) {\n // create an array of indices\n const copy = [];\n for (let i = 0; i < values.length; i++) {\n copy.push(i);\n }\n while (copy.length > 0) {\n // random choose an index, and then remove it so it\'s not chosen again\n const randVal = copy.splice(Math.floor(copy.length * Math.random()), 1);\n const index = clampToArraySize(randVal[0], values);\n yield values[index];\n }\n}\n/**\n * Randomly choose to walk up or down 1 index in the values array\n */\nfunction* randomWalk(values) {\n // randomly choose a starting index in the values array\n let index = Math.floor(Math.random() * values.length);\n while (true) {\n if (index === 0) {\n index++; // at bottom of array, so force upward step\n }\n else if (index === values.length - 1) {\n index--; // at top of array, so force downward step\n }\n else if (Math.random() < 0.5) { // else choose random downward or upward step\n index--;\n }\n else {\n index++;\n }\n yield values[index];\n }\n}\n/**\n * PatternGenerator returns a generator which will iterate over the given array\n * of values and yield the items according to the passed in pattern\n * @param values An array of values to iterate over\n * @param pattern The name of the pattern use when iterating over\n * @param index Where to start in the offset of the values array\n */\nfunction* PatternGenerator_PatternGenerator(values, pattern = "up", index = 0) {\n // safeguards\n assert(values.length > 0, "The array must have more than one value in it");\n switch (pattern) {\n case "up":\n yield* infiniteGen(values, upPatternGen);\n case "down":\n yield* infiniteGen(values, downPatternGen);\n case "upDown":\n yield* alternatingGenerator(values, true);\n case "downUp":\n yield* alternatingGenerator(values, false);\n case "alternateUp":\n yield* infiniteGen(values, jumpUp);\n case "alternateDown":\n yield* infiniteGen(values, jumpDown);\n case "random":\n yield* randomGen(values);\n case "randomOnce":\n yield* infiniteGen(values, randomOnce);\n case "randomWalk":\n yield* randomWalk(values);\n }\n}\n//# sourceMappingURL=PatternGenerator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Pattern.js\n\n\n\n\n/**\n * Pattern arpeggiates between the given notes\n * in a number of patterns.\n * @example\n * const pattern = new Tone.Pattern((time, note) => {\n * \t// the order of the notes passed in depends on the pattern\n * }, ["C2", "D4", "E5", "A6"], "upDown");\n * @category Event\n */\nclass Pattern extends (/* unused pure expression or super */ null && (Loop)) {\n constructor() {\n super(optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]));\n this.name = "Pattern";\n const options = optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]);\n this.callback = options.callback;\n this._values = options.values;\n this._pattern = PatternGenerator(options.values, options.pattern);\n this._type = options.pattern;\n }\n static getDefaults() {\n return Object.assign(Loop.getDefaults(), {\n pattern: "up",\n values: [],\n callback: noOp,\n });\n }\n /**\n * Internal function called when the notes should be called\n */\n _tick(time) {\n const value = this._pattern.next();\n this._value = value.value;\n this.callback(time, this._value);\n }\n /**\n * The array of events.\n */\n get values() {\n return this._values;\n }\n set values(val) {\n this._values = val;\n // reset the pattern\n this.pattern = this._type;\n }\n /**\n * The current value of the pattern.\n */\n get value() {\n return this._value;\n }\n /**\n * The pattern type. See Tone.CtrlPattern for the full list of patterns.\n */\n get pattern() {\n return this._type;\n }\n set pattern(pattern) {\n this._type = pattern;\n this._pattern = PatternGenerator(this._values, this._type);\n }\n}\n//# sourceMappingURL=Pattern.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Sequence.js\n\n\n\n\n\n/**\n * A sequence is an alternate notation of a part. Instead\n * of passing in an array of [time, event] pairs, pass\n * in an array of events which will be spaced at the\n * given subdivision. Sub-arrays will subdivide that beat\n * by the number of items are in the array.\n * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/)\n * @example\n * const synth = new Tone.Synth().toDestination();\n * const seq = new Tone.Sequence((time, note) => {\n * \tsynth.triggerAttackRelease(note, 0.1, time);\n * \t// subdivisions are given as subarrays\n * }, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]]).start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Sequence extends (/* unused pure expression or super */ null && (ToneEvent)) {\n constructor() {\n super(optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]));\n this.name = "Sequence";\n /**\n * The object responsible for scheduling all of the events\n */\n this._part = new Part({\n callback: this._seqCallback.bind(this),\n context: this.context,\n });\n /**\n * private reference to all of the sequence proxies\n */\n this._events = [];\n /**\n * The proxied array\n */\n this._eventsArray = [];\n const options = optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]);\n this._subdivision = this.toTicks(options.subdivision);\n this.events = options.events;\n // set all of the values\n this.loop = options.loop;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this.playbackRate = options.playbackRate;\n this.probability = options.probability;\n this.humanize = options.humanize;\n this.mute = options.mute;\n this.playbackRate = options.playbackRate;\n }\n static getDefaults() {\n return Object.assign(omitFromObject(ToneEvent.getDefaults(), ["value"]), {\n events: [],\n loop: true,\n loopEnd: 0,\n loopStart: 0,\n subdivision: "8n",\n });\n }\n /**\n * The internal callback for when an event is invoked\n */\n _seqCallback(time, value) {\n if (value !== null) {\n this.callback(time, value);\n }\n }\n /**\n * The sequence\n */\n get events() {\n return this._events;\n }\n set events(s) {\n this.clear();\n this._eventsArray = s;\n this._events = this._createSequence(this._eventsArray);\n this._eventsUpdated();\n }\n /**\n * Start the part at the given time.\n * @param time When to start the part.\n * @param offset The offset index to start at\n */\n start(time, offset) {\n this._part.start(time, offset ? this._indexTime(offset) : offset);\n return this;\n }\n /**\n * Stop the part at the given time.\n * @param time When to stop the part.\n */\n stop(time) {\n this._part.stop(time);\n return this;\n }\n /**\n * The subdivision of the sequence. This can only be\n * set in the constructor. The subdivision is the\n * interval between successive steps.\n */\n get subdivision() {\n return new TicksClass(this.context, this._subdivision).toSeconds();\n }\n /**\n * Create a sequence proxy which can be monitored to create subsequences\n */\n _createSequence(array) {\n return new Proxy(array, {\n get: (target, property) => {\n // property is index in this case\n return target[property];\n },\n set: (target, property, value) => {\n if (isString(property) && isFinite(parseInt(property, 10))) {\n if (isArray(value)) {\n target[property] = this._createSequence(value);\n }\n else {\n target[property] = value;\n }\n }\n else {\n target[property] = value;\n }\n this._eventsUpdated();\n // return true to accept the changes\n return true;\n },\n });\n }\n /**\n * When the sequence has changed, all of the events need to be recreated\n */\n _eventsUpdated() {\n this._part.clear();\n this._rescheduleSequence(this._eventsArray, this._subdivision, this.startOffset);\n // update the loopEnd\n this.loopEnd = this.loopEnd;\n }\n /**\n * reschedule all of the events that need to be rescheduled\n */\n _rescheduleSequence(sequence, subdivision, startOffset) {\n sequence.forEach((value, index) => {\n const eventOffset = index * (subdivision) + startOffset;\n if (isArray(value)) {\n this._rescheduleSequence(value, subdivision / value.length, eventOffset);\n }\n else {\n const startTime = new TicksClass(this.context, eventOffset, "i").toSeconds();\n this._part.add(startTime, value);\n }\n });\n }\n /**\n * Get the time of the index given the Sequence\'s subdivision\n * @param index\n * @return The time of that index\n */\n _indexTime(index) {\n return new TicksClass(this.context, index * (this._subdivision) + this.startOffset).toSeconds();\n }\n /**\n * Clear all of the events\n */\n clear() {\n this._part.clear();\n return this;\n }\n dispose() {\n super.dispose();\n this._part.dispose();\n return this;\n }\n //-------------------------------------\n // PROXY CALLS\n //-------------------------------------\n get loop() {\n return this._part.loop;\n }\n set loop(l) {\n this._part.loop = l;\n }\n /**\n * The index at which the sequence should start looping\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(index) {\n this._loopStart = index;\n this._part.loopStart = this._indexTime(index);\n }\n /**\n * The index at which the sequence should end looping\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(index) {\n this._loopEnd = index;\n if (index === 0) {\n this._part.loopEnd = this._indexTime(this._eventsArray.length);\n }\n else {\n this._part.loopEnd = this._indexTime(index);\n }\n }\n get startOffset() {\n return this._part.startOffset;\n }\n set startOffset(start) {\n this._part.startOffset = start;\n }\n get playbackRate() {\n return this._part.playbackRate;\n }\n set playbackRate(rate) {\n this._part.playbackRate = rate;\n }\n get probability() {\n return this._part.probability;\n }\n set probability(prob) {\n this._part.probability = prob;\n }\n get progress() {\n return this._part.progress;\n }\n get humanize() {\n return this._part.humanize;\n }\n set humanize(variation) {\n this._part.humanize = variation;\n }\n /**\n * The number of scheduled events\n */\n get length() {\n return this._part.length;\n }\n}\n//# sourceMappingURL=Sequence.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/index.js\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/CrossFade.js\n\n\n\n\n\n\n/**\n * Tone.Crossfade provides equal power fading between two inputs.\n * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n * ```\n * +---------+\n * +> input a +>--+\n * +-----------+ +---------------------+ | | |\n * | 1s signal +>--\x3e stereoPannerNode L +>----\x3e gain | |\n * +-----------+ | | +---------+ |\n * +-> pan R +>-+ | +--------+\n * | +---------------------+ | +---\x3e output +>\n * +------+ | | +---------+ | +--------+\n * | fade +>----+ | +> input b +>--+\n * +------+ | | |\n * +--\x3e gain |\n * +---------+\n * ```\n * @example\n * const crossFade = new Tone.CrossFade().toDestination();\n * // connect two inputs Tone.to a/b\n * const inputA = new Tone.Oscillator(440, "square").connect(crossFade.a).start();\n * const inputB = new Tone.Oscillator(440, "sine").connect(crossFade.b).start();\n * // use the fade to control the mix between the two\n * crossFade.fade.value = 0.5;\n * @category Component\n */\nclass CrossFade_CrossFade extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(CrossFade_CrossFade.getDefaults(), arguments, ["fade"])));\n this.name = "CrossFade";\n /**\n * The crossfading is done by a StereoPannerNode\n */\n this._panner = this.context.createStereoPanner();\n /**\n * Split the output of the panner node into two values used to control the gains.\n */\n this._split = this.context.createChannelSplitter(2);\n /**\n * Convert the fade value into an audio range value so it can be connected\n * to the panner.pan AudioParam\n */\n this._g2a = new GainToAudio({ context: this.context });\n /**\n * The input which is at full level when fade = 0\n */\n this.a = new Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The input which is at full level when fade = 1\n */\n this.b = new Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The output is a mix between `a` and `b` at the ratio of `fade`\n */\n this.output = new Gain({ context: this.context });\n this._internalChannels = [this.a, this.b];\n const options = optionsFromArguments(CrossFade_CrossFade.getDefaults(), arguments, ["fade"]);\n this.fade = new Signal({\n context: this.context,\n units: "normalRange",\n value: options.fade,\n });\n readOnly(this, "fade");\n this.context.getConstant(1).connect(this._panner);\n this._panner.connect(this._split);\n // this is necessary for standardized-audio-context\n // doesn\'t make any difference for the native AudioContext\n // https://github.com/chrisguttandin/standardized-audio-context/issues/647\n this._panner.channelCount = 1;\n this._panner.channelCountMode = "explicit";\n connect(this._split, this.a.gain, 0);\n connect(this._split, this.b.gain, 1);\n this.fade.chain(this._g2a, this._panner.pan);\n this.a.connect(this.output);\n this.b.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n fade: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.a.dispose();\n this.b.dispose();\n this.output.dispose();\n this.fade.dispose();\n this._g2a.dispose();\n this._panner.disconnect();\n this._split.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=CrossFade.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Effect.js\n\n\n\n\n/**\n * Effect is the base class for effects. Connect the effect between\n * the effectSend and effectReturn GainNodes, then control the amount of\n * effect which goes to the output using the wet control.\n */\nclass Effect_Effect extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "Effect";\n /**\n * the drywet knob to control the amount of effect\n */\n this._dryWet = new CrossFade({ context: this.context });\n /**\n * The wet control is how much of the effected\n * will pass through to the output. 1 = 100% effected\n * signal, 0 = 100% dry signal.\n */\n this.wet = this._dryWet.fade;\n /**\n * connect the effectSend to the input of hte effect\n */\n this.effectSend = new Gain({ context: this.context });\n /**\n * connect the output of the effect to the effectReturn\n */\n this.effectReturn = new Gain({ context: this.context });\n /**\n * The effect input node\n */\n this.input = new Gain({ context: this.context });\n /**\n * The effect output\n */\n this.output = this._dryWet;\n // connections\n this.input.fan(this._dryWet.a, this.effectSend);\n this.effectReturn.connect(this._dryWet.b);\n this.wet.setValueAtTime(options.wet, 0);\n this._internalChannels = [this.effectReturn, this.effectSend];\n readOnly(this, "wet");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n wet: 1,\n });\n }\n /**\n * chains the effect in between the effectSend and effectReturn\n */\n connectEffect(effect) {\n // add it to the internal channels\n this._internalChannels.push(effect);\n this.effectSend.chain(effect, this.effectReturn);\n return this;\n }\n dispose() {\n super.dispose();\n this._dryWet.dispose();\n this.effectSend.dispose();\n this.effectReturn.dispose();\n this.wet.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Effect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/LFOEffect.js\n\n\n\n/**\n * Base class for LFO-based effects.\n */\nclass LFOEffect_LFOEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "LFOEffect";\n this._lfo = new LFO({\n context: this.context,\n frequency: options.frequency,\n amplitude: options.depth,\n });\n this.depth = this._lfo.amplitude;\n this.frequency = this._lfo.frequency;\n this.type = options.type;\n readOnly(this, ["frequency", "depth"]);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n frequency: 1,\n type: "sine",\n depth: 1,\n });\n }\n /**\n * Start the effect.\n */\n start(time) {\n this._lfo.start(time);\n return this;\n }\n /**\n * Stop the lfo\n */\n stop(time) {\n this._lfo.stop(time);\n return this;\n }\n /**\n * Sync the filter to the transport. See [[LFO.sync]]\n */\n sync() {\n this._lfo.sync();\n return this;\n }\n /**\n * Unsync the filter from the transport.\n */\n unsync() {\n this._lfo.unsync();\n return this;\n }\n /**\n * The type of the LFO\'s oscillator: See [[Oscillator.type]]\n * @example\n * const autoFilter = new Tone.AutoFilter().start().toDestination();\n * const noise = new Tone.Noise().start().connect(autoFilter);\n * autoFilter.type = "square";\n */\n get type() {\n return this._lfo.type;\n }\n set type(type) {\n this._lfo.type = type;\n }\n dispose() {\n super.dispose();\n this._lfo.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LFOEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoFilter.js\n\n\n\n/**\n * AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency.\n * Setting the LFO rate and depth allows for control over the filter modulation rate\n * and depth.\n *\n * @example\n * // create an autofilter and start it\'s LFO\n * const autoFilter = new Tone.AutoFilter("4n").toDestination().start();\n * // route an oscillator through the filter and start it\n * const oscillator = new Tone.Oscillator().connect(autoFilter).start();\n * @category Effect\n */\nclass AutoFilter extends (/* unused pure expression or super */ null && (LFOEffect)) {\n constructor() {\n super(optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]));\n this.name = "AutoFilter";\n const options = optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]);\n this.filter = new Filter(Object.assign(options.filter, {\n context: this.context,\n }));\n // connections\n this.connectEffect(this.filter);\n this._lfo.connect(this.filter.frequency);\n this.octaves = options.octaves;\n this.baseFrequency = options.baseFrequency;\n }\n static getDefaults() {\n return Object.assign(LFOEffect.getDefaults(), {\n baseFrequency: 200,\n octaves: 2.6,\n filter: {\n type: "lowpass",\n rolloff: -12,\n Q: 1,\n }\n });\n }\n /**\n * The minimum value of the filter\'s cutoff frequency.\n */\n get baseFrequency() {\n return this._lfo.min;\n }\n set baseFrequency(freq) {\n this._lfo.min = this.toFrequency(freq);\n // and set the max\n this.octaves = this._octaves;\n }\n /**\n * The maximum value of the filter\'s cutoff frequency.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(oct) {\n this._octaves = oct;\n this._lfo.max = this._lfo.min * Math.pow(2, oct);\n }\n dispose() {\n super.dispose();\n this.filter.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Panner.js\n\n\n\n\n/**\n * Panner is an equal power Left/Right Panner. It is a wrapper around the StereoPannerNode.\n * @example\n * return Tone.Offline(() => {\n * // move the input signal from right to left\n * \tconst panner = new Tone.Panner(1).toDestination();\n * \tpanner.pan.rampTo(-1, 0.5);\n * \tconst osc = new Tone.Oscillator(100).connect(panner).start();\n * }, 0.5, 2);\n * @category Component\n */\nclass Panner_Panner extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(Panner_Panner.getDefaults(), arguments, ["pan"])));\n this.name = "Panner";\n /**\n * the panner node\n */\n this._panner = this.context.createStereoPanner();\n this.input = this._panner;\n this.output = this._panner;\n const options = Defaults_optionsFromArguments(Panner_Panner.getDefaults(), arguments, ["pan"]);\n this.pan = new Param_Param({\n context: this.context,\n param: this._panner.pan,\n value: options.pan,\n minValue: -1,\n maxValue: 1,\n });\n // this is necessary for standardized-audio-context\n // doesn\'t make any difference for the native AudioContext\n // https://github.com/chrisguttandin/standardized-audio-context/issues/647\n this._panner.channelCount = options.channelCount;\n this._panner.channelCountMode = "explicit";\n // initial value\n Interface_readOnly(this, "pan");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n pan: 0,\n channelCount: 1,\n });\n }\n dispose() {\n super.dispose();\n this._panner.disconnect();\n this.pan.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Panner.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoPanner.js\n\n\n\n/**\n * AutoPanner is a [[Panner]] with an [[LFO]] connected to the pan amount.\n * [Related Reading](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/).\n *\n * @example\n * // create an autopanner and start it\n * const autoPanner = new Tone.AutoPanner("4n").toDestination().start();\n * // route an oscillator through the panner and start it\n * const oscillator = new Tone.Oscillator().connect(autoPanner).start();\n * @category Effect\n */\nclass AutoPanner extends (/* unused pure expression or super */ null && (LFOEffect)) {\n constructor() {\n super(optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]));\n this.name = "AutoPanner";\n const options = optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]);\n this._panner = new Panner({\n context: this.context,\n channelCount: options.channelCount\n });\n // connections\n this.connectEffect(this._panner);\n this._lfo.connect(this._panner.pan);\n this._lfo.min = -1;\n this._lfo.max = 1;\n }\n static getDefaults() {\n return Object.assign(LFOEffect.getDefaults(), {\n channelCount: 1\n });\n }\n dispose() {\n super.dispose();\n this._panner.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoPanner.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Follower.js\n\n\n\n\n/**\n * Follower is a simple envelope follower.\n * It\'s implemented by applying a lowpass filter to the absolute value of the incoming signal.\n * ```\n * +-----+ +---------------+\n * Input +--\x3e Abs +----\x3e OnePoleFilter +--\x3e Output\n * +-----+ +---------------+\n * ```\n * @category Component\n */\nclass Follower_Follower extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Follower_Follower.getDefaults(), arguments, ["smoothing"]));\n this.name = "Follower";\n const options = optionsFromArguments(Follower_Follower.getDefaults(), arguments, ["smoothing"]);\n this._abs = this.input = new Abs({ context: this.context });\n this._lowpass = this.output = new OnePoleFilter({\n context: this.context,\n frequency: 1 / this.toSeconds(options.smoothing),\n type: "lowpass"\n });\n this._abs.connect(this._lowpass);\n this._smoothing = options.smoothing;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n smoothing: 0.05\n });\n }\n /**\n * The amount of time it takes a value change to arrive at the updated value.\n */\n get smoothing() {\n return this._smoothing;\n }\n set smoothing(smoothing) {\n this._smoothing = smoothing;\n this._lowpass.frequency = 1 / this.toSeconds(this.smoothing);\n }\n dispose() {\n super.dispose();\n this._abs.dispose();\n this._lowpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Follower.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoWah.js\n\n\n\n\n\n\n\n\n/**\n * AutoWah connects a [[Follower]] to a [[Filter]].\n * The frequency of the filter, follows the input amplitude curve.\n * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna).\n *\n * @example\n * const autoWah = new Tone.AutoWah(50, 6, -30).toDestination();\n * // initialize the synth and connect to autowah\n * const synth = new Tone.Synth().connect(autoWah);\n * // Q value influences the effect of the wah - default is 2\n * autoWah.Q.value = 6;\n * // more audible on higher notes\n * synth.triggerAttackRelease("C4", "8n");\n * @category Effect\n */\nclass AutoWah extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]));\n this.name = "AutoWah";\n const options = optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]);\n this._follower = new Follower({\n context: this.context,\n smoothing: options.follower,\n });\n this._sweepRange = new ScaleExp({\n context: this.context,\n min: 0,\n max: 1,\n exponent: 0.5,\n });\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._octaves = options.octaves;\n this._inputBoost = new Gain({ context: this.context });\n this._bandpass = new Filter({\n context: this.context,\n rolloff: -48,\n frequency: 0,\n Q: options.Q,\n });\n this._peaking = new Filter({\n context: this.context,\n type: "peaking"\n });\n this._peaking.gain.value = options.gain;\n this.gain = this._peaking.gain;\n this.Q = this._bandpass.Q;\n // the control signal path\n this.effectSend.chain(this._inputBoost, this._follower, this._sweepRange);\n this._sweepRange.connect(this._bandpass.frequency);\n this._sweepRange.connect(this._peaking.frequency);\n // the filtered path\n this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);\n // set the initial value\n this._setSweepRange();\n this.sensitivity = options.sensitivity;\n readOnly(this, ["gain", "Q"]);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n baseFrequency: 100,\n octaves: 6,\n sensitivity: 0,\n Q: 2,\n gain: 2,\n follower: 0.2,\n });\n }\n /**\n * The number of octaves that the filter will sweep above the baseFrequency.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n this._setSweepRange();\n }\n /**\n * The follower\'s smoothing time\n */\n get follower() {\n return this._follower.smoothing;\n }\n set follower(follower) {\n this._follower.smoothing = follower;\n }\n /**\n * The base frequency from which the sweep will start from.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(baseFreq) {\n this._baseFrequency = this.toFrequency(baseFreq);\n this._setSweepRange();\n }\n /**\n * The sensitivity to control how responsive to the input signal the filter is.\n */\n get sensitivity() {\n return gainToDb(1 / this._inputBoost.gain.value);\n }\n set sensitivity(sensitivity) {\n this._inputBoost.gain.value = 1 / dbToGain(sensitivity);\n }\n /**\n * sets the sweep range of the scaler\n */\n _setSweepRange() {\n this._sweepRange.min = this._baseFrequency;\n this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);\n }\n dispose() {\n super.dispose();\n this._follower.dispose();\n this._sweepRange.dispose();\n this._bandpass.dispose();\n this._peaking.dispose();\n this._inputBoost.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoWah.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/BitCrusher.worklet.js\n\n\nconst BitCrusher_worklet_workletName = "bit-crusher";\nconst bitCrusherWorklet = /* javascript */ `\n\tclass BitCrusherWorklet extends SingleIOProcessor {\n\n\t\tstatic get parameterDescriptors() {\n\t\t\treturn [{\n\t\t\t\tname: "bits",\n\t\t\t\tdefaultValue: 12,\n\t\t\t\tminValue: 1,\n\t\t\t\tmaxValue: 16,\n\t\t\t\tautomationRate: \'k-rate\'\n\t\t\t}];\n\t\t}\n\n\t\tgenerate(input, _channel, parameters) {\n\t\t\tconst step = Math.pow(0.5, parameters.bits - 1);\n\t\t\tconst val = step * Math.floor(input / step + 0.5);\n\t\t\treturn val;\n\t\t}\n\t}\n`;\nregisterProcessor(BitCrusher_worklet_workletName, bitCrusherWorklet);\n//# sourceMappingURL=BitCrusher.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/BitCrusher.js\n\n\n\n\n\n\n\n/**\n * BitCrusher down-samples the incoming signal to a different bit depth.\n * Lowering the bit depth of the signal creates distortion. Read more about BitCrushing\n * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher).\n * @example\n * // initialize crusher and route a synth through it\n * const crusher = new Tone.BitCrusher(4).toDestination();\n * const synth = new Tone.Synth().connect(crusher);\n * synth.triggerAttackRelease("C2", 2);\n *\n * @category Effect\n */\nclass BitCrusher extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]));\n this.name = "BitCrusher";\n const options = optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]);\n this._bitCrusherWorklet = new BitCrusherWorklet({\n context: this.context,\n bits: options.bits,\n });\n // connect it up\n this.connectEffect(this._bitCrusherWorklet);\n this.bits = this._bitCrusherWorklet.bits;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n bits: 4,\n });\n }\n dispose() {\n super.dispose();\n this._bitCrusherWorklet.dispose();\n return this;\n }\n}\n/**\n * Internal class which creates an AudioWorklet to do the bit crushing\n */\nclass BitCrusherWorklet extends (/* unused pure expression or super */ null && (ToneAudioWorklet)) {\n constructor() {\n super(optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments));\n this.name = "BitCrusherWorklet";\n const options = optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments);\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this.bits = new Param({\n context: this.context,\n value: options.bits,\n units: "positive",\n minValue: 1,\n maxValue: 16,\n param: this._dummyParam,\n swappable: true,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioWorklet.getDefaults(), {\n bits: 12,\n });\n }\n _audioWorkletName() {\n return workletName;\n }\n onReady(node) {\n connectSeries(this.input, node, this.output);\n const bits = node.parameters.get("bits");\n this.bits.setParam(bits);\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.bits.dispose();\n return this;\n }\n}\n//# sourceMappingURL=BitCrusher.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Chebyshev.js\n\n\n\n/**\n * Chebyshev is a waveshaper which is good\n * for making different types of distortion sounds.\n * Note that odd orders sound very different from even ones,\n * and order = 1 is no change.\n * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php).\n * @example\n * // create a new cheby\n * const cheby = new Tone.Chebyshev(50).toDestination();\n * // create a monosynth connected to our cheby\n * const synth = new Tone.MonoSynth().connect(cheby);\n * synth.triggerAttackRelease("C2", 0.4);\n * @category Effect\n */\nclass Chebyshev extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]));\n this.name = "Chebyshev";\n const options = optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]);\n this._shaper = new WaveShaper({\n context: this.context,\n length: 4096\n });\n this._order = options.order;\n this.connectEffect(this._shaper);\n this.order = options.order;\n this.oversample = options.oversample;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n order: 1,\n oversample: "none"\n });\n }\n /**\n * get the coefficient for that degree\n * @param x the x value\n * @param degree\n * @param memo memoize the computed value. this speeds up computation greatly.\n */\n _getCoefficient(x, degree, memo) {\n if (memo.has(degree)) {\n return memo.get(degree);\n }\n else if (degree === 0) {\n memo.set(degree, 0);\n }\n else if (degree === 1) {\n memo.set(degree, x);\n }\n else {\n memo.set(degree, 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo));\n }\n return memo.get(degree);\n }\n /**\n * The order of the Chebyshev polynomial which creates the equation which is applied to the incoming\n * signal through a Tone.WaveShaper. The equations are in the form:\n * ```\n * order 2: 2x^2 + 1\n * order 3: 4x^3 + 3x\n * ```\n * @min 1\n * @max 100\n */\n get order() {\n return this._order;\n }\n set order(order) {\n this._order = order;\n this._shaper.setMap((x => {\n return this._getCoefficient(x, order, new Map());\n }));\n }\n /**\n * The oversampling of the effect. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n this._shaper.oversample = oversampling;\n }\n dispose() {\n super.dispose();\n this._shaper.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Chebyshev.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Split.js\n\n\n/**\n * Split splits an incoming signal into the number of given channels.\n *\n * @example\n * const split = new Tone.Split();\n * // stereoSignal.connect(split);\n * @category Component\n */\nclass Split_Split extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Split_Split.getDefaults(), arguments, ["channels"]));\n this.name = "Split";\n const options = optionsFromArguments(Split_Split.getDefaults(), arguments, ["channels"]);\n this._splitter = this.input = this.output = this.context.createChannelSplitter(options.channels);\n this._internalChannels = [this._splitter];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n channels: 2,\n });\n }\n dispose() {\n super.dispose();\n this._splitter.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Split.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Merge.js\n\n\n/**\n * Merge brings multiple mono input channels into a single multichannel output channel.\n *\n * @example\n * const merge = new Tone.Merge().toDestination();\n * // routing a sine tone in the left channel\n * const osc = new Tone.Oscillator().connect(merge, 0, 0).start();\n * // and noise in the right channel\n * const noise = new Tone.Noise().connect(merge, 0, 1).start();;\n * @category Component\n */\nclass Merge_Merge extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Merge_Merge.getDefaults(), arguments, ["channels"]));\n this.name = "Merge";\n const options = optionsFromArguments(Merge_Merge.getDefaults(), arguments, ["channels"]);\n this._merger = this.output = this.input = this.context.createChannelMerger(options.channels);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n channels: 2,\n });\n }\n dispose() {\n super.dispose();\n this._merger.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Merge.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoEffect.js\n\n\n\n\n\n\n/**\n * Base class for Stereo effects.\n */\nclass StereoEffect_StereoEffect extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "StereoEffect";\n this.input = new Gain({ context: this.context });\n // force mono sources to be stereo\n this.input.channelCount = 2;\n this.input.channelCountMode = "explicit";\n this._dryWet = this.output = new CrossFade({\n context: this.context,\n fade: options.wet\n });\n this.wet = this._dryWet.fade;\n this._split = new Split({ context: this.context, channels: 2 });\n this._merge = new Merge({ context: this.context, channels: 2 });\n // connections\n this.input.connect(this._split);\n // dry wet connections\n this.input.connect(this._dryWet.a);\n this._merge.connect(this._dryWet.b);\n readOnly(this, ["wet"]);\n }\n /**\n * Connect the left part of the effect\n */\n connectEffectLeft(...nodes) {\n this._split.connect(nodes[0], 0, 0);\n connectSeries(...nodes);\n connect(nodes[nodes.length - 1], this._merge, 0, 0);\n }\n /**\n * Connect the right part of the effect\n */\n connectEffectRight(...nodes) {\n this._split.connect(nodes[0], 1, 0);\n connectSeries(...nodes);\n connect(nodes[nodes.length - 1], this._merge, 0, 1);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n wet: 1,\n });\n }\n dispose() {\n super.dispose();\n this._dryWet.dispose();\n this._split.dispose();\n this._merge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoFeedbackEffect.js\n\n\n\n\n\n\n/**\n * Base class for stereo feedback effects where the effectReturn is fed back into the same channel.\n */\nclass StereoFeedbackEffect_StereoFeedbackEffect extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor(options) {\n super(options);\n this.feedback = new Signal({\n context: this.context,\n value: options.feedback,\n units: "normalRange"\n });\n this._feedbackL = new Gain({ context: this.context });\n this._feedbackR = new Gain({ context: this.context });\n this._feedbackSplit = new Split({ context: this.context, channels: 2 });\n this._feedbackMerge = new Merge({ context: this.context, channels: 2 });\n this._merge.connect(this._feedbackSplit);\n this._feedbackMerge.connect(this._split);\n // the left output connected to the left input\n this._feedbackSplit.connect(this._feedbackL, 0, 0);\n this._feedbackL.connect(this._feedbackMerge, 0, 0);\n // the right output connected to the right input\n this._feedbackSplit.connect(this._feedbackR, 1, 0);\n this._feedbackR.connect(this._feedbackMerge, 0, 1);\n // the feedback control\n this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);\n readOnly(this, ["feedback"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n feedback: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.feedback.dispose();\n this._feedbackL.dispose();\n this._feedbackR.dispose();\n this._feedbackSplit.dispose();\n this._feedbackMerge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoFeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Chorus.js\n\n\n\n\n\n/**\n * Chorus is a stereo chorus effect composed of a left and right delay with an [[LFO]] applied to the delayTime of each channel.\n * When [[feedback]] is set to a value larger than 0, you also get Flanger-type effects.\n * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js).\n * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm).\n *\n * @example\n * const chorus = new Tone.Chorus(4, 2.5, 0.5).toDestination().start();\n * const synth = new Tone.PolySynth().connect(chorus);\n * synth.triggerAttackRelease(["C3", "E3", "G3"], "8n");\n *\n * @category Effect\n */\nclass Chorus extends (/* unused pure expression or super */ null && (StereoFeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]));\n this.name = "Chorus";\n const options = optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]);\n this._depth = options.depth;\n this._delayTime = options.delayTime / 1000;\n this._lfoL = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n });\n this._lfoR = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n phase: 180\n });\n this._delayNodeL = new Delay({ context: this.context });\n this._delayNodeR = new Delay({ context: this.context });\n this.frequency = this._lfoL.frequency;\n readOnly(this, ["frequency"]);\n // have one LFO frequency control the other\n this._lfoL.frequency.connect(this._lfoR.frequency);\n // connections\n this.connectEffectLeft(this._delayNodeL);\n this.connectEffectRight(this._delayNodeR);\n // lfo setup\n this._lfoL.connect(this._delayNodeL.delayTime);\n this._lfoR.connect(this._delayNodeR.delayTime);\n // set the initial values\n this.depth = this._depth;\n this.type = options.type;\n this.spread = options.spread;\n }\n static getDefaults() {\n return Object.assign(StereoFeedbackEffect.getDefaults(), {\n frequency: 1.5,\n delayTime: 3.5,\n depth: 0.7,\n type: "sine",\n spread: 180,\n feedback: 0,\n wet: 0.5,\n });\n }\n /**\n * The depth of the effect. A depth of 1 makes the delayTime\n * modulate between 0 and 2*delayTime (centered around the delayTime).\n */\n get depth() {\n return this._depth;\n }\n set depth(depth) {\n this._depth = depth;\n const deviation = this._delayTime * depth;\n this._lfoL.min = Math.max(this._delayTime - deviation, 0);\n this._lfoL.max = this._delayTime + deviation;\n this._lfoR.min = Math.max(this._delayTime - deviation, 0);\n this._lfoR.max = this._delayTime + deviation;\n }\n /**\n * The delayTime in milliseconds of the chorus. A larger delayTime\n * will give a more pronounced effect. Nominal range a delayTime\n * is between 2 and 20ms.\n */\n get delayTime() {\n return this._delayTime * 1000;\n }\n set delayTime(delayTime) {\n this._delayTime = delayTime / 1000;\n this.depth = this._depth;\n }\n /**\n * The oscillator type of the LFO.\n */\n get type() {\n return this._lfoL.type;\n }\n set type(type) {\n this._lfoL.type = type;\n this._lfoR.type = type;\n }\n /**\n * Amount of stereo spread. When set to 0, both LFO\'s will be panned centrally.\n * When set to 180, LFO\'s will be panned hard left and right respectively.\n */\n get spread() {\n return this._lfoR.phase - this._lfoL.phase;\n }\n set spread(spread) {\n this._lfoL.phase = 90 - (spread / 2);\n this._lfoR.phase = (spread / 2) + 90;\n }\n /**\n * Start the effect.\n */\n start(time) {\n this._lfoL.start(time);\n this._lfoR.start(time);\n return this;\n }\n /**\n * Stop the lfo\n */\n stop(time) {\n this._lfoL.stop(time);\n this._lfoR.stop(time);\n return this;\n }\n /**\n * Sync the filter to the transport. See [[LFO.sync]]\n */\n sync() {\n this._lfoL.sync();\n this._lfoR.sync();\n return this;\n }\n /**\n * Unsync the filter from the transport.\n */\n unsync() {\n this._lfoL.unsync();\n this._lfoR.unsync();\n return this;\n }\n dispose() {\n super.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._delayNodeL.dispose();\n this._delayNodeR.dispose();\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Chorus.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Distortion.js\n\n\n\n/**\n * A simple distortion effect using Tone.WaveShaper.\n * Algorithm from [this stackoverflow answer](http://stackoverflow.com/a/22313408).\n *\n * @example\n * const dist = new Tone.Distortion(0.8).toDestination();\n * const fm = new Tone.FMSynth().connect(dist);\n * fm.triggerAttackRelease("A1", "8n");\n * @category Effect\n */\nclass Distortion extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]));\n this.name = "Distortion";\n const options = optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]);\n this._shaper = new WaveShaper({\n context: this.context,\n length: 4096,\n });\n this._distortion = options.distortion;\n this.connectEffect(this._shaper);\n this.distortion = options.distortion;\n this.oversample = options.oversample;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n distortion: 0.4,\n oversample: "none",\n });\n }\n /**\n * The amount of distortion. Nominal range is between 0 and 1.\n */\n get distortion() {\n return this._distortion;\n }\n set distortion(amount) {\n this._distortion = amount;\n const k = amount * 100;\n const deg = Math.PI / 180;\n this._shaper.setMap((x) => {\n if (Math.abs(x) < 0.001) {\n // should output 0 when input is 0\n return 0;\n }\n else {\n return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));\n }\n });\n }\n /**\n * The oversampling of the effect. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n this._shaper.oversample = oversampling;\n }\n dispose() {\n super.dispose();\n this._shaper.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Distortion.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FeedbackEffect.js\n\n\n\n/**\n * FeedbackEffect provides a loop between an audio source and its own output.\n * This is a base-class for feedback effects.\n */\nclass FeedbackEffect_FeedbackEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "FeedbackEffect";\n this._feedbackGain = new Gain({\n context: this.context,\n gain: options.feedback,\n units: "normalRange",\n });\n this.feedback = this._feedbackGain.gain;\n readOnly(this, "feedback");\n // the feedback loop\n this.effectReturn.chain(this._feedbackGain, this.effectSend);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n feedback: 0.125,\n });\n }\n dispose() {\n super.dispose();\n this._feedbackGain.dispose();\n this.feedback.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FeedbackDelay.js\n\n\n\n\n/**\n * FeedbackDelay is a DelayNode in which part of output signal is fed back into the delay.\n *\n * @param delayTime The delay applied to the incoming signal.\n * @param feedback The amount of the effected signal which is fed back through the delay.\n * @example\n * const feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toDestination();\n * const tom = new Tone.MembraneSynth({\n * \toctaves: 4,\n * \tpitchDecay: 0.1\n * }).connect(feedbackDelay);\n * tom.triggerAttackRelease("A2", "32n");\n * @category Effect\n */\nclass FeedbackDelay extends (/* unused pure expression or super */ null && (FeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]));\n this.name = "FeedbackDelay";\n const options = optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]);\n this._delayNode = new Delay({\n context: this.context,\n delayTime: options.delayTime,\n maxDelay: options.maxDelay,\n });\n this.delayTime = this._delayNode.delayTime;\n // connect it up\n this.connectEffect(this._delayNode);\n readOnly(this, "delayTime");\n }\n static getDefaults() {\n return Object.assign(FeedbackEffect.getDefaults(), {\n delayTime: 0.25,\n maxDelay: 1,\n });\n }\n dispose() {\n super.dispose();\n this._delayNode.dispose();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackDelay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/PhaseShiftAllpass.js\n\n\n/**\n * PhaseShiftAllpass is an very efficient implementation of a Hilbert Transform\n * using two Allpass filter banks whose outputs have a phase difference of 90°.\n * Here the `offset90` phase is offset by +90° in relation to `output`.\n * Coefficients and structure was developed by Olli Niemitalo.\n * For more details see: http://yehar.com/blog/?p=368\n * @category Component\n */\nclass PhaseShiftAllpass_PhaseShiftAllpass extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "PhaseShiftAllpass";\n this.input = new Gain({ context: this.context });\n /**\n * The phase shifted output\n */\n this.output = new Gain({ context: this.context });\n /**\n * The PhaseShifted allpass output\n */\n this.offset90 = new Gain({ context: this.context });\n const allpassBank1Values = [0.6923878, 0.9360654322959, 0.9882295226860, 0.9987488452737];\n const allpassBank2Values = [0.4021921162426, 0.8561710882420, 0.9722909545651, 0.9952884791278];\n this._bank0 = this._createAllPassFilterBank(allpassBank1Values);\n this._bank1 = this._createAllPassFilterBank(allpassBank2Values);\n this._oneSampleDelay = this.context.createIIRFilter([0.0, 1.0], [1.0, 0.0]);\n // connect Allpass filter banks\n connectSeries(this.input, ...this._bank0, this._oneSampleDelay, this.output);\n connectSeries(this.input, ...this._bank1, this.offset90);\n }\n /**\n * Create all of the IIR filters from an array of values using the coefficient calculation.\n */\n _createAllPassFilterBank(bankValues) {\n const nodes = bankValues.map(value => {\n const coefficients = [[value * value, 0, -1], [1, 0, -(value * value)]];\n return this.context.createIIRFilter(coefficients[0], coefficients[1]);\n });\n return nodes;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.offset90.dispose();\n this._bank0.forEach(f => f.disconnect());\n this._bank1.forEach(f => f.disconnect());\n this._oneSampleDelay.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=PhaseShiftAllpass.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FrequencyShifter.js\n\n\n\n\n\n\n\n\n\n/**\n * FrequencyShifter can be used to shift all frequencies of a signal by a fixed amount.\n * The amount can be changed at audio rate and the effect is applied in real time.\n * The frequency shifting is implemented with a technique called single side band modulation using a ring modulator.\n * Note: Contrary to pitch shifting, all frequencies are shifted by the same amount,\n * destroying the harmonic relationship between them. This leads to the classic ring modulator timbre distortion.\n * The algorithm will produces some aliasing towards the high end, especially if your source material\n * contains a lot of high frequencies. Unfortunatelly the webaudio API does not support resampling\n * buffers in real time, so it is not possible to fix it properly. Depending on the use case it might\n * be an option to low pass filter your input before frequency shifting it to get ride of the aliasing.\n * You can find a very detailed description of the algorithm here: https://larzeitlin.github.io/RMFS/\n *\n * @example\n * const input = new Tone.Oscillator(230, "sawtooth").start();\n * const shift = new Tone.FrequencyShifter(42).toDestination();\n * input.connect(shift);\n * @category Effect\n */\nclass FrequencyShifter extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]));\n this.name = "FrequencyShifter";\n const options = optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]);\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n minValue: -this.context.sampleRate / 2,\n maxValue: this.context.sampleRate / 2,\n });\n this._sine = new ToneOscillatorNode({\n context: this.context,\n type: "sine",\n });\n this._cosine = new Oscillator({\n context: this.context,\n phase: -90,\n type: "sine",\n });\n this._sineMultiply = new Multiply({ context: this.context });\n this._cosineMultiply = new Multiply({ context: this.context });\n this._negate = new Negate({ context: this.context });\n this._add = new Add({ context: this.context });\n this._phaseShifter = new PhaseShiftAllpass({ context: this.context });\n this.effectSend.connect(this._phaseShifter);\n // connect the carrier frequency signal to the two oscillators\n this.frequency.fan(this._sine.frequency, this._cosine.frequency);\n this._phaseShifter.offset90.connect(this._cosineMultiply);\n this._cosine.connect(this._cosineMultiply.factor);\n this._phaseShifter.connect(this._sineMultiply);\n this._sine.connect(this._sineMultiply.factor);\n this._sineMultiply.connect(this._negate);\n this._cosineMultiply.connect(this._add);\n this._negate.connect(this._add.addend);\n this._add.connect(this.effectReturn);\n // start the oscillators at the same time\n const now = this.immediate();\n this._sine.start(now);\n this._cosine.start(now);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n frequency: 0,\n });\n }\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this._add.dispose();\n this._cosine.dispose();\n this._cosineMultiply.dispose();\n this._negate.dispose();\n this._phaseShifter.dispose();\n this._sine.dispose();\n this._sineMultiply.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FrequencyShifter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Freeverb.js\n\n\n\n\n\n/**\n * An array of comb filter delay values from Freeverb implementation\n */\nconst combFilterTunings = (/* unused pure expression or super */ null && ([1557 / 44100, 1617 / 44100, 1491 / 44100, 1422 / 44100, 1277 / 44100, 1356 / 44100, 1188 / 44100, 1116 / 44100]));\n/**\n * An array of allpass filter frequency values from Freeverb implementation\n */\nconst allpassFilterFrequencies = (/* unused pure expression or super */ null && ([225, 556, 441, 341]));\n/**\n * Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html).\n * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp).\n * Freeverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]].\n * @example\n * const freeverb = new Tone.Freeverb().toDestination();\n * freeverb.dampening = 1000;\n * // routing synth through the reverb\n * const synth = new Tone.NoiseSynth().connect(freeverb);\n * synth.triggerAttackRelease(0.05);\n * @category Effect\n */\nclass Freeverb extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]));\n this.name = "Freeverb";\n /**\n * the comb filters\n */\n this._combFilters = [];\n /**\n * the allpass filters on the left\n */\n this._allpassFiltersL = [];\n /**\n * the allpass filters on the right\n */\n this._allpassFiltersR = [];\n const options = optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]);\n this.roomSize = new Signal({\n context: this.context,\n value: options.roomSize,\n units: "normalRange",\n });\n // make the allpass filters on the right\n this._allpassFiltersL = allpassFilterFrequencies.map(freq => {\n const allpassL = this.context.createBiquadFilter();\n allpassL.type = "allpass";\n allpassL.frequency.value = freq;\n return allpassL;\n });\n // make the allpass filters on the left\n this._allpassFiltersR = allpassFilterFrequencies.map(freq => {\n const allpassR = this.context.createBiquadFilter();\n allpassR.type = "allpass";\n allpassR.frequency.value = freq;\n return allpassR;\n });\n // make the comb filters\n this._combFilters = combFilterTunings.map((delayTime, index) => {\n const lfpf = new LowpassCombFilter({\n context: this.context,\n dampening: options.dampening,\n delayTime,\n });\n if (index < combFilterTunings.length / 2) {\n this.connectEffectLeft(lfpf, ...this._allpassFiltersL);\n }\n else {\n this.connectEffectRight(lfpf, ...this._allpassFiltersR);\n }\n this.roomSize.connect(lfpf.resonance);\n return lfpf;\n });\n readOnly(this, ["roomSize"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n roomSize: 0.7,\n dampening: 3000\n });\n }\n /**\n * The amount of dampening of the reverberant signal.\n */\n get dampening() {\n return this._combFilters[0].dampening;\n }\n set dampening(d) {\n this._combFilters.forEach(c => c.dampening = d);\n }\n dispose() {\n super.dispose();\n this._allpassFiltersL.forEach(al => al.disconnect());\n this._allpassFiltersR.forEach(ar => ar.disconnect());\n this._combFilters.forEach(cf => cf.dispose());\n this.roomSize.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Freeverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/JCReverb.js\n\n\n\n\n\n\n/**\n * an array of the comb filter delay time values\n */\nconst combFilterDelayTimes = (/* unused pure expression or super */ null && ([1687 / 25000, 1601 / 25000, 2053 / 25000, 2251 / 25000]));\n/**\n * the resonances of each of the comb filters\n */\nconst combFilterResonances = (/* unused pure expression or super */ null && ([0.773, 0.802, 0.753, 0.733]));\n/**\n * the allpass filter frequencies\n */\nconst allpassFilterFreqs = (/* unused pure expression or super */ null && ([347, 113, 37]));\n/**\n * JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html)\n * tuned by John Chowning in 1970.\n * It is made up of three allpass filters and four [[FeedbackCombFilter]].\n * JCReverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]].\n * @example\n * const reverb = new Tone.JCReverb(0.4).toDestination();\n * const delay = new Tone.FeedbackDelay(0.5);\n * // connecting the synth to reverb through delay\n * const synth = new Tone.DuoSynth().chain(delay, reverb);\n * synth.triggerAttackRelease("A4", "8n");\n *\n * @category Effect\n */\nclass JCReverb extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]));\n this.name = "JCReverb";\n /**\n * a series of allpass filters\n */\n this._allpassFilters = [];\n /**\n * parallel feedback comb filters\n */\n this._feedbackCombFilters = [];\n const options = optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]);\n this.roomSize = new Signal({\n context: this.context,\n value: options.roomSize,\n units: "normalRange",\n });\n this._scaleRoomSize = new Scale({\n context: this.context,\n min: -0.733,\n max: 0.197,\n });\n // make the allpass filters\n this._allpassFilters = allpassFilterFreqs.map(freq => {\n const allpass = this.context.createBiquadFilter();\n allpass.type = "allpass";\n allpass.frequency.value = freq;\n return allpass;\n });\n // and the comb filters\n this._feedbackCombFilters = combFilterDelayTimes.map((delayTime, index) => {\n const fbcf = new FeedbackCombFilter({\n context: this.context,\n delayTime,\n });\n this._scaleRoomSize.connect(fbcf.resonance);\n fbcf.resonance.value = combFilterResonances[index];\n if (index < combFilterDelayTimes.length / 2) {\n this.connectEffectLeft(...this._allpassFilters, fbcf);\n }\n else {\n this.connectEffectRight(...this._allpassFilters, fbcf);\n }\n return fbcf;\n });\n // chain the allpass filters together\n this.roomSize.connect(this._scaleRoomSize);\n readOnly(this, ["roomSize"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n roomSize: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this._allpassFilters.forEach(apf => apf.disconnect());\n this._feedbackCombFilters.forEach(fbcf => fbcf.dispose());\n this.roomSize.dispose();\n this._scaleRoomSize.dispose();\n return this;\n }\n}\n//# sourceMappingURL=JCReverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoXFeedbackEffect.js\n\n\n/**\n * Just like a [[StereoFeedbackEffect]], but the feedback is routed from left to right\n * and right to left instead of on the same channel.\n * ```\n * +--------------------------------+ feedbackL <-----------------------------------+\n * | |\n * +--\x3e +-----\x3e +----\x3e +-----+\n * feedbackMerge +--\x3e split (EFFECT) merge +--\x3e feedbackSplit | |\n * +--\x3e +-----\x3e +----\x3e +---+ |\n * | |\n * +--------------------------------+ feedbackR <-------------------------------------+\n * ```\n */\nclass StereoXFeedbackEffect_StereoXFeedbackEffect extends (/* unused pure expression or super */ null && (StereoFeedbackEffect)) {\n constructor(options) {\n super(options);\n // the left output connected to the right input\n this._feedbackL.disconnect();\n this._feedbackL.connect(this._feedbackMerge, 0, 1);\n // the left output connected to the right input\n this._feedbackR.disconnect();\n this._feedbackR.connect(this._feedbackMerge, 0, 0);\n readOnly(this, ["feedback"]);\n }\n}\n//# sourceMappingURL=StereoXFeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/PingPongDelay.js\n\n\n\n\n\n/**\n * PingPongDelay is a feedback delay effect where the echo is heard\n * first in one channel and next in the opposite channel. In a stereo\n * system these are the right and left channels.\n * PingPongDelay in more simplified terms is two Tone.FeedbackDelays\n * with independent delay values. Each delay is routed to one channel\n * (left or right), and the channel triggered second will always\n * trigger at the same interval after the first.\n * @example\n * const pingPong = new Tone.PingPongDelay("4n", 0.2).toDestination();\n * const drum = new Tone.MembraneSynth().connect(pingPong);\n * drum.triggerAttackRelease("C4", "32n");\n * @category Effect\n */\nclass PingPongDelay extends (/* unused pure expression or super */ null && (StereoXFeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]));\n this.name = "PingPongDelay";\n const options = optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]);\n this._leftDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay,\n });\n this._rightDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay\n });\n this._rightPreDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay\n });\n this.delayTime = new Signal({\n context: this.context,\n units: "time",\n value: options.delayTime,\n });\n // connect it up\n this.connectEffectLeft(this._leftDelay);\n this.connectEffectRight(this._rightPreDelay, this._rightDelay);\n this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime);\n // rearranged the feedback to be after the rightPreDelay\n this._feedbackL.disconnect();\n this._feedbackL.connect(this._rightDelay);\n readOnly(this, ["delayTime"]);\n }\n static getDefaults() {\n return Object.assign(StereoXFeedbackEffect.getDefaults(), {\n delayTime: 0.25,\n maxDelay: 1\n });\n }\n dispose() {\n super.dispose();\n this._leftDelay.dispose();\n this._rightDelay.dispose();\n this._rightPreDelay.dispose();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PingPongDelay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/PitchShift.js\n\n\n\n\n\n\n\n\n/**\n * PitchShift does near-realtime pitch shifting to the incoming signal.\n * The effect is achieved by speeding up or slowing down the delayTime\n * of a DelayNode using a sawtooth wave.\n * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf).\n * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html).\n * @category Effect\n */\nclass PitchShift extends (/* unused pure expression or super */ null && (FeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]));\n this.name = "PitchShift";\n const options = optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]);\n this._frequency = new Signal({ context: this.context });\n this._delayA = new Delay({\n maxDelay: 1,\n context: this.context\n });\n this._lfoA = new LFO({\n context: this.context,\n min: 0,\n max: 0.1,\n type: "sawtooth"\n }).connect(this._delayA.delayTime);\n this._delayB = new Delay({\n maxDelay: 1,\n context: this.context\n });\n this._lfoB = new LFO({\n context: this.context,\n min: 0,\n max: 0.1,\n type: "sawtooth",\n phase: 180\n }).connect(this._delayB.delayTime);\n this._crossFade = new CrossFade({ context: this.context });\n this._crossFadeLFO = new LFO({\n context: this.context,\n min: 0,\n max: 1,\n type: "triangle",\n phase: 90\n }).connect(this._crossFade.fade);\n this._feedbackDelay = new Delay({\n delayTime: options.delayTime,\n context: this.context,\n });\n this.delayTime = this._feedbackDelay.delayTime;\n readOnly(this, "delayTime");\n this._pitch = options.pitch;\n this._windowSize = options.windowSize;\n // connect the two delay lines up\n this._delayA.connect(this._crossFade.a);\n this._delayB.connect(this._crossFade.b);\n // connect the frequency\n this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency);\n // route the input\n this.effectSend.fan(this._delayA, this._delayB);\n this._crossFade.chain(this._feedbackDelay, this.effectReturn);\n // start the LFOs at the same time\n const now = this.now();\n this._lfoA.start(now);\n this._lfoB.start(now);\n this._crossFadeLFO.start(now);\n // set the initial value\n this.windowSize = this._windowSize;\n }\n static getDefaults() {\n return Object.assign(FeedbackEffect.getDefaults(), {\n pitch: 0,\n windowSize: 0.1,\n delayTime: 0,\n feedback: 0\n });\n }\n /**\n * Repitch the incoming signal by some interval (measured in semi-tones).\n * @example\n * const pitchShift = new Tone.PitchShift().toDestination();\n * const osc = new Tone.Oscillator().connect(pitchShift).start().toDestination();\n * pitchShift.pitch = -12; // down one octave\n * pitchShift.pitch = 7; // up a fifth\n */\n get pitch() {\n return this._pitch;\n }\n set pitch(interval) {\n this._pitch = interval;\n let factor = 0;\n if (interval < 0) {\n this._lfoA.min = 0;\n this._lfoA.max = this._windowSize;\n this._lfoB.min = 0;\n this._lfoB.max = this._windowSize;\n factor = intervalToFrequencyRatio(interval - 1) + 1;\n }\n else {\n this._lfoA.min = this._windowSize;\n this._lfoA.max = 0;\n this._lfoB.min = this._windowSize;\n this._lfoB.max = 0;\n factor = intervalToFrequencyRatio(interval) - 1;\n }\n this._frequency.value = factor * (1.2 / this._windowSize);\n }\n /**\n * The window size corresponds roughly to the sample length in a looping sampler.\n * Smaller values are desirable for a less noticeable delay time of the pitch shifted\n * signal, but larger values will result in smoother pitch shifting for larger intervals.\n * A nominal range of 0.03 to 0.1 is recommended.\n */\n get windowSize() {\n return this._windowSize;\n }\n set windowSize(size) {\n this._windowSize = this.toSeconds(size);\n this.pitch = this._pitch;\n }\n dispose() {\n super.dispose();\n this._frequency.dispose();\n this._delayA.dispose();\n this._delayB.dispose();\n this._lfoA.dispose();\n this._lfoB.dispose();\n this._crossFade.dispose();\n this._crossFadeLFO.dispose();\n this._feedbackDelay.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PitchShift.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Phaser.js\n\n\n\n\n\n/**\n * Phaser is a phaser effect. Phasers work by changing the phase\n * of different frequency components of an incoming signal. Read more on\n * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)).\n * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/).\n * @example\n * const phaser = new Tone.Phaser({\n * \tfrequency: 15,\n * \toctaves: 5,\n * \tbaseFrequency: 1000\n * }).toDestination();\n * const synth = new Tone.FMSynth().connect(phaser);\n * synth.triggerAttackRelease("E3", "2n");\n * @category Effect\n */\nclass Phaser extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]));\n this.name = "Phaser";\n const options = optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]);\n this._lfoL = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1\n });\n this._lfoR = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n phase: 180,\n });\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._octaves = options.octaves;\n this.Q = new Signal({\n context: this.context,\n value: options.Q,\n units: "positive",\n });\n this._filtersL = this._makeFilters(options.stages, this._lfoL);\n this._filtersR = this._makeFilters(options.stages, this._lfoR);\n this.frequency = this._lfoL.frequency;\n this.frequency.value = options.frequency;\n // connect them up\n this.connectEffectLeft(...this._filtersL);\n this.connectEffectRight(...this._filtersR);\n // control the frequency with one LFO\n this._lfoL.frequency.connect(this._lfoR.frequency);\n // set the options\n this.baseFrequency = options.baseFrequency;\n this.octaves = options.octaves;\n // start the lfo\n this._lfoL.start();\n this._lfoR.start();\n readOnly(this, ["frequency", "Q"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n frequency: 0.5,\n octaves: 3,\n stages: 10,\n Q: 10,\n baseFrequency: 350,\n });\n }\n _makeFilters(stages, connectToFreq) {\n const filters = [];\n // make all the filters\n for (let i = 0; i < stages; i++) {\n const filter = this.context.createBiquadFilter();\n filter.type = "allpass";\n this.Q.connect(filter.Q);\n connectToFreq.connect(filter.frequency);\n filters.push(filter);\n }\n return filters;\n }\n /**\n * The number of octaves the phase goes above the baseFrequency\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n const max = this._baseFrequency * Math.pow(2, octaves);\n this._lfoL.max = max;\n this._lfoR.max = max;\n }\n /**\n * The the base frequency of the filters.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(freq) {\n this._baseFrequency = this.toFrequency(freq);\n this._lfoL.min = this._baseFrequency;\n this._lfoR.min = this._baseFrequency;\n this.octaves = this._octaves;\n }\n dispose() {\n super.dispose();\n this.Q.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._filtersL.forEach(f => f.disconnect());\n this._filtersR.forEach(f => f.disconnect());\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Phaser.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Reverb.js\n\n\n\n\n\n\n\n\n\n/**\n * Simple convolution created with decaying noise.\n * Generates an Impulse Response Buffer\n * with Tone.Offline then feeds the IR into ConvolverNode.\n * The impulse response generation is async, so you have\n * to wait until [[ready]] resolves before it will make a sound.\n *\n * Inspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen).\n * Copyright (c) 2014 Alan deLespinasse Apache 2.0 License.\n *\n * @category Effect\n */\nclass Reverb extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]));\n this.name = "Reverb";\n /**\n * Convolver node\n */\n this._convolver = this.context.createConvolver();\n /**\n * Resolves when the reverb buffer is generated. Whenever either [[decay]]\n * or [[preDelay]] are set, you have to wait until [[ready]] resolves\n * before the IR is generated with the latest values.\n */\n this.ready = Promise.resolve();\n const options = optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]);\n this._decay = options.decay;\n this._preDelay = options.preDelay;\n this.generate();\n this.connectEffect(this._convolver);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n decay: 1.5,\n preDelay: 0.01,\n });\n }\n /**\n * The duration of the reverb.\n */\n get decay() {\n return this._decay;\n }\n set decay(time) {\n time = this.toSeconds(time);\n assertRange(time, 0.001);\n this._decay = time;\n this.generate();\n }\n /**\n * The amount of time before the reverb is fully ramped in.\n */\n get preDelay() {\n return this._preDelay;\n }\n set preDelay(time) {\n time = this.toSeconds(time);\n assertRange(time, 0);\n this._preDelay = time;\n this.generate();\n }\n /**\n * Generate the Impulse Response. Returns a promise while the IR is being generated.\n * @return Promise which returns this object.\n */\n generate() {\n return __awaiter(this, void 0, void 0, function* () {\n const previousReady = this.ready;\n // create a noise burst which decays over the duration in each channel\n const context = new OfflineContext(2, this._decay + this._preDelay, this.context.sampleRate);\n const noiseL = new Noise({ context });\n const noiseR = new Noise({ context });\n const merge = new Merge({ context });\n noiseL.connect(merge, 0, 0);\n noiseR.connect(merge, 0, 1);\n const gainNode = new Gain({ context }).toDestination();\n merge.connect(gainNode);\n noiseL.start(0);\n noiseR.start(0);\n // predelay\n gainNode.gain.setValueAtTime(0, 0);\n gainNode.gain.setValueAtTime(1, this._preDelay);\n // decay\n gainNode.gain.exponentialApproachValueAtTime(0, this._preDelay, this.decay);\n // render the buffer\n const renderPromise = context.render();\n this.ready = renderPromise.then(noOp);\n // wait for the previous `ready` to resolve\n yield previousReady;\n // set the buffer\n this._convolver.buffer = (yield renderPromise).get();\n return this;\n });\n }\n dispose() {\n super.dispose();\n this._convolver.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Reverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MidSideSplit.js\n\n\n\n\n\n\n/**\n * Mid/Side processing separates the the \'mid\' signal (which comes out of both the left and the right channel)\n * and the \'side\' (which only comes out of the the side channels).\n * ```\n * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right\n * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right\n * ```\n * @category Component\n */\nclass MidSideSplit_MidSideSplit extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MidSideSplit_MidSideSplit.getDefaults(), arguments));\n this.name = "MidSideSplit";\n this._split = this.input = new Split({\n channels: 2,\n context: this.context\n });\n this._midAdd = new Add({ context: this.context });\n this.mid = new Multiply({\n context: this.context,\n value: Math.SQRT1_2,\n });\n this._sideSubtract = new Subtract({ context: this.context });\n this.side = new Multiply({\n context: this.context,\n value: Math.SQRT1_2,\n });\n this._split.connect(this._midAdd, 0);\n this._split.connect(this._midAdd.addend, 1);\n this._split.connect(this._sideSubtract, 0);\n this._split.connect(this._sideSubtract.subtrahend, 1);\n this._midAdd.connect(this.mid);\n this._sideSubtract.connect(this.side);\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._midAdd.dispose();\n this._sideSubtract.dispose();\n this._split.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideSplit.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MidSideMerge.js\n\n\n\n\n\n\n\n/**\n * MidSideMerge merges the mid and side signal after they\'ve been separated by [[MidSideSplit]]\n * ```\n * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right\n * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right\n * ```\n * @category Component\n */\nclass MidSideMerge_MidSideMerge extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MidSideMerge_MidSideMerge.getDefaults(), arguments));\n this.name = "MidSideMerge";\n this.mid = new Gain({ context: this.context });\n this.side = new Gain({ context: this.context });\n this._left = new Add({ context: this.context });\n this._leftMult = new Multiply({\n context: this.context,\n value: Math.SQRT1_2\n });\n this._right = new Subtract({ context: this.context });\n this._rightMult = new Multiply({\n context: this.context,\n value: Math.SQRT1_2\n });\n this._merge = this.output = new Merge({ context: this.context });\n this.mid.fan(this._left);\n this.side.connect(this._left.addend);\n this.mid.connect(this._right);\n this.side.connect(this._right.subtrahend);\n this._left.connect(this._leftMult);\n this._right.connect(this._rightMult);\n this._leftMult.connect(this._merge, 0, 0);\n this._rightMult.connect(this._merge, 0, 1);\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._leftMult.dispose();\n this._rightMult.dispose();\n this._left.dispose();\n this._right.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideMerge.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/MidSideEffect.js\n\n\n\n/**\n * Mid/Side processing separates the the \'mid\' signal\n * (which comes out of both the left and the right channel)\n * and the \'side\' (which only comes out of the the side channels)\n * and effects them separately before being recombined.\n * Applies a Mid/Side seperation and recombination.\n * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n * This is a base-class for Mid/Side Effects.\n * @category Effect\n */\nclass MidSideEffect_MidSideEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "MidSideEffect";\n this._midSideMerge = new MidSideMerge({ context: this.context });\n this._midSideSplit = new MidSideSplit({ context: this.context });\n this._midSend = this._midSideSplit.mid;\n this._sideSend = this._midSideSplit.side;\n this._midReturn = this._midSideMerge.mid;\n this._sideReturn = this._midSideMerge.side;\n // the connections\n this.effectSend.connect(this._midSideSplit);\n this._midSideMerge.connect(this.effectReturn);\n }\n /**\n * Connect the mid chain of the effect\n */\n connectEffectMid(...nodes) {\n this._midSend.chain(...nodes, this._midReturn);\n }\n /**\n * Connect the side chain of the effect\n */\n connectEffectSide(...nodes) {\n this._sideSend.chain(...nodes, this._sideReturn);\n }\n dispose() {\n super.dispose();\n this._midSideSplit.dispose();\n this._midSideMerge.dispose();\n this._midSend.dispose();\n this._sideSend.dispose();\n this._midReturn.dispose();\n this._sideReturn.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoWidener.js\n\n\n\n\n\n\n\n/**\n * Applies a width factor to the mid/side seperation.\n * 0 is all mid and 1 is all side.\n * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n * ```\n * Mid *= 2*(1-width)<br>\n * Side *= 2*width\n * ```\n * @category Effect\n */\nclass StereoWidener extends (/* unused pure expression or super */ null && (MidSideEffect)) {\n constructor() {\n super(optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]));\n this.name = "StereoWidener";\n const options = optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]);\n this.width = new Signal({\n context: this.context,\n value: options.width,\n units: "normalRange",\n });\n readOnly(this, ["width"]);\n this._twoTimesWidthMid = new Multiply({\n context: this.context,\n value: 2,\n });\n this._twoTimesWidthSide = new Multiply({\n context: this.context,\n value: 2,\n });\n this._midMult = new Multiply({ context: this.context });\n this._twoTimesWidthMid.connect(this._midMult.factor);\n this.connectEffectMid(this._midMult);\n this._oneMinusWidth = new Subtract({ context: this.context });\n this._oneMinusWidth.connect(this._twoTimesWidthMid);\n connect(this.context.getConstant(1), this._oneMinusWidth);\n this.width.connect(this._oneMinusWidth.subtrahend);\n this._sideMult = new Multiply({ context: this.context });\n this.width.connect(this._twoTimesWidthSide);\n this._twoTimesWidthSide.connect(this._sideMult.factor);\n this.connectEffectSide(this._sideMult);\n }\n static getDefaults() {\n return Object.assign(MidSideEffect.getDefaults(), {\n width: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.width.dispose();\n this._midMult.dispose();\n this._sideMult.dispose();\n this._twoTimesWidthMid.dispose();\n this._twoTimesWidthSide.dispose();\n this._oneMinusWidth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoWidener.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Tremolo.js\n\n\n\n\n\n\n/**\n * Tremolo modulates the amplitude of an incoming signal using an [[LFO]].\n * The effect is a stereo effect where the modulation phase is inverted in each channel.\n *\n * @example\n * // create a tremolo and start it\'s LFO\n * const tremolo = new Tone.Tremolo(9, 0.75).toDestination().start();\n * // route an oscillator through the tremolo and start it\n * const oscillator = new Tone.Oscillator().connect(tremolo).start();\n *\n * @category Effect\n */\nclass Tremolo extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]));\n this.name = "Tremolo";\n const options = optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]);\n this._lfoL = new LFO({\n context: this.context,\n type: options.type,\n min: 1,\n max: 0,\n });\n this._lfoR = new LFO({\n context: this.context,\n type: options.type,\n min: 1,\n max: 0,\n });\n this._amplitudeL = new Gain({ context: this.context });\n this._amplitudeR = new Gain({ context: this.context });\n this.frequency = new Signal({\n context: this.context,\n value: options.frequency,\n units: "frequency",\n });\n this.depth = new Signal({\n context: this.context,\n value: options.depth,\n units: "normalRange",\n });\n readOnly(this, ["frequency", "depth"]);\n this.connectEffectLeft(this._amplitudeL);\n this.connectEffectRight(this._amplitudeR);\n this._lfoL.connect(this._amplitudeL.gain);\n this._lfoR.connect(this._amplitudeR.gain);\n this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency);\n this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude);\n this.spread = options.spread;\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n frequency: 10,\n type: "sine",\n depth: 0.5,\n spread: 180,\n });\n }\n /**\n * Start the tremolo.\n */\n start(time) {\n this._lfoL.start(time);\n this._lfoR.start(time);\n return this;\n }\n /**\n * Stop the tremolo.\n */\n stop(time) {\n this._lfoL.stop(time);\n this._lfoR.stop(time);\n return this;\n }\n /**\n * Sync the effect to the transport.\n */\n sync() {\n this._lfoL.sync();\n this._lfoR.sync();\n this.context.transport.syncSignal(this.frequency);\n return this;\n }\n /**\n * Unsync the filter from the transport\n */\n unsync() {\n this._lfoL.unsync();\n this._lfoR.unsync();\n this.context.transport.unsyncSignal(this.frequency);\n return this;\n }\n /**\n * The oscillator type.\n */\n get type() {\n return this._lfoL.type;\n }\n set type(type) {\n this._lfoL.type = type;\n this._lfoR.type = type;\n }\n /**\n * Amount of stereo spread. When set to 0, both LFO\'s will be panned centrally.\n * When set to 180, LFO\'s will be panned hard left and right respectively.\n */\n get spread() {\n return this._lfoR.phase - this._lfoL.phase; // 180\n }\n set spread(spread) {\n this._lfoL.phase = 90 - (spread / 2);\n this._lfoR.phase = (spread / 2) + 90;\n }\n dispose() {\n super.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._amplitudeL.dispose();\n this._amplitudeR.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Tremolo.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Vibrato.js\n\n\n\n\n\n/**\n * A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO\n * modulates the delayTime of the delay, causing the pitch to rise and fall.\n * @category Effect\n */\nclass Vibrato extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]));\n this.name = "Vibrato";\n const options = optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]);\n this._delayNode = new Delay({\n context: this.context,\n delayTime: 0,\n maxDelay: options.maxDelay,\n });\n this._lfo = new LFO({\n context: this.context,\n type: options.type,\n min: 0,\n max: options.maxDelay,\n frequency: options.frequency,\n phase: -90 // offse the phase so the resting position is in the center\n }).start().connect(this._delayNode.delayTime);\n this.frequency = this._lfo.frequency;\n this.depth = this._lfo.amplitude;\n this.depth.value = options.depth;\n readOnly(this, ["frequency", "depth"]);\n this.effectSend.chain(this._delayNode, this.effectReturn);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n maxDelay: 0.005,\n frequency: 5,\n depth: 0.1,\n type: "sine"\n });\n }\n /**\n * Type of oscillator attached to the Vibrato.\n */\n get type() {\n return this._lfo.type;\n }\n set type(type) {\n this._lfo.type = type;\n }\n dispose() {\n super.dispose();\n this._delayNode.dispose();\n this._lfo.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Vibrato.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Analyser.js\n\n\n\n\n\n/**\n * Wrapper around the native Web Audio\'s [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).\n * Extracts FFT or Waveform data from the incoming signal.\n * @category Component\n */\nclass Analyser_Analyser extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Analyser_Analyser.getDefaults(), arguments, ["type", "size"]));\n this.name = "Analyser";\n /**\n * The analyser node.\n */\n this._analysers = [];\n /**\n * The buffer that the FFT data is written to\n */\n this._buffers = [];\n const options = optionsFromArguments(Analyser_Analyser.getDefaults(), arguments, ["type", "size"]);\n this.input = this.output = this._gain = new Gain({ context: this.context });\n this._split = new Split({\n context: this.context,\n channels: options.channels,\n });\n this.input.connect(this._split);\n assertRange(options.channels, 1);\n // create the analysers\n for (let channel = 0; channel < options.channels; channel++) {\n this._analysers[channel] = this.context.createAnalyser();\n this._split.connect(this._analysers[channel], channel, 0);\n }\n // set the values initially\n this.size = options.size;\n this.type = options.type;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n size: 1024,\n smoothing: 0.8,\n type: "fft",\n channels: 1,\n });\n }\n /**\n * Run the analysis given the current settings. If [[channels]] = 1,\n * it will return a Float32Array. If [[channels]] > 1, it will\n * return an array of Float32Arrays where each index in the array\n * represents the analysis done on a channel.\n */\n getValue() {\n this._analysers.forEach((analyser, index) => {\n const buffer = this._buffers[index];\n if (this._type === "fft") {\n analyser.getFloatFrequencyData(buffer);\n }\n else if (this._type === "waveform") {\n analyser.getFloatTimeDomainData(buffer);\n }\n });\n if (this.channels === 1) {\n return this._buffers[0];\n }\n else {\n return this._buffers;\n }\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n */\n get size() {\n return this._analysers[0].frequencyBinCount;\n }\n set size(size) {\n this._analysers.forEach((analyser, index) => {\n analyser.fftSize = size * 2;\n this._buffers[index] = new Float32Array(size);\n });\n }\n /**\n * The number of channels the analyser does the analysis on. Channel\n * separation is done using [[Split]]\n */\n get channels() {\n return this._analysers.length;\n }\n /**\n * The analysis function returned by analyser.getValue(), either "fft" or "waveform".\n */\n get type() {\n return this._type;\n }\n set type(type) {\n assert(type === "waveform" || type === "fft", `Analyser: invalid type: ${type}`);\n this._type = type;\n }\n /**\n * 0 represents no time averaging with the last analysis frame.\n */\n get smoothing() {\n return this._analysers[0].smoothingTimeConstant;\n }\n set smoothing(val) {\n this._analysers.forEach(a => a.smoothingTimeConstant = val);\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._analysers.forEach(a => a.disconnect());\n this._split.dispose();\n this._gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Analyser.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/MeterBase.js\n\n\n\n/**\n * The base class for Metering classes.\n */\nclass MeterBase_MeterBase extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MeterBase_MeterBase.getDefaults(), arguments));\n this.name = "MeterBase";\n this.input = this.output = this._analyser = new Analyser({\n context: this.context,\n size: 256,\n type: "waveform",\n });\n }\n dispose() {\n super.dispose();\n this._analyser.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MeterBase.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Meter.js\n\n\n\n\n\n/**\n * Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)\n * of an input signal. It can also get the raw value of the input signal.\n *\n * @example\n * const meter = new Tone.Meter();\n * const mic = new Tone.UserMedia();\n * mic.open();\n * // connect mic to the meter\n * mic.connect(meter);\n * // the current level of the mic\n * setInterval(() => console.log(meter.getValue()), 100);\n * @category Component\n */\nclass Meter extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]));\n this.name = "Meter";\n /**\n * The previous frame\'s value\n */\n this._rms = 0;\n const options = optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]);\n this.input = this.output = this._analyser = new Analyser({\n context: this.context,\n size: 256,\n type: "waveform",\n channels: options.channels,\n });\n this.smoothing = options.smoothing,\n this.normalRange = options.normalRange;\n }\n static getDefaults() {\n return Object.assign(MeterBase.getDefaults(), {\n smoothing: 0.8,\n normalRange: false,\n channels: 1,\n });\n }\n /**\n * Use [[getValue]] instead. For the previous getValue behavior, use DCMeter.\n * @deprecated\n */\n getLevel() {\n warn("\'getLevel\' has been changed to \'getValue\'");\n return this.getValue();\n }\n /**\n * Get the current value of the incoming signal.\n * Output is in decibels when [[normalRange]] is `false`.\n * If [[channels]] = 1, then the output is a single number\n * representing the value of the input signal. When [[channels]] > 1,\n * then each channel is returned as a value in a number array.\n */\n getValue() {\n const aValues = this._analyser.getValue();\n const channelValues = this.channels === 1 ? [aValues] : aValues;\n const vals = channelValues.map(values => {\n const totalSquared = values.reduce((total, current) => total + current * current, 0);\n const rms = Math.sqrt(totalSquared / values.length);\n // the rms can only fall at the rate of the smoothing\n // but can jump up instantly\n this._rms = Math.max(rms, this._rms * this.smoothing);\n return this.normalRange ? this._rms : gainToDb(this._rms);\n });\n if (this.channels === 1) {\n return vals[0];\n }\n else {\n return vals;\n }\n }\n /**\n * The number of channels of analysis.\n */\n get channels() {\n return this._analyser.channels;\n }\n dispose() {\n super.dispose();\n this._analyser.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Meter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/FFT.js\n\n\n\n\n\n/**\n * Get the current frequency data of the connected audio source using a fast Fourier transform.\n * @category Component\n */\nclass FFT extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(FFT.getDefaults(), arguments, ["size"]));\n this.name = "FFT";\n const options = optionsFromArguments(FFT.getDefaults(), arguments, ["size"]);\n this.normalRange = options.normalRange;\n this._analyser.type = "fft";\n this.size = options.size;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n normalRange: false,\n size: 1024,\n smoothing: 0.8,\n });\n }\n /**\n * Gets the current frequency data from the connected audio source.\n * Returns the frequency data of length [[size]] as a Float32Array of decibel values.\n */\n getValue() {\n const values = this._analyser.getValue();\n return values.map(v => this.normalRange ? dbToGain(v) : v);\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n * Determines the size of the array returned by [[getValue]] (i.e. the number of\n * frequency bins). Large FFT sizes may be costly to compute.\n */\n get size() {\n return this._analyser.size;\n }\n set size(size) {\n this._analyser.size = size;\n }\n /**\n * 0 represents no time averaging with the last analysis frame.\n */\n get smoothing() {\n return this._analyser.smoothing;\n }\n set smoothing(val) {\n this._analyser.smoothing = val;\n }\n /**\n * Returns the frequency value in hertz of each of the indices of the FFT\'s [[getValue]] response.\n * @example\n * const fft = new Tone.FFT(32);\n * console.log([0, 1, 2, 3, 4].map(index => fft.getFrequencyOfIndex(index)));\n */\n getFrequencyOfIndex(index) {\n assert(0 <= index && index < this.size, `index must be greater than or equal to 0 and less than ${this.size}`);\n return index * this.context.sampleRate / (this.size * 2);\n }\n}\n//# sourceMappingURL=FFT.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/DCMeter.js\n\n\n/**\n * DCMeter gets the raw value of the input signal at the current time.\n *\n * @example\n * const meter = new Tone.DCMeter();\n * const mic = new Tone.UserMedia();\n * mic.open();\n * // connect mic to the meter\n * mic.connect(meter);\n * // the current level of the mic\n * const level = meter.getValue();\n * @category Component\n */\nclass DCMeter extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(DCMeter.getDefaults(), arguments));\n this.name = "DCMeter";\n this._analyser.type = "waveform";\n this._analyser.size = 256;\n }\n /**\n * Get the signal value of the incoming signal\n */\n getValue() {\n const value = this._analyser.getValue();\n return value[0];\n }\n}\n//# sourceMappingURL=DCMeter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Waveform.js\n\n\n/**\n * Get the current waveform data of the connected audio source.\n * @category Component\n */\nclass Waveform extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]));\n this.name = "Waveform";\n const options = optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]);\n this._analyser.type = "waveform";\n this.size = options.size;\n }\n static getDefaults() {\n return Object.assign(MeterBase.getDefaults(), {\n size: 1024,\n });\n }\n /**\n * Return the waveform for the current time as a Float32Array where each value in the array\n * represents a sample in the waveform.\n */\n getValue() {\n return this._analyser.getValue();\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n * Determines the size of the array returned by [[getValue]].\n */\n get size() {\n return this._analyser.size;\n }\n set size(size) {\n this._analyser.size = size;\n }\n}\n//# sourceMappingURL=Waveform.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Solo.js\n\n\n\n/**\n * Solo lets you isolate a specific audio stream. When an instance is set to `solo=true`,\n * it will mute all other instances of Solo.\n * @example\n * const soloA = new Tone.Solo().toDestination();\n * const oscA = new Tone.Oscillator("C4", "sawtooth").connect(soloA);\n * const soloB = new Tone.Solo().toDestination();\n * const oscB = new Tone.Oscillator("E4", "square").connect(soloB);\n * soloA.solo = true;\n * // no audio will pass through soloB\n * @category Component\n */\nclass Solo extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]));\n this.name = "Solo";\n const options = Defaults_optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]);\n this.input = this.output = new Gain_Gain({\n context: this.context,\n });\n if (!Solo._allSolos.has(this.context)) {\n Solo._allSolos.set(this.context, new Set());\n }\n Solo._allSolos.get(this.context).add(this);\n // set initially\n this.solo = options.solo;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n solo: false,\n });\n }\n /**\n * Isolates this instance and mutes all other instances of Solo.\n * Only one instance can be soloed at a time. A soloed\n * instance will report `solo=false` when another instance is soloed.\n */\n get solo() {\n return this._isSoloed();\n }\n set solo(solo) {\n if (solo) {\n this._addSolo();\n }\n else {\n this._removeSolo();\n }\n Solo._allSolos.get(this.context).forEach(instance => instance._updateSolo());\n }\n /**\n * If the current instance is muted, i.e. another instance is soloed\n */\n get muted() {\n return this.input.gain.value === 0;\n }\n /**\n * Add this to the soloed array\n */\n _addSolo() {\n if (!Solo._soloed.has(this.context)) {\n Solo._soloed.set(this.context, new Set());\n }\n Solo._soloed.get(this.context).add(this);\n }\n /**\n * Remove this from the soloed array\n */\n _removeSolo() {\n if (Solo._soloed.has(this.context)) {\n Solo._soloed.get(this.context).delete(this);\n }\n }\n /**\n * Is this on the soloed array\n */\n _isSoloed() {\n return Solo._soloed.has(this.context) && Solo._soloed.get(this.context).has(this);\n }\n /**\n * Returns true if no one is soloed\n */\n _noSolos() {\n // either does not have any soloed added\n return !Solo._soloed.has(this.context) ||\n // or has a solo set but doesn\'t include any items\n (Solo._soloed.has(this.context) && Solo._soloed.get(this.context).size === 0);\n }\n /**\n * Solo the current instance and unsolo all other instances.\n */\n _updateSolo() {\n if (this._isSoloed()) {\n this.input.gain.value = 1;\n }\n else if (this._noSolos()) {\n // no one is soloed\n this.input.gain.value = 1;\n }\n else {\n this.input.gain.value = 0;\n }\n }\n dispose() {\n super.dispose();\n Solo._allSolos.get(this.context).delete(this);\n this._removeSolo();\n return this;\n }\n}\n/**\n * Hold all of the solo\'ed tracks belonging to a specific context\n */\nSolo._allSolos = new Map();\n/**\n * Hold the currently solo\'ed instance(s)\n */\nSolo._soloed = new Map();\n//# sourceMappingURL=Solo.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/PanVol.js\n\n\n\n\n\n/**\n * PanVol is a Tone.Panner and Tone.Volume in one.\n * @example\n * // pan the incoming signal left and drop the volume\n * const panVol = new Tone.PanVol(-0.25, -12).toDestination();\n * const osc = new Tone.Oscillator().connect(panVol).start();\n * @category Component\n */\nclass PanVol extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]));\n this.name = "PanVol";\n const options = Defaults_optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]);\n this._panner = this.input = new Panner_Panner({\n context: this.context,\n pan: options.pan,\n channelCount: options.channelCount,\n });\n this.pan = this._panner.pan;\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n // connections\n this._panner.connect(this._volume);\n this.mute = options.mute;\n Interface_readOnly(this, ["pan", "volume"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n pan: 0,\n volume: 0,\n channelCount: 1,\n });\n }\n /**\n * Mute/unmute the volume\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n dispose() {\n super.dispose();\n this._panner.dispose();\n this.pan.dispose();\n this._volume.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PanVol.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Channel.js\n\n\n\n\n\n\n/**\n * Channel provides a channel strip interface with volume, pan, solo and mute controls.\n * See [[PanVol]] and [[Solo]]\n * @example\n * // pan the incoming signal left and drop the volume 12db\n * const channel = new Tone.Channel(-0.25, -12);\n * @category Component\n */\nclass Channel extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]));\n this.name = "Channel";\n const options = Defaults_optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]);\n this._solo = this.input = new Solo({\n solo: options.solo,\n context: this.context,\n });\n this._panVol = this.output = new PanVol({\n context: this.context,\n pan: options.pan,\n volume: options.volume,\n mute: options.mute,\n channelCount: options.channelCount\n });\n this.pan = this._panVol.pan;\n this.volume = this._panVol.volume;\n this._solo.connect(this._panVol);\n Interface_readOnly(this, ["pan", "volume"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n pan: 0,\n volume: 0,\n mute: false,\n solo: false,\n channelCount: 1,\n });\n }\n /**\n * Solo/unsolo the channel. Soloing is only relative to other [[Channels]] and [[Solo]] instances\n */\n get solo() {\n return this._solo.solo;\n }\n set solo(solo) {\n this._solo.solo = solo;\n }\n /**\n * If the current instance is muted, i.e. another instance is soloed,\n * or the channel is muted\n */\n get muted() {\n return this._solo.muted || this.mute;\n }\n /**\n * Mute/unmute the volume\n */\n get mute() {\n return this._panVol.mute;\n }\n set mute(mute) {\n this._panVol.mute = mute;\n }\n /**\n * Get the gain node belonging to the bus name. Create it if\n * it doesn\'t exist\n * @param name The bus name\n */\n _getBus(name) {\n if (!Channel.buses.has(name)) {\n Channel.buses.set(name, new Gain_Gain({ context: this.context }));\n }\n return Channel.buses.get(name);\n }\n /**\n * Send audio to another channel using a string. `send` is a lot like\n * [[connect]], except it uses a string instead of an object. This can\n * be useful in large applications to decouple sections since [[send]]\n * and [[receive]] can be invoked separately in order to connect an object\n * @param name The channel name to send the audio\n * @param volume The amount of the signal to send.\n * \tDefaults to 0db, i.e. send the entire signal\n * @returns Returns the gain node of this connection.\n */\n send(name, volume = 0) {\n const bus = this._getBus(name);\n const sendKnob = new Gain_Gain({\n context: this.context,\n units: "decibels",\n gain: volume,\n });\n this.connect(sendKnob);\n sendKnob.connect(bus);\n return sendKnob;\n }\n /**\n * Receive audio from a channel which was connected with [[send]].\n * @param name The channel name to receive audio from.\n */\n receive(name) {\n const bus = this._getBus(name);\n bus.connect(this);\n return this;\n }\n dispose() {\n super.dispose();\n this._panVol.dispose();\n this.pan.dispose();\n this.volume.dispose();\n this._solo.dispose();\n return this;\n }\n}\n/**\n * Store the send/receive channels by name.\n */\nChannel.buses = new Map();\n//# sourceMappingURL=Channel.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Mono.js\n\n\n\n\n/**\n * Mono coerces the incoming mono or stereo signal into a mono signal\n * where both left and right channels have the same value. This can be useful\n * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging).\n * @category Component\n */\nclass Mono extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Mono.getDefaults(), arguments));\n this.name = "Mono";\n this.input = new Gain({ context: this.context });\n this._merge = this.output = new Merge({\n channels: 2,\n context: this.context,\n });\n this.input.connect(this._merge, 0, 0);\n this.input.connect(this._merge, 0, 1);\n }\n dispose() {\n super.dispose();\n this._merge.dispose();\n this.input.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Mono.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MultibandSplit.js\n\n\n\n\n\n\n/**\n * Split the incoming signal into three bands (low, mid, high)\n * with two crossover frequency controls.\n * ```\n * +----------------------+\n * +-> input < lowFrequency +------------------\x3e low\n * | +----------------------+\n * |\n * | +--------------------------------------+\n * input ---+-> lowFrequency < input < highFrequency +--\x3e mid\n * | +--------------------------------------+\n * |\n * | +-----------------------+\n * +-> highFrequency < input +-----------------\x3e high\n * +-----------------------+\n * ```\n * @category Component\n */\nclass MultibandSplit_MultibandSplit extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MultibandSplit_MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]));\n this.name = "MultibandSplit";\n /**\n * the input\n */\n this.input = new Gain({ context: this.context });\n /**\n * no output node, use either low, mid or high outputs\n */\n this.output = undefined;\n /**\n * The low band.\n */\n this.low = new Filter({\n context: this.context,\n frequency: 0,\n type: "lowpass",\n });\n /**\n * the lower filter of the mid band\n */\n this._lowMidFilter = new Filter({\n context: this.context,\n frequency: 0,\n type: "highpass",\n });\n /**\n * The mid band output.\n */\n this.mid = new Filter({\n context: this.context,\n frequency: 0,\n type: "lowpass",\n });\n /**\n * The high band output.\n */\n this.high = new Filter({\n context: this.context,\n frequency: 0,\n type: "highpass",\n });\n this._internalChannels = [this.low, this.mid, this.high];\n const options = optionsFromArguments(MultibandSplit_MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]);\n this.lowFrequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.lowFrequency,\n });\n this.highFrequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.highFrequency,\n });\n this.Q = new Signal({\n context: this.context,\n units: "positive",\n value: options.Q,\n });\n this.input.fan(this.low, this.high);\n this.input.chain(this._lowMidFilter, this.mid);\n // the frequency control signal\n this.lowFrequency.fan(this.low.frequency, this._lowMidFilter.frequency);\n this.highFrequency.fan(this.mid.frequency, this.high.frequency);\n // the Q value\n this.Q.connect(this.low.Q);\n this.Q.connect(this._lowMidFilter.Q);\n this.Q.connect(this.mid.Q);\n this.Q.connect(this.high.Q);\n readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n highFrequency: 2500,\n lowFrequency: 400,\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n writable(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n this.low.dispose();\n this._lowMidFilter.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.lowFrequency.dispose();\n this.highFrequency.dispose();\n this.Q.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MultibandSplit.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Listener.js\n\n\n\n/**\n * Tone.Listener is a thin wrapper around the AudioListener. Listener combined\n * with [[Panner3D]] makes up the Web Audio API\'s 3D panning system. Panner3D allows you\n * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from\n * a first-person perspective. There is only one listener per audio context.\n */\nclass Listener extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(...arguments);\n this.name = "Listener";\n this.positionX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionX,\n });\n this.positionY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionY,\n });\n this.positionZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionZ,\n });\n this.forwardX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardX,\n });\n this.forwardY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardY,\n });\n this.forwardZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardZ,\n });\n this.upX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upX,\n });\n this.upY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upY,\n });\n this.upZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upZ,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n forwardX: 0,\n forwardY: 0,\n forwardZ: -1,\n upX: 0,\n upY: 1,\n upZ: 0,\n });\n }\n dispose() {\n super.dispose();\n this.positionX.dispose();\n this.positionY.dispose();\n this.positionZ.dispose();\n this.forwardX.dispose();\n this.forwardY.dispose();\n this.forwardZ.dispose();\n this.upX.dispose();\n this.upY.dispose();\n this.upZ.dispose();\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.listener = new Listener({ context });\n});\nonContextClose(context => {\n context.listener.dispose();\n});\n//# sourceMappingURL=Listener.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Panner3D.js\n\n\n\n\n/**\n * A spatialized panner node which supports equalpower or HRTF panning.\n * @category Component\n */\nclass Panner3D extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]));\n this.name = "Panner3D";\n const options = optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]);\n this._panner = this.input = this.output = this.context.createPanner();\n // set some values\n this.panningModel = options.panningModel;\n this.maxDistance = options.maxDistance;\n this.distanceModel = options.distanceModel;\n this.coneOuterGain = options.coneOuterGain;\n this.coneOuterAngle = options.coneOuterAngle;\n this.coneInnerAngle = options.coneInnerAngle;\n this.refDistance = options.refDistance;\n this.rolloffFactor = options.rolloffFactor;\n this.positionX = new Param({\n context: this.context,\n param: this._panner.positionX,\n value: options.positionX,\n });\n this.positionY = new Param({\n context: this.context,\n param: this._panner.positionY,\n value: options.positionY,\n });\n this.positionZ = new Param({\n context: this.context,\n param: this._panner.positionZ,\n value: options.positionZ,\n });\n this.orientationX = new Param({\n context: this.context,\n param: this._panner.orientationX,\n value: options.orientationX,\n });\n this.orientationY = new Param({\n context: this.context,\n param: this._panner.orientationY,\n value: options.orientationY,\n });\n this.orientationZ = new Param({\n context: this.context,\n param: this._panner.orientationZ,\n value: options.orientationZ,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: "inverse",\n maxDistance: 10000,\n orientationX: 0,\n orientationY: 0,\n orientationZ: 0,\n panningModel: "equalpower",\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n refDistance: 1,\n rolloffFactor: 1,\n });\n }\n /**\n * Sets the position of the source in 3d space.\n */\n setPosition(x, y, z) {\n this.positionX.value = x;\n this.positionY.value = y;\n this.positionZ.value = z;\n return this;\n }\n /**\n * Sets the orientation of the source in 3d space.\n */\n setOrientation(x, y, z) {\n this.orientationX.value = x;\n this.orientationY.value = y;\n this.orientationZ.value = z;\n return this;\n }\n /**\n * The panning model. Either "equalpower" or "HRTF".\n */\n get panningModel() {\n return this._panner.panningModel;\n }\n set panningModel(val) {\n this._panner.panningModel = val;\n }\n /**\n * A reference distance for reducing volume as source move further from the listener\n */\n get refDistance() {\n return this._panner.refDistance;\n }\n set refDistance(val) {\n this._panner.refDistance = val;\n }\n /**\n * Describes how quickly the volume is reduced as source moves away from listener.\n */\n get rolloffFactor() {\n return this._panner.rolloffFactor;\n }\n set rolloffFactor(val) {\n this._panner.rolloffFactor = val;\n }\n /**\n * The distance model used by, "linear", "inverse", or "exponential".\n */\n get distanceModel() {\n return this._panner.distanceModel;\n }\n set distanceModel(val) {\n this._panner.distanceModel = val;\n }\n /**\n * The angle, in degrees, inside of which there will be no volume reduction\n */\n get coneInnerAngle() {\n return this._panner.coneInnerAngle;\n }\n set coneInnerAngle(val) {\n this._panner.coneInnerAngle = val;\n }\n /**\n * The angle, in degrees, outside of which the volume will be reduced\n * to a constant value of coneOuterGain\n */\n get coneOuterAngle() {\n return this._panner.coneOuterAngle;\n }\n set coneOuterAngle(val) {\n this._panner.coneOuterAngle = val;\n }\n /**\n * The gain outside of the coneOuterAngle\n */\n get coneOuterGain() {\n return this._panner.coneOuterGain;\n }\n set coneOuterGain(val) {\n this._panner.coneOuterGain = val;\n }\n /**\n * The maximum distance between source and listener,\n * after which the volume will not be reduced any further.\n */\n get maxDistance() {\n return this._panner.maxDistance;\n }\n set maxDistance(val) {\n this._panner.maxDistance = val;\n }\n dispose() {\n super.dispose();\n this._panner.disconnect();\n this.orientationX.dispose();\n this.orientationY.dispose();\n this.orientationZ.dispose();\n this.positionX.dispose();\n this.positionY.dispose();\n this.positionZ.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Panner3D.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Recorder.js\n\n\n\n\n\n\n/**\n * A wrapper around the MediaRecorder API. Unlike the rest of Tone.js, this module does not offer\n * any sample-accurate scheduling because it is not a feature of the MediaRecorder API.\n * This is only natively supported in Chrome and Firefox.\n * For a cross-browser shim, install (audio-recorder-polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].\n * @example\n * const recorder = new Tone.Recorder();\n * const synth = new Tone.Synth().connect(recorder);\n * // start recording\n * recorder.start();\n * // generate a few notes\n * synth.triggerAttackRelease("C3", 0.5);\n * synth.triggerAttackRelease("C4", 0.5, "+1");\n * synth.triggerAttackRelease("C5", 0.5, "+2");\n * // wait for the notes to end and stop the recording\n * setTimeout(async () => {\n * \t// the recorded audio is returned as a blob\n * \tconst recording = await recorder.stop();\n * \t// download the recording by creating an anchor element and blob url\n * \tconst url = URL.createObjectURL(recording);\n * \tconst anchor = document.createElement("a");\n * \tanchor.download = "recording.webm";\n * \tanchor.href = url;\n * \tanchor.click();\n * }, 4000);\n * @category Component\n */\nclass Recorder extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Recorder.getDefaults(), arguments));\n this.name = "Recorder";\n const options = optionsFromArguments(Recorder.getDefaults(), arguments);\n this.input = new Gain({\n context: this.context\n });\n assert(Recorder.supported, "Media Recorder API is not available");\n this._stream = this.context.createMediaStreamDestination();\n this.input.connect(this._stream);\n this._recorder = new MediaRecorder(this._stream.stream, {\n mimeType: options.mimeType\n });\n }\n static getDefaults() {\n return ToneAudioNode.getDefaults();\n }\n /**\n * The mime type is the format that the audio is encoded in. For Chrome\n * that is typically webm encoded as "vorbis".\n */\n get mimeType() {\n return this._recorder.mimeType;\n }\n /**\n * Test if your platform supports the Media Recorder API. If it\'s not available,\n * try installing this (polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].\n */\n static get supported() {\n return theWindow !== null && Reflect.has(theWindow, "MediaRecorder");\n }\n /**\n * Get the playback state of the Recorder, either "started", "stopped" or "paused"\n */\n get state() {\n if (this._recorder.state === "inactive") {\n return "stopped";\n }\n else if (this._recorder.state === "paused") {\n return "paused";\n }\n else {\n return "started";\n }\n }\n /**\n * Start the Recorder. Returns a promise which resolves\n * when the recorder has started.\n */\n start() {\n return __awaiter(this, void 0, void 0, function* () {\n assert(this.state !== "started", "Recorder is already started");\n const startPromise = new Promise(done => {\n const handleStart = () => {\n this._recorder.removeEventListener("start", handleStart, false);\n done();\n };\n this._recorder.addEventListener("start", handleStart, false);\n });\n this._recorder.start();\n return yield startPromise;\n });\n }\n /**\n * Stop the recorder. Returns a promise with the recorded content until this point\n * encoded as [[mimeType]]\n */\n stop() {\n return __awaiter(this, void 0, void 0, function* () {\n assert(this.state !== "stopped", "Recorder is not started");\n const dataPromise = new Promise(done => {\n const handleData = (e) => {\n this._recorder.removeEventListener("dataavailable", handleData, false);\n done(e.data);\n };\n this._recorder.addEventListener("dataavailable", handleData, false);\n });\n this._recorder.stop();\n return yield dataPromise;\n });\n }\n /**\n * Pause the recorder\n */\n pause() {\n assert(this.state === "started", "Recorder must be started");\n this._recorder.pause();\n return this;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this._stream.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Recorder.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Compressor.js\n\n\n\n\n/**\n * Compressor is a thin wrapper around the Web Audio\n * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface).\n * Compression reduces the volume of loud sounds or amplifies quiet sounds\n * by narrowing or "compressing" an audio signal\'s dynamic range.\n * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression).\n * @example\n * const comp = new Tone.Compressor(-30, 3);\n * @category Component\n */\nclass Compressor_Compressor extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Compressor_Compressor.getDefaults(), arguments, ["threshold", "ratio"]));\n this.name = "Compressor";\n /**\n * the compressor node\n */\n this._compressor = this.context.createDynamicsCompressor();\n this.input = this._compressor;\n this.output = this._compressor;\n const options = Defaults_optionsFromArguments(Compressor_Compressor.getDefaults(), arguments, ["threshold", "ratio"]);\n this.threshold = new Param_Param({\n minValue: this._compressor.threshold.minValue,\n maxValue: this._compressor.threshold.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.threshold,\n units: "decibels",\n value: options.threshold,\n });\n this.attack = new Param_Param({\n minValue: this._compressor.attack.minValue,\n maxValue: this._compressor.attack.maxValue,\n context: this.context,\n param: this._compressor.attack,\n units: "time",\n value: options.attack,\n });\n this.release = new Param_Param({\n minValue: this._compressor.release.minValue,\n maxValue: this._compressor.release.maxValue,\n context: this.context,\n param: this._compressor.release,\n units: "time",\n value: options.release,\n });\n this.knee = new Param_Param({\n minValue: this._compressor.knee.minValue,\n maxValue: this._compressor.knee.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.knee,\n units: "decibels",\n value: options.knee,\n });\n this.ratio = new Param_Param({\n minValue: this._compressor.ratio.minValue,\n maxValue: this._compressor.ratio.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.ratio,\n units: "positive",\n value: options.ratio,\n });\n // set the defaults\n Interface_readOnly(this, ["knee", "release", "attack", "ratio", "threshold"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n attack: 0.003,\n knee: 30,\n ratio: 12,\n release: 0.25,\n threshold: -24,\n });\n }\n /**\n * A read-only decibel value for metering purposes, representing the current amount of gain\n * reduction that the compressor is applying to the signal. If fed no signal the value will be 0 (no gain reduction).\n */\n get reduction() {\n return this._compressor.reduction;\n }\n dispose() {\n super.dispose();\n this._compressor.disconnect();\n this.attack.dispose();\n this.release.dispose();\n this.threshold.dispose();\n this.ratio.dispose();\n this.knee.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Compressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Gate.js\n\n\n\n\n\n\n/**\n * Gate only passes a signal through when the incoming\n * signal exceeds a specified threshold. It uses [[Follower]] to follow the ampltiude\n * of the incoming signal and compares it to the [[threshold]] value using [[GreaterThan]].\n *\n * @example\n * const gate = new Tone.Gate(-30, 0.2).toDestination();\n * const mic = new Tone.UserMedia().connect(gate);\n * // the gate will only pass through the incoming\n * // signal when it\'s louder than -30db\n * @category Component\n */\nclass Gate extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"])));\n this.name = "Gate";\n const options = optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"]);\n this._follower = new Follower({\n context: this.context,\n smoothing: options.smoothing,\n });\n this._gt = new GreaterThan({\n context: this.context,\n value: dbToGain(options.threshold),\n });\n this.input = new Gain({ context: this.context });\n this._gate = this.output = new Gain({ context: this.context });\n // connections\n this.input.connect(this._gate);\n // the control signal\n this.input.chain(this._follower, this._gt, this._gate.gain);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n smoothing: 0.1,\n threshold: -40\n });\n }\n /**\n * The threshold of the gate in decibels\n */\n get threshold() {\n return gainToDb(this._gt.value);\n }\n set threshold(thresh) {\n this._gt.value = dbToGain(thresh);\n }\n /**\n * The attack/decay speed of the gate. See [[Follower.smoothing]]\n */\n get smoothing() {\n return this._follower.smoothing;\n }\n set smoothing(smoothingTime) {\n this._follower.smoothing = smoothingTime;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this._follower.dispose();\n this._gt.dispose();\n this._gate.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Gate.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Limiter.js\n\n\n\n\n;\n/**\n * Limiter will limit the loudness of an incoming signal.\n * Under the hood it\'s composed of a [[Compressor]] with a fast attack\n * and release and max compression ratio.\n *\n * @example\n * const limiter = new Tone.Limiter(-20).toDestination();\n * const oscillator = new Tone.Oscillator().connect(limiter);\n * oscillator.start();\n * @category Component\n */\nclass Limiter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"])));\n this.name = "Limiter";\n const options = optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"]);\n this._compressor = this.input = this.output = new Compressor({\n context: this.context,\n ratio: 20,\n attack: 0.003,\n release: 0.01,\n threshold: options.threshold\n });\n this.threshold = this._compressor.threshold;\n readOnly(this, "threshold");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n threshold: -12\n });\n }\n /**\n * A read-only decibel value for metering purposes, representing the current amount of gain\n * reduction that the compressor is applying to the signal.\n */\n get reduction() {\n return this._compressor.reduction;\n }\n dispose() {\n super.dispose();\n this._compressor.dispose();\n this.threshold.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Limiter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/MidSideCompressor.js\n\n\n\n\n\n\n/**\n * MidSideCompressor applies two different compressors to the [[mid]]\n * and [[side]] signal components of the input. See [[MidSideSplit]] and [[MidSideMerge]].\n * @category Component\n */\nclass MidSideCompressor extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(MidSideCompressor.getDefaults(), arguments)));\n this.name = "MidSideCompressor";\n const options = optionsFromArguments(MidSideCompressor.getDefaults(), arguments);\n this._midSideSplit = this.input = new MidSideSplit({ context: this.context });\n this._midSideMerge = this.output = new MidSideMerge({ context: this.context });\n this.mid = new Compressor(Object.assign(options.mid, { context: this.context }));\n this.side = new Compressor(Object.assign(options.side, { context: this.context }));\n this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid);\n this._midSideSplit.side.chain(this.side, this._midSideMerge.side);\n readOnly(this, ["mid", "side"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n mid: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n side: {\n ratio: 6,\n threshold: -30,\n release: 0.25,\n attack: 0.03,\n knee: 10\n }\n });\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._midSideSplit.dispose();\n this._midSideMerge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideCompressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/MultibandCompressor.js\n\n\n\n\n\n\n/**\n * A compressor with separate controls over low/mid/high dynamics. See [[Compressor]] and [[MultibandSplit]]\n *\n * @example\n * const multiband = new Tone.MultibandCompressor({\n * \tlowFrequency: 200,\n * \thighFrequency: 1300,\n * \tlow: {\n * \t\tthreshold: -12\n * \t}\n * });\n * @category Component\n */\nclass MultibandCompressor extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(MultibandCompressor.getDefaults(), arguments)));\n this.name = "MultibandCompressor";\n const options = optionsFromArguments(MultibandCompressor.getDefaults(), arguments);\n this._splitter = this.input = new MultibandSplit({\n context: this.context,\n lowFrequency: options.lowFrequency,\n highFrequency: options.highFrequency\n });\n this.lowFrequency = this._splitter.lowFrequency;\n this.highFrequency = this._splitter.highFrequency;\n this.output = new Gain({ context: this.context });\n this.low = new Compressor(Object.assign(options.low, { context: this.context }));\n this.mid = new Compressor(Object.assign(options.mid, { context: this.context }));\n this.high = new Compressor(Object.assign(options.high, { context: this.context }));\n // connect the compressor\n this._splitter.low.chain(this.low, this.output);\n this._splitter.mid.chain(this.mid, this.output);\n this._splitter.high.chain(this.high, this.output);\n readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n lowFrequency: 250,\n highFrequency: 2000,\n low: {\n ratio: 6,\n threshold: -30,\n release: 0.25,\n attack: 0.03,\n knee: 10\n },\n mid: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n high: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n });\n }\n dispose() {\n super.dispose();\n this._splitter.dispose();\n this.low.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.output.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MultibandCompressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/EQ3.js\n\n\n\n\n\n/**\n * EQ3 provides 3 equalizer bins: Low/Mid/High.\n * @category Component\n */\nclass EQ3 extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]));\n this.name = "EQ3";\n /**\n * the output\n */\n this.output = new Gain({ context: this.context });\n this._internalChannels = [];\n const options = optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]);\n this.input = this._multibandSplit = new MultibandSplit({\n context: this.context,\n highFrequency: options.highFrequency,\n lowFrequency: options.lowFrequency,\n });\n this._lowGain = new Gain({\n context: this.context,\n gain: options.low,\n units: "decibels",\n });\n this._midGain = new Gain({\n context: this.context,\n gain: options.mid,\n units: "decibels",\n });\n this._highGain = new Gain({\n context: this.context,\n gain: options.high,\n units: "decibels",\n });\n this.low = this._lowGain.gain;\n this.mid = this._midGain.gain;\n this.high = this._highGain.gain;\n this.Q = this._multibandSplit.Q;\n this.lowFrequency = this._multibandSplit.lowFrequency;\n this.highFrequency = this._multibandSplit.highFrequency;\n // the frequency bands\n this._multibandSplit.low.chain(this._lowGain, this.output);\n this._multibandSplit.mid.chain(this._midGain, this.output);\n this._multibandSplit.high.chain(this._highGain, this.output);\n readOnly(this, ["low", "mid", "high", "lowFrequency", "highFrequency"]);\n this._internalChannels = [this._multibandSplit];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n high: 0,\n highFrequency: 2500,\n low: 0,\n lowFrequency: 400,\n mid: 0,\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n writable(this, ["low", "mid", "high", "lowFrequency", "highFrequency"]);\n this._multibandSplit.dispose();\n this.lowFrequency.dispose();\n this.highFrequency.dispose();\n this._lowGain.dispose();\n this._midGain.dispose();\n this._highGain.dispose();\n this.low.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.Q.dispose();\n return this;\n }\n}\n//# sourceMappingURL=EQ3.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/Convolver.js\n\n\n\n\n\n\n/**\n * Convolver is a wrapper around the Native Web Audio\n * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface).\n * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on\n * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb).\n *\n * @example\n * // initializing the convolver with an impulse response\n * const convolver = new Tone.Convolver("./path/to/ir.wav").toDestination();\n * @category Component\n */\nclass Convolver extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]));\n this.name = "Convolver";\n /**\n * The native ConvolverNode\n */\n this._convolver = this.context.createConvolver();\n const options = optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]);\n this._buffer = new ToneAudioBuffer(options.url, buffer => {\n this.buffer = buffer;\n options.onload();\n });\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n // set if it\'s already loaded, set it immediately\n if (this._buffer.loaded) {\n this.buffer = this._buffer;\n }\n // initially set normalization\n this.normalize = options.normalize;\n // connect it up\n this.input.chain(this._convolver, this.output);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n normalize: true,\n onload: noOp,\n });\n }\n /**\n * Load an impulse response url as an audio buffer.\n * Decodes the audio asynchronously and invokes\n * the callback once the audio buffer loads.\n * @param url The url of the buffer to load. filetype support depends on the browser.\n */\n load(url) {\n return __awaiter(this, void 0, void 0, function* () {\n this.buffer = yield this._buffer.load(url);\n });\n }\n /**\n * The convolver\'s buffer\n */\n get buffer() {\n if (this._buffer.length) {\n return this._buffer;\n }\n else {\n return null;\n }\n }\n set buffer(buffer) {\n if (buffer) {\n this._buffer.set(buffer);\n }\n // if it\'s already got a buffer, create a new one\n if (this._convolver.buffer) {\n // disconnect the old one\n this.input.disconnect();\n this._convolver.disconnect();\n // create and connect a new one\n this._convolver = this.context.createConvolver();\n this.input.chain(this._convolver, this.output);\n }\n const buff = this._buffer.get();\n this._convolver.buffer = buff ? buff : null;\n }\n /**\n * The normalize property of the ConvolverNode interface is a boolean that\n * controls whether the impulse response from the buffer will be scaled by\n * an equal-power normalization when the buffer attribute is set, or not.\n */\n get normalize() {\n return this._convolver.normalize;\n }\n set normalize(norm) {\n this._convolver.normalize = norm;\n }\n dispose() {\n super.dispose();\n this._buffer.dispose();\n this._convolver.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Convolver.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/classes.js\n\n\n\n\n\n\n\n//# sourceMappingURL=classes.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/index.js\n\n\n\n\n\n\n\n/**\n * The current audio context time of the global [[Context]].\n * See [[Context.now]]\n * @category Core\n */\nfunction now() {\n return getContext().now();\n}\n/**\n * The current audio context time of the global [[Context]] without the [[Context.lookAhead]]\n * See [[Context.immediate]]\n * @category Core\n */\nfunction immediate() {\n return getContext().immediate();\n}\n/**\n * The Transport object belonging to the global Tone.js Context.\n * See [[Transport]]\n * @category Core\n */\nconst esm_Transport = Global_getContext().transport;\n/**\n * The Transport object belonging to the global Tone.js Context.\n * See [[Transport]]\n * @category Core\n */\nfunction getTransport() {\n return getContext().transport;\n}\n/**\n * The Destination (output) belonging to the global Tone.js Context.\n * See [[Destination]]\n * @category Core\n */\nconst esm_Destination = Global_getContext().destination;\n/**\n * @deprecated Use [[Destination]]\n */\nconst Master = Global_getContext().destination;\n/**\n * The Destination (output) belonging to the global Tone.js Context.\n * See [[Destination]]\n * @category Core\n */\nfunction getDestination() {\n return getContext().destination;\n}\n/**\n * The [[Listener]] belonging to the global Tone.js Context.\n * @category Core\n */\nconst esm_Listener = Global_getContext().listener;\n/**\n * The [[Listener]] belonging to the global Tone.js Context.\n * @category Core\n */\nfunction getListener() {\n return getContext().listener;\n}\n/**\n * Draw is used to synchronize the draw frame with the Transport\'s callbacks.\n * See [[Draw]]\n * @category Core\n */\nconst esm_Draw = Global_getContext().draw;\n/**\n * Get the singleton attached to the global context.\n * Draw is used to synchronize the draw frame with the Transport\'s callbacks.\n * See [[Draw]]\n * @category Core\n */\nfunction getDraw() {\n return getContext().draw;\n}\n/**\n * A reference to the global context\n * See [[Context]]\n */\nconst context = Global_getContext();\n/**\n * Promise which resolves when all of the loading promises are resolved.\n * Alias for static [[ToneAudioBuffer.loaded]] method.\n * @category Core\n */\nfunction loaded() {\n return ToneAudioBuffer.loaded();\n}\n// this fills in name changes from 13.x to 14.x\n\n\nconst Buffer = (/* unused pure expression or super */ null && (ToneAudioBuffer));\nconst Buffers = (/* unused pure expression or super */ null && (ToneAudioBuffers));\nconst BufferSource = (/* unused pure expression or super */ null && (ToneBufferSource));\n//# sourceMappingURL=index.js.map\n// EXTERNAL MODULE: ./src/lib/startAudioContext.js\nvar startAudioContext = __webpack_require__(631);\nvar startAudioContext_default = /*#__PURE__*/__webpack_require__.n(startAudioContext);\n;// CONCATENATED MODULE: ./src/lib/util.js\n\n\nvar isIphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i);\nvar isIpad = navigator.userAgent.match(/iPad/i);\nvar isAndroid = navigator.userAgent.match(/Android/i);\nvar isMobile = isIphone || isIpad || isAndroid;\nvar isDesktop = !isMobile;\ndocument.body.classList.add(isMobile ? "mobile" : "desktop");\nvar browser = {\n isIphone: isIphone,\n isIpad: isIpad,\n isMobile: isMobile,\n isDesktop: isDesktop\n};\nvar choice = function choice(a) {\n return a[Math.floor(Math.random() * a.length)];\n};\nvar mod = function mod(n, m) {\n return n - m * Math.floor(n / m);\n};\nvar random = function random() {\n return Math.random();\n};\nvar rand = function rand(n) {\n return Math.random() * n;\n};\nvar randint = function randint(n) {\n return rand(n) | 0;\n};\nvar util_randrange = function randrange(a, b) {\n return a + rand(b - a);\n};\nvar randsign = function randsign() {\n return random() >= 0.5 ? -1 : 1;\n};\nvar randnullsign = function randnullsign() {\n var r = random();\n return r < 0.333 ? -1 : r < 0.666 ? 0 : 1;\n};\nfunction requestAudioContext(fn) {\n var container = document.createElement("div");\n var button = document.createElement("div");\n button.innerHTML = "Tap to start - please unmute your phone";\n Object.assign(container.style, {\n display: "block",\n position: "absolute",\n width: "100%",\n height: "100%",\n zIndex: "10000",\n top: "0px",\n left: "0px",\n backgroundColor: "rgba(0, 0, 0, 0.8)"\n });\n Object.assign(button.style, {\n display: "block",\n position: "absolute",\n left: "50%",\n top: "50%",\n padding: "20px",\n backgroundColor: "#7F33ED",\n color: "white",\n fontFamily: "monospace",\n borderRadius: "3px",\n transform: "translate3D(-50%,-50%,0)",\n textAlign: "center",\n lineHeight: "1.5",\n width: "150px"\n });\n container.appendChild(button);\n document.body.appendChild(container);\n startAudioContext_default().setContext(context);\n startAudioContext_default().on(button);\n startAudioContext_default().onStarted(function (_) {\n container.remove();\n fn();\n });\n}\n;// CONCATENATED MODULE: ./src/relabi/canvas.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction _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, _toPropertyKey(descriptor.key), descriptor); } }\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n/**\n * Relabi waveform display\n * @module src/relabi/canvas.js;\n */\nvar RelabiCanvas = /*#__PURE__*/function () {\n /**\n * Initialize relabi wave renderer\n */\n function RelabiCanvas(_ref) {\n var relabi = _ref.relabi,\n parent = _ref.parent;\n _classCallCheck(this, RelabiCanvas);\n this.relabi = relabi;\n this.height = 400;\n this.lastFrame = 0;\n this.lastAppendTime = 0;\n this.lastAppendFrame = 0;\n\n // Speed of the wave in pixels per second\n this.speed = 1 / 5;\n\n // Position of current time on the screen, from the left\n this.tZeroOffset = 20;\n\n // Attach to the DOM\n this.appendCanvas(parent);\n // Initialize array\n this.values = new Array(window.innerWidth).fill(0);\n this.notes = [];\n this.append([]);\n\n // Clear the canvas\n this.resize();\n\n // Start drawing\n this.requestAnimationFrame(0);\n }\n\n /**\n * Append the canvas\n */\n _createClass(RelabiCanvas, [{\n key: "appendCanvas",\n value: function appendCanvas(parent) {\n this.parent = parent || document.body;\n this.canvas = this.canvas || document.createElement("canvas");\n this.ctx = this.ctx || this.canvas.getContext("2d");\n this.parent.appendChild(this.canvas);\n }\n\n /**\n * Draw the next frame\n */\n }, {\n key: "requestAnimationFrame",\n value: function (_requestAnimationFrame) {\n function requestAnimationFrame(_x) {\n return _requestAnimationFrame.apply(this, arguments);\n }\n requestAnimationFrame.toString = function () {\n return _requestAnimationFrame.toString();\n };\n return requestAnimationFrame;\n }(function (frame) {\n var _this = this;\n requestAnimationFrame(function (frame) {\n _this.requestAnimationFrame(frame);\n });\n this.paint(frame);\n this.lastFrame = frame;\n }\n\n /**\n * Handle window resize\n */)\n }, {\n key: "resize",\n value: function resize() {\n this.canvas.width = window.innerWidth;\n this.canvas.height = this.height;\n }\n\n /**\n * Clear the canvas\n */\n }, {\n key: "clear",\n value: function clear() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n /**\n * Append values\n */\n }, {\n key: "append",\n value: function append(time, values, notes) {\n this.lastAppendTime = time;\n this.lastAppendFrame = this.lastFrame;\n this.values = this.values.concat(values).slice(-this.canvas.width).sort(function (a, b) {\n return a[0] - b[0];\n });\n if (notes !== null && notes !== void 0 && notes.length) {\n this.notes = this.notes.concat(notes).slice(-50).sort(function (a, b) {\n return a[0] - b[0];\n });\n }\n }\n\n /**\n * Paint the canvas\n */\n }, {\n key: "paint",\n value: function paint(frame) {\n this.clear();\n this.drawRelabiWave(frame);\n this.drawBounds();\n this.drawNotes(frame);\n }\n\n /**\n * Draw the bounds\n */\n }, {\n key: "drawBounds",\n value: function drawBounds() {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n\n // Draw dashed lines for all bounds\n var _iterator = _createForOfIteratorHelper(this.relabi.bounds),\n _step;\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var bound = _step.value;\n var y = getWaveHeight(bound.level, height);\n ctx.beginPath();\n ctx.setLineDash([4, 4]);\n ctx.lineWidth = 1;\n ctx.strokeStyle = bound.color || "#888";\n ctx.moveTo(0, y);\n ctx.lineTo(width, y);\n ctx.stroke();\n }\n\n // Draw the zero position\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n ctx.beginPath();\n ctx.setLineDash([1, 1]);\n ctx.lineWidth = 2;\n ctx.strokeStyle = "#666";\n ctx.moveTo(width - this.tZeroOffset, 0);\n ctx.lineTo(width - this.tZeroOffset, height);\n ctx.stroke();\n }\n\n /**\n * Draw the relabi wave\n */\n }, {\n key: "drawRelabiWave",\n value: function drawRelabiWave(frame) {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n var pointCount = this.values.length;\n var index = 0;\n\n // Start the path\n ctx.beginPath();\n ctx.strokeStyle = "#dff";\n ctx.lineWidth = 0.75;\n ctx.setLineDash([]);\n\n // This is the offset in seconds from the last frame we computed\n var frameOffset = (frame - this.lastAppendFrame) / 1000;\n\n // Make a path connecting all values\n var _iterator2 = _createForOfIteratorHelper(this.values),\n _step2;\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var point = _step2.value;\n if (!point) {\n index += 1;\n continue;\n }\n var _point = _slicedToArray(point, 2),\n time = _point[0],\n value = _point[1];\n\n // This is the offset of this time from current time\n // If this is in the future, it will be positive.\n // Subtracting the frame offset pulls it negative.\n var timeOffset = this.lastAppendTime + frameOffset - time;\n var x = width - timeOffset * this.speed * width - this.tZeroOffset;\n var y = getWaveHeight(value, height);\n if (x < 0) {\n continue;\n }\n if (index === 0) {\n ctx.moveTo(x, y);\n }\n ctx.lineTo(x, y);\n index += 1;\n }\n\n // Paint the line\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n ctx.stroke();\n }\n\n /**\n * Draw the notes\n */\n }, {\n key: "drawNotes",\n value: function drawNotes(frame) {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n\n // This is the offset in seconds from the last frame we computed\n var frameOffset = (frame - this.lastAppendFrame) / 1000;\n\n // Make a path connecting all values\n var _iterator3 = _createForOfIteratorHelper(this.notes),\n _step3;\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var note = _step3.value;\n var _note = _slicedToArray(note, 3),\n time = _note[0],\n value = _note[1],\n direction = _note[2];\n var timeOffset = this.lastAppendTime + frameOffset - time;\n var x = width - timeOffset * this.speed * width - this.tZeroOffset;\n var y = getWaveHeight(value, height);\n\n // Don\'t draw notes that haven\'t played yet\n if (x > width - this.tZeroOffset) {\n continue;\n }\n\n // Draw notes as a dot that fades out\n var opacity = 1 - timeOffset * this.speed * width / 1000;\n if (opacity < 0.001) {\n continue;\n }\n ctx.beginPath();\n ctx.arc(x - 2.5, y, 5, 0, 2 * Math.PI);\n ctx.fillStyle = direction ? "rgba(255,128,192,".concat(opacity, ")") : "rgba(192,255,128,".concat(opacity, ")");\n ctx.fill();\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n }]);\n return RelabiCanvas;\n}();\n/**\n * Get the height of the wave at a given value\n */\n\nvar getWaveHeight = function getWaveHeight(value, height) {\n return (value + 1) / 2 * height;\n};\n;// CONCATENATED MODULE: ./src/relabi/index.js\nfunction relabi_typeof(obj) { "@babel/helpers - typeof"; return relabi_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, relabi_typeof(obj); }\nfunction relabi_slicedToArray(arr, i) { return relabi_arrayWithHoles(arr) || relabi_iterableToArrayLimit(arr, i) || relabi_unsupportedIterableToArray(arr, i) || relabi_nonIterableRest(); }\nfunction relabi_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction relabi_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return relabi_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return relabi_arrayLikeToArray(o, minLen); }\nfunction relabi_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction relabi_iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction relabi_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction relabi_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction relabi_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, relabi_toPropertyKey(descriptor.key), descriptor); } }\nfunction relabi_createClass(Constructor, protoProps, staticProps) { if (protoProps) relabi_defineProperties(Constructor.prototype, protoProps); if (staticProps) relabi_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction relabi_toPropertyKey(arg) { var key = relabi_toPrimitive(arg, "string"); return relabi_typeof(key) === "symbol" ? key : String(key); }\nfunction relabi_toPrimitive(input, hint) { if (relabi_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (relabi_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n/**\n * Relabi event generator\n */\n\n\n\nvar TWO_PI = 2 * Math.PI;\n\n/**\n * Wave functions\n */\nvar WAVE_FUNCTIONS = {\n sine: Math.cos,\n triangle: function triangle(time) {\n return 4 / TWO_PI * Math.abs(((time - TWO_PI / 4) % TWO_PI + TWO_PI) % TWO_PI - TWO_PI / 2) - 1;\n },\n square: function square(time) {\n return time % TWO_PI < Math.PI ? 1 : -1;\n },\n saw: function saw(time) {\n return (time % TWO_PI - Math.PI) / Math.PI;\n }\n};\n\n/**\n * Relabi generator\n */\nvar Relabi = /*#__PURE__*/function () {\n /**\n * Initialize generator\n */\n function Relabi(_ref) {\n var waves = _ref.waves,\n bounds = _ref.bounds,\n parent = _ref.parent;\n relabi_classCallCheck(this, Relabi);\n this.updateTime = 1;\n this.steps = 50;\n this.waves = waves || [{\n type: "triangle",\n frequency: randrange(0.5, 1.5)\n }, {\n type: "triangle",\n frequency: randrange(0.75, 2.25)\n }, {\n type: "triangle",\n frequency: randrange(1, 3)\n }, {\n type: "triangle",\n frequency: randrange(2, 4)\n }];\n this.bounds = bounds;\n this.previousValue = null;\n this.canvas = new RelabiCanvas({\n relabi: this,\n parent: parent\n });\n }\n\n /**\n * Start the generator\n */\n relabi_createClass(Relabi, [{\n key: "start",\n value: function start() {\n var _this = this;\n console.log("Start Relabi");\n this.stop();\n this.clock = new Clock_Clock(function (time) {\n var values = _this.generate(time);\n var notes = _this.play(values);\n _this.canvas.append(time, values, notes);\n }, this.updateTime);\n this.clock.start();\n }\n\n /**\n * Stop the generator and reset it\n */\n }, {\n key: "stop",\n value: function stop() {\n if (this.clock) {\n this.clock.stop();\n this.clock.dispose();\n }\n }\n\n /**\n * Generate relabi events\n */\n }, {\n key: "generate",\n value: function generate(time) {\n var waveCount = this.waves.length;\n var index;\n var step;\n var value;\n var values = [];\n\n // Overshoot the line slightly each time\n var stepCount = this.steps + 20;\n\n // Generate several events per second\n for (step = 0; step < stepCount; step += 1) {\n // Time offset for this event\n var timeOffset = time + step * this.updateTime / this.steps;\n\n // Initialize value\n value = 0;\n\n // Compute the wave functions for this event\n for (index = 0; index < waveCount; index += 1) {\n var wave = this.waves[index];\n value += WAVE_FUNCTIONS[wave.type](timeOffset * wave.frequency);\n }\n\n // Scale to [-1, 1]\n value /= waveCount;\n values.push([timeOffset, value]);\n }\n return values;\n }\n\n /**\n * Schedule relabi events\n */\n }, {\n key: "play",\n value: function play(values) {\n var boundsCount = this.bounds.length;\n var previousValue = this.previousValue;\n var index;\n var step;\n var noteCount = 0;\n var notes = [];\n for (step = 0; step < this.steps; step += 1) {\n // Get the next value\n var _values$step = relabi_slicedToArray(values[step], 2),\n time = _values$step[0],\n value = _values$step[1];\n\n // Compute whether we crossed a boundary, and which direction\n for (index = 0; index < boundsCount; index += 1) {\n var bound = this.bounds[index];\n if (value < bound.level && bound.level < previousValue && previousValue !== null) {\n // Going down\n this.trigger(time, bound.sounds[0]);\n notes.push([time, bound.level, true]);\n noteCount += 1;\n } else if (value > bound.level && bound.level > previousValue && previousValue !== null) {\n // Going up\n this.trigger(time, bound.sounds[1]);\n notes.push([time, bound.level, false]);\n noteCount += 1;\n }\n }\n\n // Update the previous value\n previousValue = value;\n }\n\n // Store the latest value\n this.previousValue = previousValue;\n\n // Return the notes\n return notes;\n }\n\n /**\n * Trigger an event\n */\n }, {\n key: "trigger",\n value: function trigger(time, sound) {\n // console.log("trigger index", index, time);\n sound.instrument.play(time, sound);\n }\n }]);\n return Relabi;\n}();\n\n;// CONCATENATED MODULE: ./src/lib/output.js\n\nvar compressor = new Compressor_Compressor(-30, 3);\nvar gain = new Gain_Gain(0.3);\ncompressor.connect(gain);\ngain.toDestination();\n/* harmony default export */ const output = (compressor);\n;// CONCATENATED MODULE: ./src/lib/sampler.js\nfunction sampler_typeof(obj) { "@babel/helpers - typeof"; return sampler_typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, sampler_typeof(obj); }\nfunction _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : 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; }; return _extends.apply(this, arguments); }\nfunction sampler_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction sampler_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, sampler_toPropertyKey(descriptor.key), descriptor); } }\nfunction sampler_createClass(Constructor, protoProps, staticProps) { if (protoProps) sampler_defineProperties(Constructor.prototype, protoProps); if (staticProps) sampler_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction sampler_toPropertyKey(arg) { var key = sampler_toPrimitive(arg, "string"); return sampler_typeof(key) === "symbol" ? key : String(key); }\nfunction sampler_toPrimitive(input, hint) { if (sampler_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (sampler_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n\n\n\nvar PLAYER_COUNT = 4;\nvar sampler_Sampler = /*#__PURE__*/function () {\n function Sampler(_ref) {\n var samples = _ref.samples,\n tonal = _ref.tonal;\n sampler_classCallCheck(this, Sampler);\n this.tonal = tonal;\n this.samples = samples.map(function (_ref2) {\n var sample = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));\n sample.players = [];\n sample.index = -1;\n for (var i = 0; i < PLAYER_COUNT; i++) {\n var fn = sample.fn;\n if (window.location.href.match(/asdf.us/)) {\n fn = "//asdf.us/kalimba/" + fn;\n }\n var player = new Player_Player({\n url: fn,\n retrigger: true,\n playbackRate: 1\n });\n player.connect(output);\n sample.players.push(player);\n }\n return sample;\n });\n }\n sampler_createClass(Sampler, [{\n key: "play",\n value: function play(time, options) {\n var sound = options.index ? this.samples[options.index] : choice(this.samples);\n sound.index = (sound.index + 1) % PLAYER_COUNT;\n var player = sound.players[sound.index];\n if (this.tonal) {\n player.playbackRate = (options.frequency * choice([0.5, 1]) + util_randrange(0, 10)) / sound.root;\n }\n player.start(time || 0);\n }\n }]);\n return Sampler;\n}();\n\n;// CONCATENATED MODULE: ./src/lib/instruments.js\n\nvar Kalimba = new sampler_Sampler({\n tonal: true,\n samples: [{\n root: 226,\n fn: "samples/380737__cabled-mess__sansula-01-a-raw.mp3"\n }, {\n root: 267,\n fn: "samples/380736__cabled-mess__sansula-02-c-raw.mp3"\n }, {\n root: 340,\n fn: "samples/380735__cabled-mess__sansula-03-e-raw.mp3"\n }, {\n root: 452,\n fn: "samples/380733__cabled-mess__sansula-06-a-02-raw.mp3"\n }]\n});\nvar Drums = new sampler_Sampler({\n tonal: false,\n samples: [{\n fn: "samples/707_bd.mp3"\n }, {\n fn: "samples/707_clap.mp3"\n },\n // { fn: "samples/707_cow.mp3" },\n {\n fn: "samples/707_hat.mp3"\n }, {\n fn: "samples/707_rim.mp3"\n }]\n});\n;// CONCATENATED MODULE: ./src/ui/App.jsx\nfunction App_slicedToArray(arr, i) { return App_arrayWithHoles(arr) || App_iterableToArrayLimit(arr, i) || App_unsupportedIterableToArray(arr, i) || App_nonIterableRest(); }\nfunction App_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction App_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return App_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return App_arrayLikeToArray(o, minLen); }\nfunction App_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction App_iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction App_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n/**\n * Relabi generator UI\n * @module src/ui/App.js;\n */\n\n\n\n\n\nfunction App() {\n var _useState = (0,react.useState)(),\n _useState2 = App_slicedToArray(_useState, 2),\n relabi = _useState2[0],\n setRelabi = _useState2[1];\n var relabiRef = (0,react.useRef)();\n\n /**\n * Instantiate the Relabi generator\n */\n (0,react.useEffect)(function () {\n if (!relabi) {\n var relabiGenerator = new Relabi({\n waves: [{\n type: "sine",\n frequency: 0.75\n }, {\n type: "sine",\n frequency: 1.0\n }, {\n type: "sine",\n frequency: 1.617\n }, {\n type: "sine",\n frequency: 3.141\n }],\n bounds: [{\n level: -0.75,\n color: "#f33",\n sounds: [{\n instrument: Drums,\n index: 0\n }, {\n instrument: Drums,\n index: 1\n }]\n }, {\n level: 0.75,\n color: "#f83",\n sounds: [{\n instrument: Drums,\n index: 2\n }, {\n instrument: Drums,\n index: 3\n }]\n }, {\n level: -0.25,\n color: "#3b8",\n sounds: [{\n instrument: Kalimba,\n frequency: 440\n }, {\n instrument: Kalimba,\n frequency: 440 * 3 / 2\n }]\n }, {\n level: 0.25,\n color: "#36f",\n sounds: [{\n instrument: Kalimba,\n frequency: 440 * 6 / 5\n }, {\n instrument: Kalimba,\n frequency: 440 * 6 / 7\n }]\n }]\n });\n relabiGenerator.start();\n setRelabi(relabiGenerator);\n }\n }, [relabi]);\n (0,react.useEffect)(function () {\n if (relabi && relabiRef.current) {\n relabi.canvas.appendCanvas(relabiRef.current);\n }\n }, [relabi, relabiRef.current]);\n\n /**\n * Render\n */\n return /*#__PURE__*/react.createElement("div", {\n style: {\n height: "100%",\n width: "100%",\n padding: 0,\n margin: 0,\n display: "flex",\n flexDirection: "column",\n justifyContent: "center"\n }\n }, /*#__PURE__*/react.createElement("div", {\n ref: relabiRef\n }));\n}\n;// CONCATENATED MODULE: ./src/index.jsx\n\n\n\n\ndocument.body.style.backgroundColor = "#111";\ndocument.body.style.color = "#fff";\ndocument.body.style.margin = 0;\ndocument.body.style.padding = 0;\ndocument.body.style.height = "100%";\ndocument.body.style.width = "100%";\ndocument.body.parentNode.style.margin = 0;\ndocument.body.parentNode.style.padding = 0;\ndocument.body.parentNode.style.height = "100%";\ndocument.body.parentNode.style.width = "100%";\nrequestAudioContext(function () {\n var container = document.createElement("div");\n container.style.height = "100%";\n container.style.width = "100%";\n document.body.innerHTML = "";\n document.body.appendChild(container);\n var root = (0,client/* createRoot */.s)(container);\n root.render( /*#__PURE__*/react.createElement(App, null));\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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YUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUFDQTtBQUNBLFFBQVEsWUFBTSxDQUFDLGNBQWM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU07QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCLFlBQVksWUFBTSxDQUFDLG1CQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHlCQUF5QjtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxrQkFBUTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQVM7QUFDeEIsZ0JBQWdCLGNBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixnQkFBZ0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsb0JBQVE7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLDZGQUE2RixzQkFBc0IsSUFBSSxxQkFBcUI7QUFDMUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLHNHQUFzRyxzQkFBc0IsSUFBSSx3QkFBd0I7QUFDdEs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixFQUFFO0FBQ3pCO0FBQ0E7QUFDQSxRQUFRLFlBQU0sMkdBQTJHLHNCQUFzQixJQUFJLHdCQUF3QjtBQUMzSztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUFLO0FBQ2xEO0FBQ0EsK0JBQStCLFVBQVU7QUFDekM7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QiwyQ0FBMkI7QUFDeEQsc0JBQXNCLGNBQUk7QUFDMUI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLG9CQUFvQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxDQUFDLFdBQUs7QUFDbkIsaUM7O0FDMVB5QztBQUNlO0FBQ1g7QUFDRztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNPLE1BQU0sV0FBSyxTQUFTLDZEQUFhO0FBQ3hDO0FBQ0EsbUNBQW1DLFdBQUs7QUFDeEM7QUFDQSw2Q0FBNkMsV0FBSztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUM7O0FDekRrQztBQUNpQjtBQUNEO0FBQ0U7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsV0FBVztBQUM5QjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLG1DOztBQ3ZEK0I7QUFDeUI7QUFDZjtBQUNJO0FBQ087QUFDYjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ08sTUFBTSxpQ0FBZ0IsU0FBUyxJQUFJO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsNkJBQW9CLENBQUMsaUNBQWdCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixjQUFJO0FBQ3pCLG9CQUFvQixjQUFJO0FBQ3hCLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU0sMERBQTBELEtBQUs7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLGNBQUksWUFBWSxjQUFJO0FBQ2xELFlBQVksa0JBQVE7QUFDcEIsbURBQW1ELCtCQUFlO0FBQ2xFO0FBQ0E7QUFDQSxtREFBbUQsK0JBQWU7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Qzs7QUNsSHVDO0FBQ0k7QUFDRTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLGNBQVMsU0FBUyw4REFBYztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBLG1CQUFtQixjQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsZUFBZSxjQUFTO0FBQ3hCO0FBQ0EsZ0M7O0FDeEV1QztBQUNjO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNPLE1BQU0sZ0JBQVUsU0FBUyxnQ0FBa0I7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQLGVBQWUsZ0JBQVU7QUFDekI7QUFDQSxpQzs7QUM1RDZEO0FBQ3ZCO0FBQzJDO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDTyxtQkFBbUIsK0JBQWU7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsOEJBQThCLFNBQVM7QUFDdkMsQ0FBQztBQUNELGNBQWM7QUFDZDtBQUNBLENBQUM7QUFDRCxnQzs7QUM3RytCO0FBQ1M7QUFDUDtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sK0JBQStCLElBQUk7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLENBQUMsbUJBQVM7QUFDeEIsUUFBUSxZQUFNLENBQUMsbUJBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxvQkFBb0I7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsZ0JBQVU7QUFDbkM7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLG1CQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQVU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFNBQUk7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELFFBQVE7QUFDN0Q7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELGtCQUFRO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELGtCQUFRO0FBQ2pFO0FBQ0E7QUFD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c0NBQXNDLHVCQUF1QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0I7O0FDeE9zQztBQUN0QztBQUNBO0FBQ0E7QUFD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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Qzs7QUMxT3dCO0FBQ0k7QUFDWTtBQUNFO0FBQ0E7QUFDRztBQUNGO0FBQ0E7QUFDQztBQUNJO0FBQ2Y7QUFDUztBQUNWO0FBQ0M7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QUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCx3QkFBd0IseUJBQXlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDck1tQztBQUNxQjtBQUNnQjtBQUN0QjtBQUNSO0FBQ1Y7QUFDMEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyw0QkFBNEIsV0FBSztBQUN4QztBQUNBLGNBQWMsNkJBQW9CO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsNkJBQW9CO0FBQzVDO0FBQ0E7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQSxlQUFlLGtCQUFTLENBQUMsaUNBQXNCLElBQUksdUJBQWlCO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsdURBQXVELHdCQUFjO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLElBQUksS0FBSztBQUNUO0FBQ0EsVUFBVTtBQUNWLElBQUksU0FBUztBQUNiO0FBQ0EseUM7O0FDcEU0RTtBQUNDO0FBQ3JDO0FBQ0U7QUFDb0I7QUFDSjtBQUNoQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyx5QkFBeUIsMERBQVU7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsNkRBQTZELEtBQUssS0FBSyxVQUFVO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLHdDQUFxQjtBQUNyQztBQUNBO0FBQ0EsOEM7O0FDdkJ5RDtBQUNoQjtBQUNvQjtBQUN0RCxNQUFNLGlDQUFnQixTQUFTLDZEQUFhO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRkFBa0YseUJBQXlCO0FBQzNHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDOztBQ3ZDb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaLDZEOztBQ2pDNkM7QUFDTztBQUM3QztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsOEJBQThCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHlCQUF5QjtBQUNqRDtBQUNBLDBCQUEwQix3QkFBd0I7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWixxRDs7QUN2RW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osNkM7O0FDL0NzRDtBQUNSO0FBQzRCO0FBQ25FLE1BQU0sc0NBQVc7QUFDeEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLENBQUMsc0NBQVc7QUFDN0Isc0Q7O0FDcEMrQztBQUNFO0FBQytCO0FBQ2hCO0FBQ1g7QUFDa0I7QUFDWjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLHFDQUFrQixTQUFTLGdFQUFnQjtBQUN4RDtBQUNBLG1DQUFtQyxxQ0FBa0I7QUFDckQ7QUFDQSw2Q0FBNkMscUNBQWtCO0FBQy9ELGdDQUFnQyx1QkFBdUI7QUFDdkQsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Qzs7QUN2RWlFO0FBQ0Q7QUFDakI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLDJCQUFhLFNBQVMsNkRBQWE7QUFDaEQ7QUFDQSxtQ0FBbUMsMkJBQWE7QUFDaEQ7QUFDQSw2Q0FBNkMsMkJBQWE7QUFDMUQ7QUFDQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFNBQVM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDOztBQ3ZHaUU7QUFDRDtBQUNOO0FBQ1Y7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUNBQWlCLFNBQVMsNkRBQWE7QUFDcEQ7QUFDQSxtQ0FBbUMsbUNBQWlCO0FBQ3BEO0FBQ0EsNkNBQTZDLG1DQUFpQjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkM7O0FDcEQwRTtBQUN4QjtBQUNXO0FBQ3JCO0FBQ0U7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyx5QkFBeUIsMERBQVU7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDL0U4QztBQUMwQztBQUM3QjtBQUNqQjtBQUNWO0FBQ2tCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxlQUFlO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ08sd0JBQXdCLDBEQUFVO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELGdCQUFnQjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBGQUEwRixRQUFRO0FBQ2xHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNVN3QztBQUMwQjtBQUNMO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLCtEQUFlO0FBQ3pDO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQSw2Q0FBNkMsU0FBSTtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNuS2dEO0FBQ2dCO0FBQ1M7QUFDZDtBQUNvQjtBQUN2QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sb0NBQW9DO0FBQzlDLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLHlEQUFTO0FBQ25DO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFNBQUk7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0Qiw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxTQUFJO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ2haNEM7QUFDRjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxVQUFVLGlDQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDcEs4QjtBQUN3QjtBQUNPO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyxzQkFBc0Isb0RBQUk7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xFZ0Q7QUFDNkI7QUFDbEI7QUFDN0I7QUFDVTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLHlEQUFTO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUN0UHVCO0FBQ0E7QUFDRztBQUNDO0FBQ0M7QUFDNUIsaUM7O0FDTCtDO0FBQzJCO0FBQ1Y7QUFDWDtBQUNFO0FBQ1Y7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyw2REFBYTtBQUM1QztBQUNBLGlEQUFpRCxtQkFBUztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDaExrQztBQUMrQjtBQUNsQjtBQUNBO0FBQ2E7QUFDSTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNPLHVCQUF1Qiw2REFBYTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtB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O0FBQy9CdEMsUUFBUSxDQUFDQyxJQUFJLENBQUM0QixLQUFLLENBQUNJLE1BQU0sR0FBRyxNQUFNO0FBQ25DakMsUUFBUSxDQUFDQyxJQUFJLENBQUM0QixLQUFLLENBQUNHLEtBQUssR0FBRyxNQUFNO0FBQ2xDaEMsUUFBUSxDQUFDQyxJQUFJLENBQUN1TixVQUFVLENBQUMzTCxLQUFLLENBQUNzTCxNQUFNLEdBQUcsQ0FBQztBQUN6Q25OLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDdU4sVUFBVSxDQUFDM0wsS0FBSyxDQUFDUyxPQUFPLEdBQUcsQ0FBQztBQUMxQ3RDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDdU4sVUFBVSxDQUFDM0wsS0FBSyxDQUFDSSxNQUFNLEdBQUcsTUFBTTtBQUM5Q2pDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDdU4sVUFBVSxDQUFDM0wsS0FBSyxDQUFDRyxLQUFLLEdBQUcsTUFBTTtBQUU3Q1gsbUJBQW1CLENBQUMsWUFBTTtFQUN4QixJQUFNRSxTQUFTLEdBQUd2QixRQUFRLENBQUN3QixhQUFhLENBQUMsS0FBSyxDQUFDO0VBQy9DRCxTQUFTLENBQUNNLEtBQUssQ0FBQ0ksTUFBTSxHQUFHLE1BQU07RUFDL0JWLFNBQVMsQ0FBQ00sS0FBSyxDQUFDRyxLQUFLLEdBQUcsTUFBTTtFQUM5QmhDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDeUIsU0FBUyxHQUFHLEVBQUU7RUFDNUIxQixRQUFRLENBQUNDLElBQUksQ0FBQzRDLFdBQVcsQ0FBQ3RCLFNBQVMsQ0FBQztFQUNwQyxJQUFNOEssSUFBSSxHQUFHa0IsNEJBQVUsQ0FBQ2hNLFNBQVMsQ0FBQztFQUNsQzhLLElBQUksQ0FBQ29CLE1BQU0sZUFBQ2pCLG1CQUFBLENBQUNJLEdBQUcsTUFBRSxDQUFDLENBQUM7QUFDdEIsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3ZlcnNpb24uanM/MzM4MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hYm9ydC1lcnJvci5qcz83MzgyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzPzc4N2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMuanM/ZjBmZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanM/YWQzZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2dsb2JhbHMuanM/NzRmNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtY29uc3RydWN0aWJsZS5qcz81MjgwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zcGxpdC1pbXBvcnQtc3RhdGVtZW50cy5qcz83ODkyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1hdWRpby13b3JrbGV0LW1vZHVsZS5qcz83NDg3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtdmFsdWUtZm9yLWtleS5qcz81ZDc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9waWNrLWVsZW1lbnQtZnJvbS1zZXQuanM/NTYwZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzP2E1MmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcz8wMjdjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlLmpzPzJmOTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYXVkaW8td29ya2xldC1ub2RlLmpzPzFiOGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLmpzP2FlNWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5LmpzPzdhNTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz8zMzllIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz8xMGM5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1zaWxlbnQtY29ubmVjdGlvbi5qcz9jOWM5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcz9kYTZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtY29uc3RydWN0b3IuanM/MDg1NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dC5qcz80OTY1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz83MzFhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQuanM/MzdmZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pbmRleC1zaXplLWVycm9yLmpzP2JjY2UiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kLmpzPzIzYjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzPzUyN2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9jb25zdGFudHMuanM/NjJmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUuanM/MTFkNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3IuanM/NzU2OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz82NGRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS5qcz9mMmZmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2JpcXVhZC1maWx0ZXItbm9kZS5qcz9hMjIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2NvbnN0YW50LXNvdXJjZS1ub2RlLmpzPzI0MWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvZ2Fpbi1ub2RlLmpzP2FlMTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvb3NjaWxsYXRvci1ub2RlLmpzPzQwOWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvc3RlcmVvLXBhbm5lci1ub2RlLmpzP2ZkNzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzPzJhNzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucy5qcz80ZGFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zLmpzP2M5MzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGguanM/OWU5YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtdmFsaWQtbGF0ZW5jeS1oaW50LmpzPzgwMDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz85NWI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanM/MDUzNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/ODJiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1saXN0ZW5lci1mYWN0b3J5LmpzP2QwNzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYXVkaW8tbm9kZS5qcz9iNDVlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24uanM/ZThjMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaW5zZXJ0LWVsZW1lbnQtaW4tc2V0LmpzPzBlMjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2FkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcz8zZTIwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzPzE2YjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXIuanM/MTM2NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS10by1uYXRpdmUtYXVkaW8tbm9kZS5qcz8yZmU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24uanM/M2M1NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzP2U4NjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlbGV0ZS1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcz85YjE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzPzIxOTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZS5qcz9mNzI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUuanM/MzA0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1wYXJhbS5qcz85NGQ5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1wYXJ0LW9mLWEtY3ljbGUuanM/M2NjYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtcGFzc2l2ZS1hdWRpby1ub2RlLmpzP2FhMzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC1zdXBwb3J0LmpzP2UzNDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Zpc2l0LWVhY2gtYXVkaW8tbm9kZS1vbmNlLmpzPzAyYmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUuanM/OTIxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLmpzP2RlZjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tbm9kZS1jb25zdHJ1Y3Rvci5qcz85ZmU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLWZhY3RvcnkuanM/OTJkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1wYXJhbS1yZW5kZXJlci5qcz8wOTA4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvcmVhZC1vbmx5LW1hcC5qcz85Yzg1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcz81MTJiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jb3B5LWZyb20tY2hhbm5lbC5qcz9kMDBlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jb3B5LXRvLWNoYW5uZWwuanM/Y2ZlZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMuanM/ZjAxOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzP2UxMmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/M2YxNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/YjEzNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanM/MjU2MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz84MjdiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NhY2hlLXRlc3QtcmVzdWx0LmpzP2ZjNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz9lZDAyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz9lMDg3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz81NGJhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzP2ViMDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29ubmVjdC1hdWRpby1wYXJhbS5qcz81NzI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcz8xMjQyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Nvbm5lY3RlZC1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanM/NjQ2NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb25zdGFudC1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz80YmQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MzE0NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nLmpzPzA5YmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29udm9sdmVyLW5vZGUtY29uc3RydWN0b3IuanM/MDVlOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzVhOTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/NTMyYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kYXRhLWNsb25lLWVycm9yLmpzPzE5NWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RldGFjaC1hcnJheS1idWZmZXIuanM/OWY3ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWNvZGUtYXVkaW8tZGF0YS5qcz8yNjlkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlY3JlbWVudC1jeWNsZS1jb3VudGVyLmpzPzFmNGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVsYXktbm9kZS1jb25zdHJ1Y3Rvci5qcz8xMTNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8xZTc1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzP2UyMTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVsZXRlLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlLmpzPzFkNDQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvZGVsYXktbm9kZS5qcz82ZTk2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RldGVjdC1jeWNsZXMuanM/N2FiMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kaXNjb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanM/M2Q0MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3IuanM/ODJmMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz9iYTkwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2VuY29kaW5nLWVycm9yLmpzP2I2N2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZXZhbHVhdGUtc291cmNlLmpzPzM1ZjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yLmpzPzQyMjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZXhwb3NlLWN1cnJlbnQtZnJhbWUtYW5kLWN1cnJlbnQtdGltZS5qcz82M2Y3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2ZldGNoLXNvdXJjZS5qcz9lOWRjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dhaW4tbm9kZS1jb25zdHJ1Y3Rvci5qcz9jN2RlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dhaW4tbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzc3ZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzLmpzPzYwNGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtcmVuZGVyZXIuanM/ZGE1MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUuanM/MDM2MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYXVkaW8tcGFyYW0tcmVuZGVyZXIuanM/MGZlNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz85MjMyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3IuanM/ZTA5NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtbmF0aXZlLWNvbnRleHQuanM/NGVhYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/ZGE5ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGVzLmpzP2RjZTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaW52YWxpZC1hY2Nlc3MtZXJyb3IuanM/MzYxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QuanM/ODc0NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanM/MDU2ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZmlsdGVyLWJ1ZmZlci5qcz9lNDFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzM3MzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeS5qcz9lMzI1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLWFueS1hdWRpby1jb250ZXh0LmpzPzVhMjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLW5vZGUuanM/MDc4OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tcGFyYW0uanM/N2U3NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzP2RmMjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLWNvbnRleHQuanM/MjI2YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tbm9kZS5qcz82M2I5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1wYXJhbS5qcz8xNTFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1jb250ZXh0LmpzPzVjZTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz81YWQ2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLXNlY3VyZS1jb250ZXh0LmpzPzg2ZjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz83MzcwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzPzMwNzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzP2FhNGIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzP2JhNTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWluaW1hbC1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzP2VkZDMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/ZGU2MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQuanM/ZTUzOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9taW5pbWFsLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz81MDM2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21vbml0b3ItY29ubmVjdGlvbnMuanM/ZmM3NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbi5qcz84ZWY3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucy5qcz9jZTc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLXN1cHBvcnQuanM/MTAxZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC5qcz9mNTc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hbmFseXNlci1ub2RlLWZhY3RvcnkuanM/YjM0MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzPzg4ZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZS5qcz82M2YwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanM/ZjgwMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMuanM/MjUxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcz85MjRmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeS5qcz8zZjkwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzPzI3ZTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanM/ZGVkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yLmpzP2UxNmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtY2xvbmFiaWxpdHktb2YtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanM/NmMyZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZhY3RvcnkuanM/MjhkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY29tcHV0ZS1idWZmZXItc2l6ZS5qcz9kMTE2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jbG9uZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcz84YjUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcHJvbWlzZS5qcz8xMmQ1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanM/M2E5ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZha2VyLWZhY3RvcnkuanM/MGMwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYmlxdWFkLWZpbHRlci1ub2RlLmpzP2E5ZGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWNoYW5uZWwtbWVyZ2VyLW5vZGUtZmFjdG9yeS5qcz8yNTZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWNoYW5uZWwtc3BsaXR0ZXItbm9kZS5qcz8zYmFmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanM/ODliYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFjdG9yeS5qcz81YTAzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMuanM/NTAxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeS5qcz9lMGNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5LmpzP2ExNGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWRlbGF5LW5vZGUuanM/MDUxOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnkuanM/NDg5NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtZ2Fpbi1ub2RlLmpzP2Y3ZjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5LmpzP2YzZTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzP2Y4YWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUuanM/MDcwOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanM/ZDFjYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLmpzP2VjYzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzPzM2MzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz83MmY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1vc2NpbGxhdG9yLW5vZGUtZmFjdG9yeS5qcz85N2VmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1wYW5uZXItbm9kZS1mYWN0b3J5LmpzP2VjZmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanM/MGRhZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5LmpzPzliYjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXNjcmlwdC1wcm9jZXNzb3Itbm9kZS5qcz9iMTUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFjdG9yeS5qcz81OGY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcz8wZGUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZhY3RvcnkuanM/ODU5NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzPzMzNDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbm90LXN1cHBvcnRlZC1lcnJvci5qcz8xMzYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL29mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz8zMGQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL29zY2lsbGF0b3Itbm9kZS1jb25zdHJ1Y3Rvci5qcz85YzViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL29zY2lsbGF0b3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzczMmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcGFubmVyLW5vZGUtY29uc3RydWN0b3IuanM/Njg0ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzE4MjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcGVyaW9kaWMtd2F2ZS1jb25zdHJ1Y3Rvci5qcz9jMTAwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3JlbmRlci1hdXRvbWF0aW9uLmpzPzE4ZWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlLmpzPzNiODUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1wYXJhbS5qcz83NGY4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3JlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzPzEzYTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzLmpzP2YyODAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzP2UzMDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc3RhcnQtcmVuZGVyaW5nLmpzPzcxMzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzPzhlYzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/N2I0MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci1zdXBwb3J0LmpzPzRiYjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydC5qcz9mYmNhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Rlc3Qtb2ZmbGluZS1hdWRpby1jb250ZXh0LWN1cnJlbnQtdGltZS1zdXBwb3J0LmpzP2NlYTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvdW5rbm93bi1lcnJvci5qcz9jMWQwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dhdmUtc2hhcGVyLW5vZGUtY29uc3RydWN0b3IuanM/MTQyZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MjgzYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93aW5kb3cuanM/YWIzYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy5qcz8zZTNkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMuanM/MWFkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLmpzPzcwZDUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd3JhcC1jaGFubmVsLW1lcmdlci1ub2RlLmpzPzg3NTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1maXJzdC1zYW1wbGUuanM/ODk1YSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtZGMtY3VydmUuanM/ZDRlMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvb3ZlcndyaXRlLWFjY2Vzc29ycy5qcz8xYjI3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zYW5pdGl6ZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcz84MDU4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMuanM/NDkwNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2FuaXRpemUtcGVyaW9kaWMtd2F2ZS1vcHRpb25zLmpzP2Y2ZGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC12YWx1ZS1hdC10aW1lLXVudGlsLXBvc3NpYmxlLmpzP2E5YzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzPzY3MmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmctc3VwcG9ydC5qcz84ZGRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLXN1cHBvcnQuanM/ZjYxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcz9lMTZlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzP2U1NmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcz83NGY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLWNsb25hYmlsaXR5LmpzPzY3YzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcuanM/MWYxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanM/ZWQyMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1ldmVudC1saXN0ZW5lci5qcz9lNDllIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvbW9kdWxlLmpzPzc4ZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9EZWJ1Zy5qcz9hMzc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvVHlwZUNoZWNrLmpzPzg2NzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9BdWRpb0NvbnRleHQuanM/OTFhYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzPzlhYjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVGlja2VyLmpzP2E0NTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9BZHZhbmNlZFR5cGVDaGVjay5qcz9iZjZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRGVmYXVsdHMuanM/NWI3OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9Ub25lLmpzP2FmYWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9NYXRoLmpzP2Y0Y2YiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9UaW1lbGluZS5qcz9lNTI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvQ29udGV4dEluaXRpYWxpemF0aW9uLmpzPzAxMzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9FbWl0dGVyLmpzPzE1ZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9CYXNlQ29udGV4dC5qcz8xZDIzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvQ29udGV4dC5qcz9hMjgyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvRHVtbXlDb250ZXh0LmpzPzRjOWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9JbnRlcmZhY2UuanM/MDZlMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlci5qcz8xNDliIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHQuanM/YWIxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9HbG9iYWwuanM/NTgzYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL0NvbnZlcnNpb25zLmpzPzQ2ZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UaW1lQmFzZS5qcz9iNjc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvVGltZS5qcz80MTQyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvRnJlcXVlbmN5LmpzPzQ1YzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UcmFuc3BvcnRUaW1lLmpzP2Q1MGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lV2l0aENvbnRleHQuanM/ZDY4MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL1N0YXRlVGltZWxpbmUuanM/ZjFiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1BhcmFtLmpzPzFmNzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlLmpzP2I2NGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9HYWluLmpzP2IyMzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9PbmVTaG90U291cmNlLmpzPzQ3NzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9Ub25lQ29uc3RhbnRTb3VyY2UuanM/ZjRiZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NpZ25hbC5qcz9kZGVhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RpY2tQYXJhbS5qcz81Y2UzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RpY2tTaWduYWwuanM/NzIxNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UaWNrU291cmNlLmpzPzgyYzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svQ2xvY2suanM/MTBhMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0RlbGF5LmpzP2JiM2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9PZmZsaW5lLmpzP2U5NDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzLmpzPzQ5ZDUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9NaWRpLmpzP2M4ZmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UaWNrcy5qcz9lNmNlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRHJhdy5qcz81NDNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvSW50ZXJ2YWxUaW1lbGluZS5qcz8wODljIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2luZGV4LmpzP2NkMzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZS5qcz9hMDk4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvRGVzdGluYXRpb24uanM/MWJjZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL1RpbWVsaW5lVmFsdWUuanM/YjAzMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UcmFuc3BvcnRFdmVudC5qcz8zZjE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RyYW5zcG9ydFJlcGVhdEV2ZW50LmpzPzk4ZGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVHJhbnNwb3J0LmpzPzRjNGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9Tb3VyY2UuanM/NTA5YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlLmpzPzJiM2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9Ob2lzZS5qcz9kMzA2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvVXNlck1lZGlhLmpzP2M3M2YiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL09zY2lsbGF0b3JJbnRlcmZhY2UuanM/ZDlkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlLmpzP2ZiYmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL09zY2lsbGF0b3IuanM/NGRkMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NpZ25hbE9wZXJhdG9yLmpzPzllODgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9XYXZlU2hhcGVyLmpzP2EzY2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9BdWRpb1RvR2Fpbi5qcz9hZGFkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvTXVsdGlwbHkuanM/NTA3OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvQU1Pc2NpbGxhdG9yLmpzPzU4MjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL0ZNT3NjaWxsYXRvci5qcz81YTE4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9QdWxzZU9zY2lsbGF0b3IuanM/NDI5NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvRmF0T3NjaWxsYXRvci5qcz9iOGRkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9QV01Pc2NpbGxhdG9yLmpzP2VmZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yLmpzPzdkNzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9BZGQuanM/NDI4MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NjYWxlLmpzP2VkNmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9aZXJvLmpzP2VkYjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL0xGTy5qcz9mMzNhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRGVjb3JhdG9yLmpzPzk2ZmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9idWZmZXIvUGxheWVyLmpzPzc3ODAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9idWZmZXIvUGxheWVycy5qcz80NzQ5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvYnVmZmVyL0dyYWluUGxheWVyLmpzPzBhMWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9pbmRleC5qcz9mNDIzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvQWJzLmpzP2JiOTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9HYWluVG9BdWRpby5qcz8yMjZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvTmVnYXRlLmpzPzBhMjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TdWJ0cmFjdC5qcz9iNjdkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvR3JlYXRlclRoYW5aZXJvLmpzPzYyMjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9HcmVhdGVyVGhhbi5qcz9iZDMzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvUG93LmpzP2E4NDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TY2FsZUV4cC5qcz80Njc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU3luY2VkU2lnbmFsLmpzPzk1NzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9pbmRleC5qcz8wMzU2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGUuanM/MjNmOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9JbnN0cnVtZW50LmpzP2U5MzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTW9ub3Bob25pYy5qcz83NGVlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGUuanM/ZjIxMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9TeW50aC5qcz9lNWU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01vZHVsYXRpb25TeW50aC5qcz8zYzI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L0FNU3ludGguanM/YmEwNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9CaXF1YWRGaWx0ZXIuanM/NjQ2ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXIuanM/MTMxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2VudmVsb3BlL0ZyZXF1ZW5jeUVudmVsb3BlLmpzPzg3MDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTW9ub1N5bnRoLmpzPzJkZWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvRHVvU3ludGguanM/Nzg3ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9GTVN5bnRoLmpzP2I5YzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTWV0YWxTeW50aC5qcz85MzJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01lbWJyYW5lU3ludGguanM/OTU0MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Ob2lzZVN5bnRoLmpzPzNjOGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGUuanM/OGE2NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXQuanM/ZTA4ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Iud29ya2xldC5qcz81MWYxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldC5qcz81NjhjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvRGVsYXlMaW5lLndvcmtsZXQuanM/ZDUwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9GZWVkYmFja0NvbWJGaWx0ZXIud29ya2xldC5qcz8wODhjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlci5qcz9hNTFmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL09uZVBvbGVGaWx0ZXIuanM/YTc4ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlci5qcz8yOGUwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L1BsdWNrU3ludGguanM/MDZjYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Qb2x5U3ludGguanM/NTg4MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9TYW1wbGVyLmpzPzMxOTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvaW5kZXguanM/YzYxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvVG9uZUV2ZW50LmpzP2U1MzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L0xvb3AuanM/ZGJkYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvUGFydC5qcz84ZDM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9QYXR0ZXJuR2VuZXJhdG9yLmpzPzljZGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L1BhdHRlcm4uanM/YzQ2NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvU2VxdWVuY2UuanM/OGY5MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvaW5kZXguanM/NDA0YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvQ3Jvc3NGYWRlLmpzPzJjODYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9FZmZlY3QuanM/ZDEyNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0xGT0VmZmVjdC5qcz80YjM5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQXV0b0ZpbHRlci5qcz8wOTc0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9QYW5uZXIuanM/YjFlYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0F1dG9QYW5uZXIuanM/MmE0NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0ZvbGxvd2VyLmpzPzQ2YjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9BdXRvV2FoLmpzP2M5Y2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9CaXRDcnVzaGVyLndvcmtsZXQuanM/ZGI4NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0JpdENydXNoZXIuanM/YTQ5YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0NoZWJ5c2hldi5qcz9iMTg3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9TcGxpdC5qcz85OWI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9NZXJnZS5qcz9kMDViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvU3RlcmVvRWZmZWN0LmpzP2YwNmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9TdGVyZW9GZWVkYmFja0VmZmVjdC5qcz8xMWUwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQ2hvcnVzLmpzPzc0MWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9EaXN0b3J0aW9uLmpzPzgwNDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GZWVkYmFja0VmZmVjdC5qcz9hNzE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRmVlZGJhY2tEZWxheS5qcz84YmYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL1BoYXNlU2hpZnRBbGxwYXNzLmpzPzhkNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GcmVxdWVuY3lTaGlmdGVyLmpzPzhhNjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GcmVldmVyYi5qcz9lODk3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvSkNSZXZlcmIuanM/MTVkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1N0ZXJlb1hGZWVkYmFja0VmZmVjdC5qcz84OTg2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUGluZ1BvbmdEZWxheS5qcz9kZTI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUGl0Y2hTaGlmdC5qcz84NmE2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUGhhc2VyLmpzPzZiNzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9SZXZlcmIuanM/MGQ4MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZVNwbGl0LmpzP2ZlM2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL01pZFNpZGVNZXJnZS5qcz82ZmIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvTWlkU2lkZUVmZmVjdC5qcz9lZmY3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvU3RlcmVvV2lkZW5lci5qcz8wZGIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvVHJlbW9sby5qcz8wZTFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvVmlicmF0by5qcz8wYzFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvaW5kZXguanM/ZWM0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0FuYWx5c2VyLmpzP2VkYWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9NZXRlckJhc2UuanM/NDc2YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL01ldGVyLmpzP2RmNDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9GRlQuanM/NjVlZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0RDTWV0ZXIuanM/N2I5MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL1dhdmVmb3JtLmpzPzk5ZDMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1NvbG8uanM/MWJiZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUGFuVm9sLmpzPzFhZjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL0NoYW5uZWwuanM/ZDM3MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTW9uby5qcz85ZmE4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9NdWx0aWJhbmRTcGxpdC5qcz8zNDUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvTGlzdGVuZXIuanM/MjAzOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUGFubmVyM0QuanM/YzlkZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUmVjb3JkZXIuanM/YWQ3YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL0NvbXByZXNzb3IuanM/NmRiNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL0dhdGUuanM/OGJmNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL0xpbWl0ZXIuanM/MTVjNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL01pZFNpZGVDb21wcmVzc29yLmpzP2RiNTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9NdWx0aWJhbmRDb21wcmVzc29yLmpzP2ZkYmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvRVEzLmpzPzJmNzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvQ29udm9sdmVyLmpzP2VhMTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9pbmRleC5qcz8xZDc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jbGFzc2VzLmpzP2QzYzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luZGV4LmpzPzVlNTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi91dGlsLmpzP2YxZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3JlbGFiaS9jYW52YXMuanM/ZGM5ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvcmVsYWJpL2luZGV4LmpzPzAyZmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi9vdXRwdXQuanM/M2ZlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3NhbXBsZXIuanM/NTk2YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL2luc3RydW1lbnRzLmpzP2Y5YTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3VpL0FwcC5qc3g/NDQyYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvaW5kZXguanN4P2VkMTIiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHZlcnNpb24gPSBcIjE0LjcuNzdcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZlcnNpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFib3J0RXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnQWJvcnRFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWJvcnQtZXJyb3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKGluc2VydEVsZW1lbnRJblNldCkgPT4ge1xuICAgIHJldHVybiAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQoYWN0aXZlSW5wdXRzW2lucHV0XSwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZUNvbm5lY3Rpb25zU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgYXVkaW9Ob2RlUmVuZGVyZXIsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhY3RpdmVJbnB1dHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgYWN0aXZlSW5wdXRzLnB1c2gobmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb05vZGVDb25uZWN0aW9uc1N0b3JlLnNldChhdWRpb05vZGUsIHtcbiAgICAgICAgICAgIGFjdGl2ZUlucHV0cyxcbiAgICAgICAgICAgIG91dHB1dHM6IG5ldyBTZXQoKSxcbiAgICAgICAgICAgIHBhc3NpdmVJbnB1dHM6IG5ldyBXZWFrTWFwKCksXG4gICAgICAgICAgICByZW5kZXJlcjogYXVkaW9Ob2RlUmVuZGVyZXJcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gKGF1ZGlvUGFyYW1Db25uZWN0aW9uc1N0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb1BhcmFtLCBhdWRpb1BhcmFtUmVuZGVyZXIpID0+IHtcbiAgICAgICAgYXVkaW9QYXJhbUNvbm5lY3Rpb25zU3RvcmUuc2V0KGF1ZGlvUGFyYW0sIHsgYWN0aXZlSW5wdXRzOiBuZXcgU2V0KCksIHBhc3NpdmVJbnB1dHM6IG5ldyBXZWFrTWFwKCksIHJlbmRlcmVyOiBhdWRpb1BhcmFtUmVuZGVyZXIgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IEFDVElWRV9BVURJT19OT0RFX1NUT1JFID0gbmV3IFdlYWtTZXQoKTtcbmV4cG9ydCBjb25zdCBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19OT0RFX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fUEFSQU1fU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IENPTlRFWFRfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEVWRU5UX0xJU1RFTkVSUyA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQ1lDTEVfQ09VTlRFUlMgPSBuZXcgV2Vha01hcCgpO1xuLy8gVGhpcyBjbHVua3kgbmFtZSBpcyBib3Jyb3dlZCBmcm9tIHRoZSBzcGVjLiA6LSlcbmV4cG9ydCBjb25zdCBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgPSBuZXcgV2Vha01hcCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2xvYmFscy5qcy5tYXAiLCJjb25zdCBoYW5kbGVyID0ge1xuICAgIGNvbnN0cnVjdCgpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXI7XG4gICAgfVxufTtcbmV4cG9ydCBjb25zdCBpc0NvbnN0cnVjdGlibGUgPSAoY29uc3RydWN0aWJsZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KGNvbnN0cnVjdGlibGUsIGhhbmRsZXIpO1xuICAgICAgICBuZXcgcHJveHkoKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtY29uc3RydWN0aWJsZS5qcy5tYXAiLCIvKlxuICogVGhpcyBtYXNzaXZlIHJlZ2V4IHRyaWVzIHRvIGNvdmVyIGFsbCB0aGUgZm9sbG93aW5nIGNhc2VzLlxuICpcbiAqIGltcG9ydCAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgeyBuYW1lZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgeyBuYW1lZEltcG9ydCBhcyByZW5hbWVuZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgKiBhcyBuYW1lc3BhY2VJbXBvcnQgZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCB7IG5hbWVkSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCB7IG5hbWVkSW1wb3J0IGFzIHJlbmFtZW5kSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCAqIGFzIG5hbWVzcGFjZUltcG9ydCBmcm9tICcuL3BhdGgnO1xuICovXG5jb25zdCBJTVBPUlRfU1RBVEVNRU5UX1JFR0VYID0gL15pbXBvcnQoPzooPzpbXFxzXStbXFx3XSt8KD86W1xcc10rW1xcd10rW1xcc10qLCk/W1xcc10qXFx7W1xcc10qW1xcd10rKD86W1xcc10rYXNbXFxzXStbXFx3XSspPyg/OltcXHNdKixbXFxzXSpbXFx3XSsoPzpbXFxzXSthc1tcXHNdK1tcXHddKyk/KSpbXFxzXSp9fCg/OltcXHNdK1tcXHddK1tcXHNdKiwpP1tcXHNdKlxcKltcXHNdK2FzW1xcc10rW1xcd10rKVtcXHNdK2Zyb20pPyg/OltcXHNdKikoXCIoW15cIlxcXFxdfFxcXFwuKStcInwnKFteJ1xcXFxdfFxcXFwuKSsnKSg/OltcXHNdKik7Py87IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG5leHBvcnQgY29uc3Qgc3BsaXRJbXBvcnRTdGF0ZW1lbnRzID0gKHNvdXJjZSwgdXJsKSA9PiB7XG4gICAgY29uc3QgaW1wb3J0U3RhdGVtZW50cyA9IFtdO1xuICAgIGxldCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyA9IHNvdXJjZS5yZXBsYWNlKC9eW1xcc10rLywgJycpO1xuICAgIGxldCByZXN1bHQgPSBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cy5tYXRjaChJTVBPUlRfU1RBVEVNRU5UX1JFR0VYKTtcbiAgICB3aGlsZSAocmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHVucmVzb2x2ZWRVcmwgPSByZXN1bHRbMV0uc2xpY2UoMSwgLTEpO1xuICAgICAgICBjb25zdCBpbXBvcnRTdGF0ZW1lbnRXaXRoUmVzb2x2ZWRVcmwgPSByZXN1bHRbMF1cbiAgICAgICAgICAgIC5yZXBsYWNlKC8oW1xcc10rKT87PyQvLCAnJylcbiAgICAgICAgICAgIC5yZXBsYWNlKHVucmVzb2x2ZWRVcmwsIG5ldyBVUkwodW5yZXNvbHZlZFVybCwgdXJsKS50b1N0cmluZygpKTtcbiAgICAgICAgaW1wb3J0U3RhdGVtZW50cy5wdXNoKGltcG9ydFN0YXRlbWVudFdpdGhSZXNvbHZlZFVybCk7XG4gICAgICAgIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMuc2xpY2UocmVzdWx0WzBdLmxlbmd0aCkucmVwbGFjZSgvXltcXHNdKy8sICcnKTtcbiAgICAgICAgcmVzdWx0ID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMubWF0Y2goSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCk7XG4gICAgfVxuICAgIHJldHVybiBbaW1wb3J0U3RhdGVtZW50cy5qb2luKCc7JyksIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zcGxpdC1pbXBvcnQtc3RhdGVtZW50cy5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGlzQ29uc3RydWN0aWJsZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtY29uc3RydWN0aWJsZSc7XG5pbXBvcnQgeyBzcGxpdEltcG9ydFN0YXRlbWVudHMgfSBmcm9tICcuLi9oZWxwZXJzL3NwbGl0LWltcG9ydC1zdGF0ZW1lbnRzJztcbmNvbnN0IHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzID0gKHBhcmFtZXRlckRlc2NyaXB0b3JzKSA9PiB7XG4gICAgaWYgKHBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkocGFyYW1ldGVyRGVzY3JpcHRvcnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBwYXJhbWV0ZXJEZXNjcmlwdG9ycyBwcm9wZXJ0eSBvZiBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBpcyBub3QgYW4gYXJyYXkuJyk7XG4gICAgfVxufTtcbmNvbnN0IHZlcmlmeVByb2Nlc3NvckN0b3IgPSAocHJvY2Vzc29yQ3RvcikgPT4ge1xuICAgIGlmICghaXNDb25zdHJ1Y3RpYmxlKHByb2Nlc3NvckN0b3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBzaG91bGQgYmUgYSBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgaWYgKHByb2Nlc3NvckN0b3IucHJvdG90eXBlID09PSBudWxsIHx8IHR5cGVvZiBwcm9jZXNzb3JDdG9yLnByb3RvdHlwZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGdpdmVuIHZhbHVlIGZvciBwcm9jZXNzb3JDdG9yIHNob3VsZCBoYXZlIGEgcHJvdG90eXBlLicpO1xuICAgIH1cbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGV2YWx1YXRlU291cmNlLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZmV0Y2hTb3VyY2UsIGdldE5hdGl2ZUNvbnRleHQsIGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG9uZ29pbmdSZXF1ZXN0cywgcmVzb2x2ZWRSZXF1ZXN0cywgdGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCwgd2luZG93KSA9PiB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICByZXR1cm4gKGNvbnRleHQsIG1vZHVsZVVSTCwgb3B0aW9ucyA9IHsgY3JlZGVudGlhbHM6ICdvbWl0JyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPSByZXNvbHZlZFJlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgIT09IHVuZGVmaW5lZCAmJiByZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0Lmhhcyhtb2R1bGVVUkwpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID0gb25nb2luZ1JlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdCA9IG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dC5nZXQobW9kdWxlVVJMKTtcbiAgICAgICAgICAgIGlmIChwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VPZk9uZ29pbmdSZXF1ZXN0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAvLyBCdWcgIzU5OiBTYWZhcmkgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBhdWRpb1dvcmtsZXQgcHJvcGVydHkuXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuYXRpdmVDb250ZXh0LmF1ZGlvV29ya2xldCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IGZldGNoU291cmNlKG1vZHVsZVVSTClcbiAgICAgICAgICAgICAgICAudGhlbigoW3NvdXJjZSwgYWJzb2x1dGVVcmxdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgW2ltcG9ydFN0YXRlbWVudHMsIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXSA9IHNwbGl0SW1wb3J0U3RhdGVtZW50cyhzb3VyY2UsIGFic29sdXRlVXJsKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93OlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiAkeyBpbXBvcnRTdGF0ZW1lbnRzIH07XG4gICAgICAgICAgICAgICAgICogKChhLCBiKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgIChhW2JdID0gYVtiXSB8fCBbIF0pLnB1c2goXG4gICAgICAgICAgICAgICAgICogICAgICAgICAoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLCBnbG9iYWwsIHJlZ2lzdGVyUHJvY2Vzc29yLCBzYW1wbGVSYXRlLCBzZWxmLCB3aW5kb3cpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAkeyBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyB9XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9XG4gICAgICAgICAgICAgICAgICogICAgICk7XG4gICAgICAgICAgICAgICAgICogfSkod2luZG93LCAnX0FXR1MnKTtcbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4gICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFNvdXJjZSA9IGAke2ltcG9ydFN0YXRlbWVudHN9OygoYSxiKT0+eyhhW2JdPWFbYl18fFtdKS5wdXNoKChBdWRpb1dvcmtsZXRQcm9jZXNzb3IsZ2xvYmFsLHJlZ2lzdGVyUHJvY2Vzc29yLHNhbXBsZVJhdGUsc2VsZix3aW5kb3cpPT57JHtzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c31cbn0pfSkod2luZG93LCdfQVdHUycpYDtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBFdmFsdWF0aW5nIHRoZSBnaXZlbiBzb3VyY2UgY29kZSBpcyBhIHBvc3NpYmxlIHNlY3VyaXR5IHByb2JsZW0uXG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2YWx1YXRlU291cmNlKHdyYXBwZWRTb3VyY2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSA9IHdpbmRvdy5fQVdHUy5wb3AoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lLCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUoY2xhc3MgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtcbiAgICAgICAgICAgICAgICB9LCB1bmRlZmluZWQsIChuYW1lLCBwcm9jZXNzb3JDdG9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID0gTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQcm9jZXNzb3JDdG9yKHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UGFyYW1ldGVyRGVzY3JpcHRvcnMocHJvY2Vzc29yQ3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuc2V0KG5hbWUsIHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UHJvY2Vzc29yQ3Rvcihwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzKHByb2Nlc3NvckN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLnNldChuYXRpdmVDb250ZXh0LCBuZXcgTWFwKFtbbmFtZSwgcHJvY2Vzc29yQ3Rvcl1dKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgOiBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgZmV0Y2hTb3VyY2UobW9kdWxlVVJMKSxcbiAgICAgICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQsIHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQpKVxuICAgICAgICAgICAgXSkudGhlbigoW1tzb3VyY2UsIGFic29sdXRlVXJsXSwgaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gaW5kZXggKyAxO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gY3VycmVudEluZGV4O1xuICAgICAgICAgICAgICAgIGNvbnN0IFtpbXBvcnRTdGF0ZW1lbnRzLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c10gPSBzcGxpdEltcG9ydFN0YXRlbWVudHMoc291cmNlLCBhYnNvbHV0ZVVybCk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiBjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgX19idWZmZXJzID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UgPSAoKHBvc3RNZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgcmV0dXJuIChtZXNzYWdlLCB0cmFuc2ZlcmFibGVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkVHJhbnNmZXJhYmxlcyA9ICh0cmFuc2ZlcmFibGVzKVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgPyB0cmFuc2ZlcmFibGVzLmZpbHRlcigodHJhbnNmZXJhYmxlKSA9PiAhdGhpcy5fX2J1ZmZlcnMuaGFzKHRyYW5zZmVyYWJsZSkpXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICA6IHRyYW5zZmVyYWJsZXM7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc3RNZXNzYWdlLmNhbGwodGhpcy5wb3J0LCBtZXNzYWdlLCBmaWx0ZXJlZFRyYW5zZmVyYWJsZXMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgfSkodGhpcy5wb3J0LnBvc3RNZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgfVxuICAgICAgICAgICAgICAgICAqIH1cbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgPyAnQXVkaW9Xb3JrbGV0UHJvY2Vzc29yJ1xuICAgICAgICAgICAgICAgICAgICA6ICdjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7X19iPW5ldyBXZWFrU2V0KCk7Y29uc3RydWN0b3IoKXtzdXBlcigpOyhwPT5wLnBvc3RNZXNzYWdlPShxPT4obSx0KT0+cS5jYWxsKHAsbSx0P3QuZmlsdGVyKHU9PiF0aGlzLl9fYi5oYXModSkpOnQpKShwLnBvc3RNZXNzYWdlKSkodGhpcy5wb3J0KX19JztcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTcwOiBDaHJvbWUgYW5kIEVkZ2UgZG8gY2FsbCBwcm9jZXNzKCkgd2l0aCBhbiBhcnJheSB3aXRoIGVtcHR5IGNoYW5uZWxEYXRhIGZvciBlYWNoIGlucHV0IGlmIG5vIGlucHV0IGlzIGNvbm5lY3RlZC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTc5OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRvIHRyYW5zZmVyIGFueSBidWZmZXIgd2hpY2ggaGFzIGJlZW4gcGFzc2VkIHRvIHRoZSBwcm9jZXNzKCkgbWV0aG9kIGFzIGFuIGFyZ3VtZW50LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogQnVnICMxOTA6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIHdoZW4gbG9hZGluZyBhbiB1bnBhcnNhYmxlIG1vZHVsZS5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93OlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiBgJHsgaW1wb3J0U3RhdGVtZW50cyB9O1xuICAgICAgICAgICAgICAgICAqICgoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLCByZWdpc3RlclByb2Nlc3NvcikgPT4geyR7IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzIH1cbiAgICAgICAgICAgICAgICAgKiB9KShcbiAgICAgICAgICAgICAgICAgKiAgICAgJHvCoHBhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgfSxcbiAgICAgICAgICAgICAgICAgKiAgICAgKG5hbWUsIHByb2Nlc3NvckN0b3IpID0+IHJlZ2lzdGVyUHJvY2Vzc29yKG5hbWUsIGNsYXNzIGV4dGVuZHMgcHJvY2Vzc29yQ3RvciB7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIF9fY29sbGVjdEJ1ZmZlcnMgPSAoYXJyYXkpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICBhcnJheS5mb3JFYWNoKChlbGVtZW50KSA9PiB0aGlzLl9fYnVmZmVycy5hZGQoZWxlbWVudC5idWZmZXIpKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHByb2Nlc3MgKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIGlucHV0cy5mb3JFYWNoKHRoaXMuX19jb2xsZWN0QnVmZmVycyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgb3V0cHV0cy5mb3JFYWNoKHRoaXMuX19jb2xsZWN0QnVmZmVycyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgdGhpcy5fX2NvbGxlY3RCdWZmZXJzKE9iamVjdC52YWx1ZXMocGFyYW1ldGVycykpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnByb2Nlc3MoXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIChpbnB1dHMubWFwKChpbnB1dCkgPT4gaW5wdXQuc29tZSgoY2hhbm5lbERhdGEpID0+IGNoYW5uZWxEYXRhLmxlbmd0aCA9PT0gMCkpID8gWyBdIDogaW5wdXQpLFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBvdXRwdXRzLFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICB9KVxuICAgICAgICAgICAgICAgICAqICk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiByZWdpc3RlclByb2Nlc3NvcihgX19zYWMke2N1cnJlbnRJbmRleH1gLCBjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvcntcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBwcm9jZXNzICgpIHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgKiAgICAgfVxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogfSlgXG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyRGVmaW5pdGlvbiA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlID8gJycgOiAnX19jID0gKGEpID0+IGEuZm9yRWFjaChlPT50aGlzLl9fYi5hZGQoZS5idWZmZXIpKTsnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclJlZ2lzdHJhdGlvbiA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgID8gJydcbiAgICAgICAgICAgICAgICAgICAgOiAnaS5mb3JFYWNoKHRoaXMuX19jKTtvLmZvckVhY2godGhpcy5fX2MpO3RoaXMuX19jKE9iamVjdC52YWx1ZXMocCkpOyc7XG4gICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFNvdXJjZSA9IGAke2ltcG9ydFN0YXRlbWVudHN9OygoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLHJlZ2lzdGVyUHJvY2Vzc29yKT0+eyR7c291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHN9XG59KSgke3BhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3J9LChuLHApPT5yZWdpc3RlclByb2Nlc3NvcihuLGNsYXNzIGV4dGVuZHMgcHske21lbWJlckRlZmluaXRpb259cHJvY2VzcyhpLG8scCl7JHtidWZmZXJSZWdpc3RyYXRpb259cmV0dXJuIHN1cGVyLnByb2Nlc3MoaS5tYXAoaj0+ai5zb21lKGs9PmsubGVuZ3RoPT09MCk/W106aiksbyxwKX19KSk7cmVnaXN0ZXJQcm9jZXNzb3IoJ19fc2FjJHtjdXJyZW50SW5kZXh9JyxjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3Nvcntwcm9jZXNzKCl7cmV0dXJuICExfX0pYDtcbiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3dyYXBwZWRTb3VyY2VdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04JyB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmF1ZGlvV29ya2xldFxuICAgICAgICAgICAgICAgICAgICAuYWRkTW9kdWxlKHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE4NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBhbGxvdyB0byBjcmVhdGUgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBvbiBhIGNsb3NlZCBBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LmF1ZGlvV29ya2xldC5hZGRNb2R1bGUodXJsLCBvcHRpb25zKS50aGVuKCgpID0+IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MDogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBsb2FkaW5nIGFuIHVucGFyc2FibGUgbW9kdWxlLlxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBgX19zYWMke2N1cnJlbnRJbmRleH1gKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAob25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9uZ29pbmdSZXF1ZXN0cy5zZXQoY29udGV4dCwgbmV3IE1hcChbW21vZHVsZVVSTCwgcHJvbWlzZV1dKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQuc2V0KG1vZHVsZVVSTCwgcHJvbWlzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPSByZXNvbHZlZFJlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkUmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWRSZXF1ZXN0cy5zZXQoY29udGV4dCwgbmV3IFNldChbbW9kdWxlVVJMXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQuYWRkKG1vZHVsZVVSTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID0gb25nb2luZ1JlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0LmRlbGV0ZShtb2R1bGVVUkwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8td29ya2xldC1tb2R1bGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGdldFZhbHVlRm9yS2V5ID0gKG1hcCwga2V5KSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBtYXAuZ2V0KGtleSk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHZhbHVlIHdpdGggdGhlIGdpdmVuIGtleSBjb3VsZCBub3QgYmUgZm91bmQuJyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtdmFsdWUtZm9yLWtleS5qcy5tYXAiLCJleHBvcnQgY29uc3QgcGlja0VsZW1lbnRGcm9tU2V0ID0gKHNldCwgcHJlZGljYXRlKSA9PiB7XG4gICAgY29uc3QgbWF0Y2hpbmdFbGVtZW50cyA9IEFycmF5LmZyb20oc2V0KS5maWx0ZXIocHJlZGljYXRlKTtcbiAgICBpZiAobWF0Y2hpbmdFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdNb3JlIHRoYW4gb25lIGVsZW1lbnQgd2FzIGZvdW5kLicpO1xuICAgIH1cbiAgICBpZiAobWF0Y2hpbmdFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ05vIGVsZW1lbnQgd2FzIGZvdW5kLicpO1xuICAgIH1cbiAgICBjb25zdCBbbWF0Y2hpbmdFbGVtZW50XSA9IG1hdGNoaW5nRWxlbWVudHM7XG4gICAgc2V0LmRlbGV0ZShtYXRjaGluZ0VsZW1lbnQpO1xuICAgIHJldHVybiBtYXRjaGluZ0VsZW1lbnQ7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGljay1lbGVtZW50LWZyb20tc2V0LmpzLm1hcCIsImltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gZ2V0VmFsdWVGb3JLZXkocGFzc2l2ZUlucHV0cywgc291cmNlKTtcbiAgICBjb25zdCBtYXRjaGluZ0Nvbm5lY3Rpb24gPSBwaWNrRWxlbWVudEZyb21TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQgJiYgcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gaW5wdXQpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuZGVsZXRlKHNvdXJjZSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGluZ0Nvbm5lY3Rpb247XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEVWRU5UX0xJU1RFTkVSUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShFVkVOVF9MSVNURU5FUlMsIGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFDVElWRV9BVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICBpZiAoQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQXVkaW9Ob2RlIGlzIGFscmVhZHkgc3RvcmVkLicpO1xuICAgIH1cbiAgICBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5hZGQoYXVkaW9Ob2RlKTtcbiAgICBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSkuZm9yRWFjaCgoZXZlbnRMaXN0ZW5lcikgPT4gZXZlbnRMaXN0ZW5lcih0cnVlKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNBdWRpb1dvcmtsZXROb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAncG9ydCcgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIGlmICghQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQXVkaW9Ob2RlIGlzIG5vdCBzdG9yZWQuJyk7XG4gICAgfVxuICAgIEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmRlbGV0ZShhdWRpb05vZGUpO1xuICAgIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoYXVkaW9Ob2RlKS5mb3JFYWNoKChldmVudExpc3RlbmVyKSA9PiBldmVudExpc3RlbmVyKGZhbHNlKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG4vLyBTZXQgdGhlIGludGVybmFsU3RhdGUgb2YgdGhlIGF1ZGlvTm9kZSB0byAncGFzc2l2ZScgaWYgaXQgaXMgbm90IGFuIEF1ZGlvV29ya2xldE5vZGUgYW5kIGlmIGl0IGhhcyBubyAnYWN0aXZlJyBpbnB1dCBjb25uZWN0aW9ucy5cbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeSA9IChhdWRpb05vZGUsIGFjdGl2ZUlucHV0cykgPT4ge1xuICAgIGlmICghaXNBdWRpb1dvcmtsZXROb2RlKGF1ZGlvTm9kZSkgJiYgYWN0aXZlSW5wdXRzLmV2ZXJ5KChjb25uZWN0aW9ucykgPT4gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkpIHtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZShhdWRpb05vZGUpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeS5qcy5tYXAiLCJpbXBvcnQgeyBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBZGRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAoYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRBdWRpb05vZGVUYWlsVGltZSwgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBpbnNlcnRFbGVtZW50SW5TZXQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc1BhcnRPZkFDeWNsZSwgaXNQYXNzaXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgdGFpbFRpbWVUaW1lb3V0SWRzID0gbmV3IFdlYWtNYXAoKTtcbiAgICByZXR1cm4gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQsIGlzT2ZmbGluZSkgPT4ge1xuICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShzb3VyY2UpO1xuICAgICAgICBjb25zdCBldmVudExpc3RlbmVyID0gKGlzQWN0aXZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNQYXNzaXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBpbnB1dCwgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdGFpbFRpbWUgPSBnZXRBdWRpb05vZGVUYWlsVGltZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgaWYgKHRhaWxUaW1lID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5KGRlc3RpbmF0aW9uLCBhY3RpdmVJbnB1dHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWlsVGltZVRpbWVvdXRJZCA9IHRhaWxUaW1lVGltZW91dElkcy5nZXQoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGFpbFRpbWVUaW1lb3V0SWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRhaWxUaW1lVGltZW91dElkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0YWlsVGltZVRpbWVvdXRJZHMuc2V0KGRlc3RpbmF0aW9uLCBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgdGFpbFRpbWUgKiAxMDAwKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoaW5zZXJ0RWxlbWVudEluU2V0KG91dHB1dHMsIFtkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dF0sIChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQgJiYgb3V0cHV0Q29ubmVjdGlvblsyXSA9PT0gaW5wdXQsIHRydWUpKSB7XG4gICAgICAgICAgICBldmVudExpc3RlbmVycy5hZGQoZXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChpbnNlcnRFbGVtZW50SW5TZXQpID0+IHtcbiAgICByZXR1cm4gKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gcGFzc2l2ZUlucHV0cy5nZXQoc291cmNlKTtcbiAgICAgICAgaWYgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhc3NpdmVJbnB1dHMuc2V0KHNvdXJjZSwgbmV3IFNldChbW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdXSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQgJiYgcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gaW5wdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFNpbGVudENvbm5lY3Rpb24gPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdCA9ICgpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIGRpc2Nvbm5lY3QpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB9O1xuICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1zaWxlbnQtY29ubmVjdGlvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSAoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBhdWRpb1dvcmtsZXROb2RlKSA9PiB7XG4gICAgICAgIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVDb250ZXh0KS5hZGQoYXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZmZ0U2l6ZTogMjA0OCxcbiAgICBtYXhEZWNpYmVsczogLTMwLFxuICAgIG1pbkRlY2liZWxzOiAtMTAwLFxuICAgIHNtb290aGluZ1RpbWVDb25zdGFudDogMC44XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvbk5vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBbmFseXNlck5vZGUgZXh0ZW5kcyBhdWRpb25Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgYW5hbHlzZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQW5hbHlzZXJOb2RlLCBhbmFseXNlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUgPSBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZmdFNpemUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGZmdFNpemUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZyZXF1ZW5jeUJpbkNvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4RGVjaWJlbHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzO1xuICAgICAgICB9XG4gICAgICAgIHNldCBtYXhEZWNpYmVscyh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxMTg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiBtYXhEZWNpYmVscyBpcyBub3QgbW9yZSB0aGFuIG1pbkRlY2liZWxzLlxuICAgICAgICAgICAgY29uc3QgbWF4RGVjaWJlbHMgPSB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHM7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICghKHZhbHVlID4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyA9IG1heERlY2liZWxzO1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1pbkRlY2liZWxzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscztcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWluRGVjaWJlbHModmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgICAgIGNvbnN0IG1pbkRlY2liZWxzID0gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAoISh0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPiB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMgPSBtaW5EZWNpYmVscztcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBzbW9vdGhpbmdUaW1lQ29uc3RhbnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgc21vb3RoaW5nVGltZUNvbnN0YW50KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0Qnl0ZUZyZXF1ZW5jeURhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlRnJlcXVlbmN5RGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGbG9hdEZyZXF1ZW5jeURhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGdldEZsb2F0VGltZURvbWFpbkRhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5hbHlzZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNPd25lZEJ5Q29udGV4dCA9IChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlLmNvbnRleHQgPT09IG5hdGl2ZUNvbnRleHQ7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtb3duZWQtYnktY29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQW5hbHlzZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBbmFseXNlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBbmFseXNlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBbmFseXNlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBbmFseXNlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBmZnRTaXplOiBuYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4RGVjaWJlbHM6IG5hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyxcbiAgICAgICAgICAgICAgICAgICAgbWluRGVjaWJlbHM6IG5hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscyxcbiAgICAgICAgICAgICAgICAgICAgc21vb3RoaW5nVGltZUNvbnN0YW50OiBuYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBbmFseXNlck5vZGUgPSBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBbmFseXNlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQgPSAobmF0aXZlQXVkaW9CdWZmZXIpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKG5ldyBGbG9hdDMyQXJyYXkoMSksIDAsIC0xKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW5kZXhTaXplRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW5kZXhTaXplRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LXNpemUtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW5kZXhTaXplRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgPSAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSA9ICgoZ2V0Q2hhbm5lbERhdGEpID0+IHtcbiAgICAgICAgcmV0dXJuIChjaGFubmVsKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsRGF0YS5jYWxsKGF1ZGlvQnVmZmVyLCBjaGFubmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBudW1iZXJPZkNoYW5uZWxzOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICBsZXQgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG51bGw7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvQnVmZmVyIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoMSwgMSwgNDQxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOTk6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBOb3RTdXBwb3J0ZWRFcnJvciB3aGVuIHRoZSBudW1iZXJPZkNoYW5uZWxzIGlzIHplcm8uIEJ1dCBpdCBvbmx5IGRvZXMgaXQgd2hlbiB1c2luZyB0aGVcbiAgICAgICAgICAgICAqIGZhY3RvcnkgZnVuY3Rpb24uIEJ1dCBzaW5jZSBGaXJlZm94IGFsc28gc3VwcG9ydHMgdGhlIGNvbnN0cnVjdG9yIGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGZpbmUuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIGNhY2hlVGVzdFJlc3VsdCh0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQsIHRlc3ROYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydClcbiAgICAgICAgICAgICAgICA/IG5ldyBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0pXG4gICAgICAgICAgICAgICAgOiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgLy8gQnVnICM5OTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gdGhlIG51bWJlck9mQ2hhbm5lbHMgaXMgemVyby5cbiAgICAgICAgICAgIGlmIChhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTAwOiBTYWZhcmkgZG9lcyB0aHJvdyBhIHdyb25nIGVycm9yIHdoZW4gY2FsbGluZyBnZXRDaGFubmVsRGF0YSgpIHdpdGggYW4gb3V0LW9mLWJvdW5kcyB2YWx1ZS5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNTc6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdGhlIGJ1ZmZlck9mZnNldCB0byBiZSBvdXQtb2YtYm91bmRzLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIFRoaXMgZG9lcyB2aW9sYXRlIGFsbCBnb29kIHByYXRpY2VzIGJ1dCBpdCBpcyBuZWNlc3NhcnkgdG8gYWxsb3cgdGhpcyBBdWRpb0J1ZmZlciB0byBiZSB1c2VkIHdpdGggbmF0aXZlXG4gICAgICAgICAgICAgKiAoT2ZmbGluZSlBdWRpb0NvbnRleHRzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGljIFtTeW1ib2wuaGFzSW5zdGFuY2VdKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gKChpbnN0YW5jZSAhPT0gbnVsbCAmJiB0eXBlb2YgaW5zdGFuY2UgPT09ICdvYmplY3QnICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnN0YW5jZSkgPT09IEF1ZGlvQnVmZmVyLnByb3RvdHlwZSkgfHxcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmhhcyhpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUID0gLTMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbmV4cG9ydCBjb25zdCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCA9IC1NT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50cy5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzQWN0aXZlQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4gQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hY3RpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYnVmZmVyOiBudWxsLFxuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgbG9vcDogZmFsc2UsXG4gICAgbG9vcEVuZDogMCxcbiAgICBsb29wU3RhcnQ6IDAsXG4gICAgcGxheWJhY2tSYXRlOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyID0gYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJTZXQgPSBtZXJnZWRPcHRpb25zLmJ1ZmZlciAhPT0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICAgICAgLy8gQnVnICM3MzogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHNldCBidWZmZXIodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSB2YWx1ZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzI6IE9ubHkgQ2hyb21lICYgRWRnZSBkbyBub3QgYWxsb3cgdG8gcmVhc3NpZ24gdGhlIGJ1ZmZlciB5ZXQuXG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJTZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJTZXQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wO1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wRW5kO1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wRW5kKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcFN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIuc3RhcnQgPSBkdXJhdGlvbiA9PT0gdW5kZWZpbmVkID8gW3doZW4sIG9mZnNldF0gOiBbd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KC4uLnN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHN0b3AgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wbGF5YmFja1JhdGUsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGxheWJhY2tSYXRlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBzdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0b3AodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdG9wID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0F1ZGlvQnVmZmVyU291cmNlTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BsYXliYWNrUmF0ZScgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNCaXF1YWRGaWx0ZXJOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnZnJlcXVlbmN5JyBpbiBhdWRpb05vZGUgJiYgJ2dhaW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQ29uc3RhbnRTb3VyY2VOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnb2Zmc2V0JyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzR2Fpbk5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICEoJ2ZyZXF1ZW5jeScgaW4gYXVkaW9Ob2RlKSAmJiAnZ2FpbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdhaW4tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNPc2NpbGxhdG9yTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ2RldHVuZScgaW4gYXVkaW9Ob2RlICYmICdmcmVxdWVuY3knIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vc2NpbGxhdG9yLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzU3RlcmVvUGFubmVyTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BhbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0ZXJlby1wYW5uZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFLCBhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IChhdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFLCBhdWRpb1BhcmFtKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGlzQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgaXNCaXF1YWRGaWx0ZXJOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2JpcXVhZC1maWx0ZXItbm9kZSc7XG5pbXBvcnQgeyBpc0NvbnN0YW50U291cmNlTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9jb25zdGFudC1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBpc0dhaW5Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2dhaW4tbm9kZSc7XG5pbXBvcnQgeyBpc09zY2lsbGF0b3JOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL29zY2lsbGF0b3Itbm9kZSc7XG5pbXBvcnQgeyBpc1N0ZXJlb1Bhbm5lck5vZGUgfSBmcm9tICcuLi9ndWFyZHMvc3RlcmVvLXBhbm5lci1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4vc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZSwgdHJhY2UpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICBhY3RpdmVJbnB1dHMuZm9yRWFjaCgoY29ubmVjdGlvbnMpID0+IGNvbm5lY3Rpb25zLmZvckVhY2goKFtzb3VyY2VdKSA9PiB7XG4gICAgICAgIGlmICghdHJhY2UuaW5jbHVkZXMoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoc291cmNlLCBbLi4udHJhY2UsIGF1ZGlvTm9kZV0pO1xuICAgICAgICB9XG4gICAgfSkpO1xuICAgIGNvbnN0IGF1ZGlvUGFyYW1zID0gaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICA/IFtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgYXVkaW9Ob2RlLnBsYXliYWNrUmF0ZVxuICAgICAgICBdXG4gICAgICAgIDogaXNBdWRpb1dvcmtsZXROb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgID8gQXJyYXkuZnJvbShhdWRpb05vZGUucGFyYW1ldGVycy52YWx1ZXMoKSlcbiAgICAgICAgICAgIDogaXNCaXF1YWRGaWx0ZXJOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuUSwgYXVkaW9Ob2RlLmRldHVuZSwgYXVkaW9Ob2RlLmZyZXF1ZW5jeSwgYXVkaW9Ob2RlLmdhaW5dXG4gICAgICAgICAgICAgICAgOiBpc0NvbnN0YW50U291cmNlTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5vZmZzZXRdXG4gICAgICAgICAgICAgICAgICAgIDogaXNHYWluTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuZ2Fpbl1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogaXNPc2NpbGxhdG9yTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLmRldHVuZSwgYXVkaW9Ob2RlLmZyZXF1ZW5jeV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGlzU3RlcmVvUGFubmVyTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5wYW5dXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogW107XG4gICAgZm9yIChjb25zdCBhdWRpb1BhcmFtIG9mIGF1ZGlvUGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgaWYgKGF1ZGlvUGFyYW1Db25uZWN0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhdWRpb1BhcmFtQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzLmZvckVhY2goKFtzb3VyY2VdKSA9PiBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyhzb3VyY2UsIHRyYWNlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZShhdWRpb05vZGUpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zIH0gZnJvbSAnLi9kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBkZWFjdGl2YXRlQXVkaW9HcmFwaCA9IChjb250ZXh0KSA9PiB7XG4gICAgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoY29udGV4dC5kZXN0aW5hdGlvbiwgW10pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlYWN0aXZhdGUtYXVkaW8tZ3JhcGguanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzVmFsaWRMYXRlbmN5SGludCA9IChsYXRlbmN5SGludCkgPT4ge1xuICAgIHJldHVybiAobGF0ZW5jeUhpbnQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICB0eXBlb2YgbGF0ZW5jeUhpbnQgPT09ICdudW1iZXInIHx8XG4gICAgICAgICh0eXBlb2YgbGF0ZW5jeUhpbnQgPT09ICdzdHJpbmcnICYmIChsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJyB8fCBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJykpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy12YWxpZC1sYXRlbmN5LWhpbnQuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgaXNWYWxpZExhdGVuY3lIaW50IH0gZnJvbSAnLi4vaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9Db250ZXh0IGV4dGVuZHMgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTIgU2FmYXJpIGRvZXMgdGhyb3cgYSBTeW50YXhFcnJvciBpZiB0aGUgc2FtcGxlUmF0ZSBpcyBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIgJiYgZXJyLm1lc3NhZ2UgPT09ICdzYW1wbGVSYXRlIGlzIG5vdCBpbiByYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxMzEgU2FmYXJpIHJldHVybnMgbnVsbCB3aGVuIHRoZXJlIGFyZSBmb3VyIG90aGVyIEF1ZGlvQ29udGV4dHMgcnVubmluZyBhbHJlYWR5LlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVVua25vd25FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM1MSBPbmx5IENocm9tZSBhbmQgRWRnZSB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gbGF0ZW5jeUhpbnQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgIGlmICghaXNWYWxpZExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHByb3ZpZGVkIHZhbHVlICcke29wdGlvbnMubGF0ZW5jeUhpbnR9JyBpcyBub3QgYSB2YWxpZCBlbnVtIHZhbHVlIG9mIHR5cGUgQXVkaW9Db250ZXh0TGF0ZW5jeUNhdGVnb3J5LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNTAgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgc2V0dGluZyB0aGUgc2FtcGxlUmF0ZS5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNhbXBsZVJhdGUgIT09IHVuZGVmaW5lZCAmJiBuYXRpdmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSAhPT0gb3B0aW9ucy5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvQ29udGV4dCwgMik7XG4gICAgICAgICAgICBjb25zdCB7IGxhdGVuY3lIaW50IH0gPSBvcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgeyBzYW1wbGVSYXRlIH0gPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBAdG9kbyBUaGUgdmFsdWVzIGZvciAnYmFsYW5jZWQnLCAnaW50ZXJhY3RpdmUnIGFuZCAncGxheWJhY2snIGFyZSBqdXN0IGNvcGllZCBmcm9tIENocm9tZSdzIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgdGhpcy5fYmFzZUxhdGVuY3kgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3kgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgICAgID8gbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5XG4gICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gNTEyIC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAyNTYgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDEwMjQgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogLypcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBAdG9kbyBUaGUgbWluICgyNTYpIGFuZCBtYXggKDE2Mzg0KSB2YWx1ZXMgYXJlIHRha2VuIGZyb20gdGhlIGFsbG93ZWQgYnVmZmVyU2l6ZSB2YWx1ZXMgb2YgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFNjcmlwdFByb2Nlc3Nvck5vZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWF0aC5tYXgoMiwgTWF0aC5taW4oMTI4LCBNYXRoLnJvdW5kKChsYXRlbmN5SGludCAqIHNhbXBsZVJhdGUpIC8gMTI4KSkpICogMTI4KSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQgPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBCdWcgIzE4ODogU2FmYXJpIHdpbGwgc2V0IHRoZSBjb250ZXh0J3Mgc3RhdGUgdG8gJ2ludGVycnVwdGVkJyBpbiBjYXNlIHRoZSB1c2VyIHN3aXRjaGVzIHRhYnMuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWUgPSAxZS0zNztcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5jb25uZWN0KHRoaXMuX25hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICMzNDogQ2hyb21lIGFuZCBFZGdlIHByZXRlbmQgdG8gYmUgcnVubmluZyByaWdodCBhd2F5LCBidXQgZmlyZSBhbiBvbnN0YXRlY2hhbmdlIGV2ZW50IHdoZW4gdGhlIHN0YXRlIGFjdHVhbGx5IGNoYW5nZXNcbiAgICAgICAgICAgICAqIHRvICdydW5uaW5nJy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAnc3VzcGVuZGVkJztcbiAgICAgICAgICAgICAgICBjb25zdCByZXZva2VTdGF0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgYmFzZUxhdGVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUxhdGVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlICE9PSBudWxsID8gdGhpcy5fc3RhdGUgOiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzM1OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBBdWRpb0NvbnRleHQgd2FzIGNsb3NlZCBiZWZvcmUuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzM0OiBJZiB0aGUgc3RhdGUgd2FzIHNldCB0byBzdXNwZW5kZWQgYmVmb3JlIGl0IHNob3VsZCBiZSByZXZva2VkIG5vdy5cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUdhaW5Ob2RlICE9PSBudWxsICYmIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKG1lZGlhRWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhRWxlbWVudCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UobWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhU3RyZWFtIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tTb3VyY2UobWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYVN0cmVhbVRyYWNrIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VtZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlUHJvbWlzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzdW1lKCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlc3VtZSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU1OiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIGluc3RlYWQgb2YgYW4gSW52YWxpZFN0YXRlRXJyb3IuXG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkIHx8IGVyci5jb2RlID09PSAxNSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBzdXNwZW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdXNwZW5kKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgY2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlcihyZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gaXNPZmZsaW5lO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzUyOiBDaHJvbWUsIEVkZ2UgJiBTYWZhcmkgZG8gbm90IHRocm93IGFuIGV4Y2VwdGlvbiBhdCBhbGwuXG4gICAgICAgICAgICAvLyBCdWcgIzU0OiBGaXJlZm94IGRvZXMgdGhyb3cgYW4gSW5kZXhTaXplRXJyb3IuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZG9lcyBub3QgaW5pdGlhbGl6ZSB0aGUgbWF4Q2hhbm5lbENvdW50IHByb3BlcnR5IGNvcnJlY3RseS5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzUzOiBObyBicm93c2VyIGRvZXMgdGhyb3cgYW4gZXhjZXB0aW9uIHlldC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9pc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtYXhDaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyID0gKHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIGNvbnN0IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0xpc3RlbmVyRmFjdG9yeSA9IChjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0Rmlyc3RTYW1wbGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChjb250ZXh0LCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUxpc3RlbmVyID0gbmF0aXZlQ29udGV4dC5saXN0ZW5lcjtcbiAgICAgICAgLy8gQnVnICMxMTc6IE9ubHkgQ2hyb21lICYgRWRnZSBzdXBwb3J0IHRoZSBuZXcgaW50ZXJmYWNlIGFscmVhZHkuXG4gICAgICAgIGNvbnN0IGNyZWF0ZUZha2VBdWRpb1BhcmFtcyA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoMSk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgbGV0IGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBsYXN0T3JpZW50YXRpb24gPSBbMCwgMCwgLTEsIDAsIDEsIDBdO1xuICAgICAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFswLCAwLCAwXTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCAyNTYsIDksIDApO1xuICAgICAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMyksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDUpXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0T3JpZW50YXRpb24oLi4ub3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNiksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA3KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDgpXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdG9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVMaXN0ZW5lci5zZXRQb3NpdGlvbiguLi5wb3NpdG9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTZXRPcmllbnRhdGlvbiA9IChpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbltpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0T3JpZW50YXRpb24oLi4ubGFzdE9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTZXRQb3NpdGlvbiA9IChpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbltpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0UG9zaXRpb24oLi4ubGFzdFBvc2l0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVGYWtlQXVkaW9QYXJhbSA9IChpbnB1dCwgaW5pdGlhbFZhbHVlLCBzZXRWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGluaXRpYWxWYWx1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhpcyBzaG91bGQgYmUgc3RvcHBlZCB3aGVuIHRoZSBjb250ZXh0IGlzIGNsb3NlZC5cbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgJ2RlZmF1bHRWYWx1ZScsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICM2MiAmICM3NDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgQ29uc3RhbnRTb3VyY2VOb2RlcyBhbmQgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kXG4gICAgICAgICAgICAgICAgICogbWluVmFsdWUgZm9yIEdhaW5Ob2Rlcy5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbSh7IGNvbnRleHQgfSwgaXNPZmZsaW5lLCBjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhhdWRpb1BhcmFtLCAndmFsdWUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChhdWRpb1BhcmFtKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQuY2FsbChhdWRpb1BhcmFtLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlICE9PSA5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxMTc6IFVzaW5nIHNldE9yaWVudGF0aW9uKCkgYW5kIHNldFBvc2l0aW9uKCkgZG9lc24ndCB3b3JrIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSA9ICgoY2FuY2VsQW5kSG9sZEF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjYW5jZWxBbmRIb2xkQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMgPSAoKGNhbmNlbFNjaGVkdWxlZFZhbHVlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSA9ICgoZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSA9ICgobGluZWFyUmFtcFRvVmFsdWVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUgPSAoKHNldFRhcmdldEF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRUYXJnZXRBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUgPSAoKHNldFZhbHVlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHNldFZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSA9ICgoc2V0VmFsdWVDdXJ2ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRWYWx1ZUN1cnZlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmb3J3YXJkWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMCwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMCkpLFxuICAgICAgICAgICAgICAgIGZvcndhcmRZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgxLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigxKSksXG4gICAgICAgICAgICAgICAgZm9yd2FyZFo6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDIsIC0xLCBjcmVhdGVTZXRPcmllbnRhdGlvbigyKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25YOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg2LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigwKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg3LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigxKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25aOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg4LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigyKSksXG4gICAgICAgICAgICAgICAgdXBYOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgzLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigzKSksXG4gICAgICAgICAgICAgICAgdXBZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg0LCAxLCBjcmVhdGVTZXRPcmllbnRhdGlvbig0KSksXG4gICAgICAgICAgICAgICAgdXBaOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg1LCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbig1KSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgZm9yd2FyZFgsIGZvcndhcmRZLCBmb3J3YXJkWiwgcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWiwgdXBYLCB1cFksIHVwWiB9ID0gbmF0aXZlTGlzdGVuZXIuZm9yd2FyZFggPT09IHVuZGVmaW5lZCA/IGNyZWF0ZUZha2VBdWRpb1BhcmFtcygpIDogbmF0aXZlTGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBnZXQgZm9yd2FyZFgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcndhcmRYO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBmb3J3YXJkWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZFk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGZvcndhcmRaKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3J3YXJkWjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25YKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25ZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdXBYKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1cFg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHVwWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB1cFooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVwWjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWxpc3RlbmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZU9yQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAnY29udGV4dCcgaW4gYXVkaW9Ob2RlT3JBdWRpb1BhcmFtO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGUgfSBmcm9tICcuL2F1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiA9IChvdXRwdXRDb25uZWN0aW9uKSA9PiB7XG4gICAgcmV0dXJuIGlzQXVkaW9Ob2RlKG91dHB1dENvbm5lY3Rpb25bMF0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGluc2VydEVsZW1lbnRJblNldCA9IChzZXQsIGVsZW1lbnQsIHByZWRpY2F0ZSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGZvciAoY29uc3QgbG1udCBvZiBzZXQpIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShsbW50KSkge1xuICAgICAgICAgICAgaWYgKGlnbm9yZUR1cGxpY2F0ZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignVGhlIHNldCBjb250YWlucyBhdCBsZWFzdCBvbmUgc2ltaWxhciBlbGVtZW50LicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldC5hZGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5zZXJ0LWVsZW1lbnQtaW4tc2V0LmpzLm1hcCIsImltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4vaW5zZXJ0LWVsZW1lbnQtaW4tc2V0JztcbmV4cG9ydCBjb25zdCBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgaW5zZXJ0RWxlbWVudEluU2V0KGFjdGl2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5leHBvcnQgY29uc3QgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChwYXNzaXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPSBwYXNzaXZlSW5wdXRzLmdldChzb3VyY2UpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuc2V0KHNvdXJjZSwgbmV3IFNldChbW291dHB1dCwgZXZlbnRMaXN0ZW5lcl1dKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNOYXRpdmVBdWRpb05vZGVGYWtlciA9IChuYXRpdmVBdWRpb05vZGVPck5hdGl2ZUF1ZGlvTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuICdpbnB1dHMnIGluIG5hdGl2ZUF1ZGlvTm9kZU9yTmF0aXZlQXVkaW9Ob2RlRmFrZXI7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXIuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5leHBvcnQgY29uc3QgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSkpIHtcbiAgICAgICAgY29uc3QgZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUuaW5wdXRzW2lucHV0XTtcbiAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QoZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIDApO1xuICAgICAgICByZXR1cm4gW2Zha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCAwXTtcbiAgICB9XG4gICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgIHJldHVybiBbbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXRdO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IChhY3RpdmVJbnB1dENvbm5lY3Rpb25zLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIGZvciAoY29uc3QgYWN0aXZlSW5wdXRDb25uZWN0aW9uIG9mIGFjdGl2ZUlucHV0Q29ubmVjdGlvbnMpIHtcbiAgICAgICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSB7XG4gICAgICAgICAgICBhY3RpdmVJbnB1dENvbm5lY3Rpb25zLmRlbGV0ZShhY3RpdmVJbnB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuIGFjdGl2ZUlucHV0Q29ubmVjdGlvbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24uanMubWFwIiwiaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KSA9PiB7XG4gICAgcmV0dXJuIHBpY2tFbGVtZW50RnJvbVNldChhY3RpdmVJbnB1dHMsIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUgPSAoYXVkaW9Ob2RlLCBldmVudExpc3RlbmVyKSA9PiB7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSk7XG4gICAgaWYgKCFldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnRMaXN0ZW5lcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBleHBlY3RlZCBldmVudCBsaXN0ZW5lci4nKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gZ2V0VmFsdWVGb3JLZXkocGFzc2l2ZUlucHV0cywgc291cmNlKTtcbiAgICBjb25zdCBtYXRjaGluZ0Nvbm5lY3Rpb24gPSBwaWNrRWxlbWVudEZyb21TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuZGVsZXRlKHNvdXJjZSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGluZ0Nvbm5lY3Rpb247XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmV4cG9ydCBjb25zdCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUpKSB7XG4gICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLmlucHV0c1tpbnB1dF0sIG91dHB1dCwgMCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldE5hdGl2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fTk9ERV9TVE9SRSwgYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fUEFSQU1fU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0TmF0aXZlQXVkaW9QYXJhbSA9IChhdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX1BBUkFNX1NUT1JFLCBhdWRpb1BhcmFtKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IENZQ0xFX0NPVU5URVJTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgaXNQYXJ0T2ZBQ3ljbGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIENZQ0xFX0NPVU5URVJTLmhhcyhhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBhcnQtb2YtYS1jeWNsZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzUGFzc2l2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gIUFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBhc3NpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2RTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFRoaXMgYnVnIGV4aXN0ZWQgaW4gU2FmYXJpIHVwIHVudGlsIHYxNC4wLjIuIFNpbmNlIEF1ZGlvV29ya2xldHMgd2VyZSBub3Qgc3VwcG9ydGVkIGluIFNhZmFyaSB1bnRpbCB2MTQuMSB0aGUgcHJlc2VuY2Ugb2YgdGhlXG4gICAgICAgICAqIGNvbnN0cnVjdG9yIGZvciBhbiBBdWRpb1dvcmtsZXROb2RlIGNhbiBiZSB1c2VkIGhlcmUgdG8gc2tpcCB0aGUgdGVzdC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhbmFseXplciA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoMjU2LCAxLCAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxuICAgICAgICAgICAgY29uc3QgZHVtbXkgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgLy8gQnVnICM5NTogU2FmYXJpIGRvZXMgbm90IHBsYXkgb25lIHNhbXBsZSBidWZmZXJzLlxuICAgICAgICAgICAgY29uc3Qgb25lcyA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMiwgNDQxMDApO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBvbmVzLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAgICAgY2hhbm5lbERhdGFbMF0gPSAxO1xuICAgICAgICAgICAgY2hhbm5lbERhdGFbMV0gPSAxO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICAgICAgc291cmNlLmJ1ZmZlciA9IG9uZXM7XG4gICAgICAgICAgICBzb3VyY2UubG9vcCA9IHRydWU7XG4gICAgICAgICAgICBzb3VyY2UuY29ubmVjdChhbmFseXplcikuY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgc291cmNlLmNvbm5lY3QoZHVtbXkpO1xuICAgICAgICAgICAgc291cmNlLmRpc2Nvbm5lY3QoZHVtbXkpO1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICBhbmFseXplci5vbmF1ZGlvcHJvY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNobm5sRHQgPSBldmVudC5pbnB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5wcm90b3R5cGUuc29tZS5jYWxsKGNobm5sRHQsIChzYW1wbGUpID0+IHNhbXBsZSA9PT0gMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGFuYWx5emVyLm9uYXVkaW9wcm9jZXNzID0gbnVsbDsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNjb25uZWN0KGFuYWx5emVyKTtcbiAgICAgICAgICAgICAgICBhbmFseXplci5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc291cmNlLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2Qtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZSA9IChjeWNsZXMsIHZpc2l0b3IpID0+IHtcbiAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwKCk7XG4gICAgZm9yIChjb25zdCBjeWNsZSBvZiBjeWNsZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBhdWRpb05vZGUgb2YgY3ljbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gY291bnRzLmdldChhdWRpb05vZGUpO1xuICAgICAgICAgICAgY291bnRzLnNldChhdWRpb05vZGUsIGNvdW50ID09PSB1bmRlZmluZWQgPyAxIDogY291bnQgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb3VudHMuZm9yRWFjaCgoY291bnQsIGF1ZGlvTm9kZSkgPT4gdmlzaXRvcihhdWRpb05vZGUsIGNvdW50KSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZUF1ZGlvTm9kZU9yQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAnY29udGV4dCcgaW4gbmF0aXZlQXVkaW9Ob2RlT3JBdWRpb1BhcmFtO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZCA9IChuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdCA9ICgoY29ubmVjdCkgPT4ge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkIG5vLWluZmVycmFibGUtdHlwZXNcbiAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSA/IGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpIDogY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIG5ldyBjb25uZWN0aW9uIG9ubHkgaWYgdGhlIGNhbGxzIHRvIGNvbm5lY3QgYWJvdmUgZGlkbid0IHRocm93IGFuIGVycm9yLlxuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID0gY29ubmVjdGlvbnMuZ2V0KGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIGlmIChjb25uZWN0aW9uc1RvRGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbiwgW3sgaW5wdXQsIG91dHB1dCB9XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmV2ZXJ5KChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLmlucHV0ICE9PSBpbnB1dCB8fCBjb25uZWN0aW9uLm91dHB1dCAhPT0gb3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24ucHVzaCh7IGlucHV0LCBvdXRwdXQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0LmJpbmQobmF0aXZlQXVkaW9Ob2RlKSk7XG4gICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QgPSAoKGRpc2Nvbm5lY3QpID0+IHtcbiAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgICAgICAgICBkaXNjb25uZWN0LmFwcGx5KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2Rlc3RpbmF0aW9uLCBjb25uZWN0aW9uc1RvRGVzdGluYXRpb25dIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQ29ubmVjdGlvbnMgPSBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZmlsdGVyKChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLm91dHB1dCAhPT0gZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZENvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbiwgZmlsdGVyZWRDb25uZWN0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25uZWN0aW9ucy5oYXMoZGVzdGluYXRpb25Pck91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID0gY29ubmVjdGlvbnMuZ2V0KGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQ29ubmVjdGlvbnMgPSBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZmlsdGVyKChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLm91dHB1dCAhPT0gb3V0cHV0ICYmIChjb25uZWN0aW9uLmlucHV0ICE9PSBpbnB1dCB8fCBpbnB1dCA9PT0gdW5kZWZpbmVkKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRDb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb25Pck91dHB1dCwgZmlsdGVyZWRDb25uZWN0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtkZXN0aW5hdGlvbiwgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uXSBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5mb3JFYWNoKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KGRlc3RpbmF0aW9uLCBjb25uZWN0aW9uLm91dHB1dCwgY29ubmVjdGlvbi5pbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgY29ubmVjdGlvbi5vdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX1NUT1JFLCBFVkVOVF9MSVNURU5FUlMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGlzY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS1mcm9tLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuLi9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNQYXJ0T2ZBQ3ljbGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXBhcnQtb2YtYS1jeWNsZSc7XG5pbXBvcnQgeyBpc1Bhc3NpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXBhc3NpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5JztcbmltcG9ydCB7IHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZSB9IGZyb20gJy4uL2hlbHBlcnMvdmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZCc7XG5jb25zdCBhZGRDb25uZWN0aW9uVG9BdWRpb1BhcmFtT2ZBdWRpb0NvbnRleHQgPSAoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpc09mZmxpbmUpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lciA9IChpc0FjdGl2ZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pO1xuICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgaWYgKGluc2VydEVsZW1lbnRJblNldChvdXRwdXRzLCBbZGVzdGluYXRpb24sIG91dHB1dF0sIChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIHRydWUpKSB7XG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmFkZChldmVudExpc3RlbmVyKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbmNvbnN0IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9Ob2RlID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbihhY3RpdmVJbnB1dHNbaW5wdXRdLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgIHJldHVybiBbcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsyXSwgZmFsc2VdO1xuICAgIH1cbiAgICByZXR1cm4gW2FjdGl2ZUlucHV0Q29ubmVjdGlvblsyXSwgdHJ1ZV07XG59O1xuY29uc3QgZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb1BhcmFtID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzLCBwYXNzaXZlSW5wdXRzIH0gPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbihhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICBpZiAoYWN0aXZlSW5wdXRDb25uZWN0aW9uID09PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgcmV0dXJuIFtwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzFdLCBmYWxzZV07XG4gICAgfVxuICAgIHJldHVybiBbYWN0aXZlSW5wdXRDb25uZWN0aW9uWzJdLCB0cnVlXTtcbn07XG5jb25zdCBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZSA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBbbGlzdGVuZXIsIGlzQWN0aXZlXSA9IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9Ob2RlKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpO1xuICAgIGlmIChsaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUoc291cmNlLCBsaXN0ZW5lcik7XG4gICAgICAgIGlmIChpc0FjdGl2ZSAmJiAhaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKSwgZ2V0TmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICB9XG59O1xuY29uc3QgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgW2xpc3RlbmVyLCBpc0FjdGl2ZV0gPSBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvUGFyYW0oc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlKHNvdXJjZSwgbGlzdGVuZXIpO1xuICAgICAgICBpZiAoaXNBY3RpdmUgJiYgIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSkuZGlzY29ubmVjdChnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKSwgb3V0cHV0KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5jb25zdCBkZWxldGVBbnlDb25uZWN0aW9uID0gKHNvdXJjZSwgaXNPZmZsaW5lKSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZGVzdGluYXRpb25zID0gW107XG4gICAgZm9yIChjb25zdCBvdXRwdXRDb25uZWN0aW9uIG9mIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cykge1xuICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0oc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGRlc3RpbmF0aW9ucy5wdXNoKG91dHB1dENvbm5lY3Rpb25bMF0pO1xuICAgIH1cbiAgICBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMuY2xlYXIoKTtcbiAgICByZXR1cm4gZGVzdGluYXRpb25zO1xufTtcbmNvbnN0IGRlbGV0ZUNvbm5lY3Rpb25BdE91dHB1dCA9IChzb3VyY2UsIGlzT2ZmbGluZSwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZGVzdGluYXRpb25zID0gW107XG4gICAgZm9yIChjb25zdCBvdXRwdXRDb25uZWN0aW9uIG9mIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cykge1xuICAgICAgICBpZiAob3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUoc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlc3RpbmF0aW9ucy5wdXNoKG91dHB1dENvbm5lY3Rpb25bMF0pO1xuICAgICAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmRlbGV0ZShvdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzdGluYXRpb25zO1xufTtcbmNvbnN0IGRlbGV0ZUNvbm5lY3Rpb25Ub0Rlc3RpbmF0aW9uID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cylcbiAgICAgICAgLmZpbHRlcigob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiZcbiAgICAgICAgKG91dHB1dCA9PT0gdW5kZWZpbmVkIHx8IG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkgJiZcbiAgICAgICAgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgb3V0cHV0Q29ubmVjdGlvblsyXSA9PT0gaW5wdXQpKVxuICAgICAgICAubWFwKChvdXRwdXRDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0Q29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmRlbGV0ZShvdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIG91dHB1dENvbm5lY3Rpb25bMF07XG4gICAgfSk7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yID0gKGFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBhZGRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGVjcmVtZW50Q3ljbGVDb3VudGVyLCBkZXRlY3RDeWNsZXMsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVBdWRpb1BhcmFtLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb05vZGUgZXh0ZW5kcyBldmVudFRhcmdldENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgaXNBY3RpdmUsIG5hdGl2ZUF1ZGlvTm9kZSwgYXVkaW9Ob2RlUmVuZGVyZXIpIHtcbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZSA9IG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxMjogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgdG8gZGlzY29ubmVjdCBhIHNwZWNpZmljIGRlc3RpbmF0aW9uLlxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpICYmXG4gICAgICAgICAgICAgICAgdHJ1ZSAhPT1cbiAgICAgICAgICAgICAgICAgICAgY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9KSkge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kKG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBBVURJT19OT0RFX1NUT1JFLnNldCh0aGlzLCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgRVZFTlRfTElTVEVORVJTLnNldCh0aGlzLCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgaWYgKGNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnICYmIGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnModGhpcywgYXVkaW9Ob2RlUmVuZGVyZXIsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgfVxuICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZFxuICAgICAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc0OiBTYWZhcmkgZG9lcyBleHBvc2UgYSB3cm9uZyBudW1iZXJPZk91dHB1dHMgZm9yIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVzLlxuICAgICAgICAgICAgaWYgKG91dHB1dCA8IDAgfHwgb3V0cHV0ID49IHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQodGhpcy5fY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pIHx8IGlzTmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSh0aGlzLl9uYXRpdmVBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNQYXNzaXZlID0gaXNQYXNzaXZlQXVkaW9Ob2RlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lIHx8IGlzUGFzc2l2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QoLi4uY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcgJiYgIWlzUGFzc2l2ZSAmJiBpc1Bhc3NpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0MTogU2FmYXJpIGRvZXMgbm90IHRocm93IHRoZSBjb3JyZWN0IGV4Y2VwdGlvbiBzbyBmYXIuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXNOZXdDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBhZGRDb25uZWN0aW9uVG9BdWRpb05vZGUodGhpcywgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICAgICAgaWYgKGlzTmV3Q29ubmVjdGlvblRvQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN5Y2xlcyA9IGRldGVjdEN5Y2xlcyhbdGhpc10sIGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlcihpc09mZmxpbmUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjNzMsICMxNDcgJiAjMTUzOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCB0byBjb25uZWN0IGFuIGlucHV0IHNpZ25hbCB0byB0aGUgcGxheWJhY2tSYXRlIEF1ZGlvUGFyYW0gb2YgYW5cbiAgICAgICAgICAgICAqIEF1ZGlvQnVmZmVyU291cmNlTm9kZS4gVGhpcyBjYW4ndCBiZSBlYXNpbHkgZGV0ZWN0ZWQgYW5kIHRoYXQncyB3aHkgdGhlIG91dGRhdGVkIG5hbWUgcHJvcGVydHkgaXMgdXNlZCBoZXJlIHRvIGlkZW50aWZ5XG4gICAgICAgICAgICAgKiBTYWZhcmkuIEluIGFkZGl0aW9uIHRvIHRoYXQgdGhlIG1heFZhbHVlIHByb3BlcnR5IGlzIHVzZWQgdG8gb25seSBkZXRlY3QgdGhlIGFmZmVjdGVkIHZlcnNpb25zIGJlbG93IHYxNC4wLjIuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1BhcmFtLm5hbWUgPT09ICdwbGF5YmFja1JhdGUnICYmIG5hdGl2ZUF1ZGlvUGFyYW0ubWF4VmFsdWUgPT09IDEwMjQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUgfHwgaXNQYXNzaXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTg6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaXNOZXdDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gYWRkQ29ubmVjdGlvblRvQXVkaW9QYXJhbU9mQXVkaW9Db250ZXh0KHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgIGlmIChpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjeWNsZXMgPSBkZXRlY3RDeWNsZXMoW3RoaXNdLCBkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlcihpc09mZmxpbmUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpIHtcbiAgICAgICAgICAgIGxldCBkZXN0aW5hdGlvbnM7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dCh0aGlzLl9jb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVBbnlDb25uZWN0aW9uKHRoaXMsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA8IDAgfHwgZGVzdGluYXRpb25Pck91dHB1dCA+PSB0aGlzLm51bWJlck9mT3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVDb25uZWN0aW9uQXRPdXRwdXQodGhpcywgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChvdXRwdXQgIT09IHVuZGVmaW5lZCAmJiAob3V0cHV0IDwgMCB8fCBvdXRwdXQgPj0gdGhpcy5udW1iZXJPZk91dHB1dHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSAmJiBpbnB1dCAhPT0gdW5kZWZpbmVkICYmIChpbnB1dCA8IDAgfHwgaW5wdXQgPj0gZGVzdGluYXRpb25Pck91dHB1dC5udW1iZXJPZklucHV0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQ29ubmVjdGlvblRvRGVzdGluYXRpb24odGhpcywgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZGVzdGluYXRpb24gb2YgZGVzdGluYXRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3ljbGVzID0gZGV0ZWN0Q3ljbGVzKFt0aGlzXSwgZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBkZWNyZW1lbnRDeWNsZUNvdW50ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IEF1dG9tYXRpb25FdmVudExpc3QgfSBmcm9tICdhdXRvbWF0aW9uLWV2ZW50cyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkgPSAoYWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGF1ZGlvUGFyYW1TdG9yZSwgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyLCBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50LCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGlzQXVkaW9QYXJhbU9mT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSwgbWF4VmFsdWUgPSBudWxsLCBtaW5WYWx1ZSA9IG51bGwpID0+IHtcbiAgICAgICAgLy8gQnVnICMxOTYgT25seSBTYWZhcmkgc2V0cyB0aGUgZGVmYXVsdFZhbHVlIHRvIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlO1xuICAgICAgICBjb25zdCBhdXRvbWF0aW9uRXZlbnRMaXN0ID0gbmV3IEF1dG9tYXRpb25FdmVudExpc3QoZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbVJlbmRlcmVyID0gaXNBdWRpb1BhcmFtT2ZPZmZsaW5lQXVkaW9Db250ZXh0ID8gY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyKGF1dG9tYXRpb25FdmVudExpc3QpIDogbnVsbDtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbSA9IHtcbiAgICAgICAgICAgIGdldCBkZWZhdWx0VmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1heFZhbHVlID09PSBudWxsID8gbmF0aXZlQXVkaW9QYXJhbS5tYXhWYWx1ZSA6IG1heFZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWluVmFsdWUgPT09IG51bGwgPyBuYXRpdmVBdWRpb1BhcmFtLm1pblZhbHVlIDogbWluVmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0udmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzk4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCB5ZXQgdHJlYXQgdGhlIHZhbHVlIHNldHRlciBsaWtlIGEgY2FsbCB0byBzZXRWYWx1ZUF0VGltZSgpLlxuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKGNhbmNlbFRpbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzI4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCB5ZXQgaW1wbGVtZW50IGNhbmNlbEFuZEhvbGRBdFRpbWUoKS5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXNMYXN0RXZlbnQgPSBBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudExhc3RFdmVudCA9IEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNMYXN0RXZlbnQgIT09IGN1cnJlbnRMYXN0RXZlbnQgJiYgY3VycmVudExhc3RFdmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5lbmRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ2xpbmVhclJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5lbmRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5zdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnc2V0VmFsdWVDdXJ2ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZXMsIGN1cnJlbnRMYXN0RXZlbnQuc3RhcnRUaW1lLCBjdXJyZW50TGFzdEV2ZW50LmR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTg3OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGVuZFRpbWUpIHx8IGVuZFRpbWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTQ6IEZpcmVmb3ggZG9lcyBub3QgaW1wbGljaXRseSBjYWxsIHNldFZhbHVlQXRUaW1lKCkgaWYgdGhlcmUgaXMgbm8gcHJldmlvdXMgZXZlbnQuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50KGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZShkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZW5kVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTk1OiBGaXJlZm94IGRvZXMgbm90IGltcGxpY2l0bHkgY2FsbCBzZXRWYWx1ZUF0VGltZSgpIGlmIHRoZXJlIGlzIG5vIHByZXZpb3VzIGV2ZW50LlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBlbmRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQodGFyZ2V0LCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgc3RhcnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAxODM6IFNhZmFyaSBvbmx5IGFjY2VwdHMgYSBGbG9hdDMyQXJyYXkuXG4gICAgICAgICAgICAgICAgY29uc3QgY29udmVydGVkVmFsdWVzID0gdmFsdWVzIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gdmFsdWVzIDogbmV3IEZsb2F0MzJBcnJheSh2YWx1ZXMpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICMxNTI6IFNhZmFyaSBkb2VzIG5vdCBjb3JyZWN0bHkgaW50ZXJwb2xhdGUgdGhlIHZhbHVlcyBvZiB0aGUgY3VydmUuXG4gICAgICAgICAgICAgICAgICogQHRvZG8gVW5mb3J0dW5hdGVseSB0aGVyZSBpcyBubyB3YXkgdG8gdGVzdCBmb3IgdGhpcyBiZWhhdmlvciBpbiBhIHN5bmNocm9ub3VzIGZhc2hpb24gd2hpY2ggaXMgd2h5IHRlc3RpbmcgZm9yIHRoZVxuICAgICAgICAgICAgICAgICAqIGV4aXN0ZW5jZSBvZiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBzdGFydFRpbWUgKyBkdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlUmF0ZSA9IGF1ZGlvTm9kZS5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0U2FtcGxlID0gTWF0aC5jZWlsKHN0YXJ0VGltZSAqIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXN0U2FtcGxlID0gTWF0aC5mbG9vcihlbmRUaW1lICogc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzID0gbGFzdFNhbXBsZSAtIGZpcnN0U2FtcGxlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnBvbGF0ZWRWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkludGVycG9sYXRlZFZhbHVlczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aGVvcmV0aWNJbmRleCA9ICgoY29udmVydGVkVmFsdWVzLmxlbmd0aCAtIDEpIC8gZHVyYXRpb24pICogKChmaXJzdFNhbXBsZSArIGkpIC8gc2FtcGxlUmF0ZSAtIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb3dlckluZGV4ID0gTWF0aC5mbG9vcih0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRlZFZhbHVlc1tpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGNvbnZlcnRlZFZhbHVlc1tsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogY29udmVydGVkVmFsdWVzW2xvd2VySW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIC0gKHVwcGVySW5kZXggLSB0aGVvcmV0aWNJbmRleCkpICogY29udmVydGVkVmFsdWVzW3VwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoaW50ZXJwb2xhdGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShpbnRlcnBvbGF0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lT2ZMYXN0U2FtcGxlID0gbGFzdFNhbXBsZSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aW1lT2ZMYXN0U2FtcGxlIDwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKGF1ZGlvUGFyYW0sIGludGVycG9sYXRlZFZhbHVlc1tpbnRlcnBvbGF0ZWRWYWx1ZXMubGVuZ3RoIC0gMV0sIHRpbWVPZkxhc3RTYW1wbGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZShhdWRpb1BhcmFtLCBjb252ZXJ0ZWRWYWx1ZXNbY29udmVydGVkVmFsdWVzLmxlbmd0aCAtIDFdLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoY29udmVydGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShjb252ZXJ0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXVkaW9QYXJhbVN0b3JlLnNldChhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLnNldChhdWRpb1BhcmFtLCBhdWRpb05vZGUpO1xuICAgICAgICBhZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSwgYXVkaW9QYXJhbVJlbmRlcmVyKTtcbiAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1wYXJhbS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIgPSAoYXV0b21hdGlvbkV2ZW50TGlzdCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIHJlcGxheShhdWRpb1BhcmFtKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF1dG9tYXRpb25FdmVudCBvZiBhdXRvbWF0aW9uRXZlbnRMaXN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBlbmRUaW1lLCB2YWx1ZSB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2xpbmVhclJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGVuZFRpbWUsIHZhbHVlIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFRhcmdldCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBzdGFydFRpbWUsIHRhcmdldCwgdGltZUNvbnN0YW50IH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHN0YXJ0VGltZSwgdmFsdWUgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZUN1cnZlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGR1cmF0aW9uLCBzdGFydFRpbWUsIHZhbHVlcyB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGFwcGx5IGFuIHVua25vd24gYXV0b21hdGlvbi5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1wYXJhbS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY2xhc3MgUmVhZE9ubHlNYXAge1xuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy5fbWFwID0gbmV3IE1hcChwYXJhbWV0ZXJzKTtcbiAgICB9XG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuc2l6ZTtcbiAgICB9XG4gICAgZW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5lbnRyaWVzKCk7XG4gICAgfVxuICAgIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcgPSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwga2V5LCB0aGlzKSk7XG4gICAgfVxuICAgIGdldChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhuYW1lKTtcbiAgICB9XG4gICAga2V5cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5rZXlzKCk7XG4gICAgfVxuICAgIHZhbHVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC52YWx1ZXMoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZWFkLW9ubHktbWFwLmpzLm1hcCIsImltcG9ydCB7IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgUmVhZE9ubHlNYXAgfSBmcm9tICcuLi9yZWFkLW9ubHktbWFwJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgLy8gQnVnICM2MTogVGhlIGNoYW5uZWxDb3VudE1vZGUgc2hvdWxkIGJlICdtYXgnIGFjY29yZGluZyB0byB0aGUgc3BlYyBidXQgaXMgc2V0IHRvICdleHBsaWNpdCcgdG8gYWNoaWV2ZSBjb25zaXN0ZW50IGJlaGF2aW9yLlxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG51bWJlck9mSW5wdXRzOiAxLFxuICAgIG51bWJlck9mT3V0cHV0czogMSxcbiAgICBwYXJhbWV0ZXJEYXRhOiB7fSxcbiAgICBwcm9jZXNzb3JPcHRpb25zOiB7fVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSAoYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvciwgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucywgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHksIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvV29ya2xldE5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMoeyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE5MTogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG9wdGlvbnMgYXJlbid0IGNsb25hYmxlLlxuICAgICAgICAgICAgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHkobWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPSBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc29yQ29uc3RydWN0b3IgPSBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPT09IG51bGwgfHwgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgLy8gQnVnICMxODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgYWxsb3cgdG8gY3JlYXRlIGFuIEF1ZGlvV29ya2xldE5vZGUgb24gYSBjbG9zZWQgQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGlzT2ZmbGluZSB8fCBuYXRpdmVDb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJ1xuICAgICAgICAgICAgICAgID8gbmF0aXZlQ29udGV4dFxuICAgICAgICAgICAgICAgIDogKF9hID0gZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlKG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGlzT2ZmbGluZSA/IG51bGwgOiBjb250ZXh0LmJhc2VMYXRlbmN5LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hbWUsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyKG5hbWUsIG1lcmdlZE9wdGlvbnMsIHByb2Nlc3NvckNvbnN0cnVjdG9yKSA6IG51bGwpKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBAdG9kbyBBZGQgYSBtZWNoYW5pc20gdG8gc3dpdGNoIGFuIEF1ZGlvV29ya2xldE5vZGUgdG8gcGFzc2l2ZSBvbmNlIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gb2YgdGhlIEF1ZGlvV29ya2xldFByb2Nlc3NvclxuICAgICAgICAgICAgICogcmV0dXJucyBmYWxzZS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBbXTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycy5mb3JFYWNoKChuYXRpdmVBdWRpb1BhcmFtLCBubSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgICAgICAgICAgcGFyYW1ldGVycy5wdXNoKFtubSwgYXVkaW9QYXJhbV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fcGFyYW1ldGVycyA9IG5ldyBSZWFkT25seU1hcChwYXJhbWV0ZXJzKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzg2ICYgIzg3OiBJbnZva2luZyB0aGUgcmVuZGVyZXIgb2YgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBtaWdodCBiZSBuZWNlc3NhcnkgaWYgaXQgaGFzIG5vIGRpcmVjdCBvciBpbmRpcmVjdCBjb25uZWN0aW9uIHRvXG4gICAgICAgICAgICAgKiB0aGUgZGVzdGluYXRpb24uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShuYXRpdmVDb250ZXh0LCB0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyh0aGlzKTtcbiAgICAgICAgICAgIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25wcm9jZXNzb3JlcnJvcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbnByb2Nlc3NvcmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbnByb2Nlc3NvcmVycm9yKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciA9IHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgICAgIHRoaXMuX29ucHJvY2Vzc29yZXJyb3IgPVxuICAgICAgICAgICAgICAgIG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgIT09IG51bGwgJiYgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciA9PT0gd3JhcHBlZExpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgOiBuYXRpdmVPblByb2Nlc3NvckVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYXJhbWV0ZXJzKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3BhcmFtZXRlcnMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtZXRlcnM7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvcnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wb3J0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGZ1bmN0aW9uIGNvcHlGcm9tQ2hhbm5lbChhdWRpb0J1ZmZlciwgXG4vLyBAdG9kbyBUaGVyZSBpcyBjdXJyZW50bHkgbm8gd2F5IHRvIGRlZmluZSBzb21ldGhpbmcgbGlrZSB7IFsga2V5OiBudW1iZXIgfCBzdHJpbmcgXTogRmxvYXQzMkFycmF5IH1cbnBhcmVudCwga2V5LCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpIHtcbiAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50W2tleV0gPSBuZXcgRmxvYXQzMkFycmF5KDEyOCk7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsKHBhcmVudFtrZXldLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpLlxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKTtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHBhcmVudFtrZXldID0gY2hhbm5lbERhdGEuc2xpY2UoYnVmZmVyT2Zmc2V0LCBidWZmZXJPZmZzZXQgKyAxMjgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2xpY2VkSW5wdXQgPSBuZXcgRmxvYXQzMkFycmF5KGNoYW5uZWxEYXRhLmJ1ZmZlciwgYnVmZmVyT2Zmc2V0ICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULCAxMjgpO1xuICAgICAgICAgICAgcGFyZW50W2tleV0uc2V0KHNsaWNlZElucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcHktZnJvbS1jaGFubmVsLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjb3B5VG9DaGFubmVsID0gKGF1ZGlvQnVmZmVyLCBwYXJlbnQsIGtleSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKHBhcmVudFtrZXldLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weVRvQ2hhbm5lbCgpLlxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpLnNldChwYXJlbnRba2V5XSwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb3B5LXRvLWNoYW5uZWwuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5lc3RlZEFycmF5cyA9ICh4LCB5KSA9PiB7XG4gICAgY29uc3QgYXJyYXlzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB4OyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgYXJyYXkgPSBbXTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdHlwZW9mIHkgPT09ICdudW1iZXInID8geSA6IHlbaV07XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgIGFycmF5LnB1c2gobmV3IEZsb2F0MzJBcnJheSgxMjgpKTtcbiAgICAgICAgfVxuICAgICAgICBhcnJheXMucHVzaChhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhcnJheXM7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLW5lc3RlZC1hcnJheXMuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpID0+IHtcbiAgICBjb25zdCBub2RlVG9Qcm9jZXNzb3JNYXAgPSBnZXRWYWx1ZUZvcktleShOT0RFX1RPX1BST0NFU1NPUl9NQVBTLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkobm9kZVRvUHJvY2Vzc29yTWFwLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgY29weUZyb21DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LWZyb20tY2hhbm5lbCc7XG5pbXBvcnQgeyBjb3B5VG9DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LXRvLWNoYW5uZWwnO1xuaW1wb3J0IHsgY3JlYXRlTmVzdGVkQXJyYXlzIH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGUtbmVzdGVkLWFycmF5cyc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3InO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5jb25zdCBwcm9jZXNzQnVmZmVyID0gYXN5bmMgKHByb3h5LCByZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucywgb3V0cHV0Q2hhbm5lbENvdW50LCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUpID0+IHtcbiAgICAvLyBDZWlsIHRoZSBsZW5ndGggdG8gdGhlIG5leHQgZnVsbCByZW5kZXIgcXVhbnR1bS5cbiAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgIGNvbnN0IGxlbmd0aCA9IHJlbmRlcmVkQnVmZmVyID09PSBudWxsID8gTWF0aC5jZWlsKHByb3h5LmNvbnRleHQubGVuZ3RoIC8gMTI4KSAqIDEyOCA6IHJlbmRlcmVkQnVmZmVyLmxlbmd0aDtcbiAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxDb3VudCAqIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgY29uc3QgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9IG91dHB1dENoYW5uZWxDb3VudC5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSArIHZhbHVlLCAwKTtcbiAgICBjb25zdCBwcm9jZXNzZWRCdWZmZXIgPSBudW1iZXJPZk91dHB1dENoYW5uZWxzID09PSAwXG4gICAgICAgID8gbnVsbFxuICAgICAgICA6IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mT3V0cHV0Q2hhbm5lbHMsIGxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHByb2Nlc3NvciBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhwcm94eSk7XG4gICAgY29uc3QgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gYXdhaXQgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KTtcbiAgICBjb25zdCBpbnB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZklucHV0cywgb3B0aW9ucy5jaGFubmVsQ291bnQpO1xuICAgIGNvbnN0IG91dHB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZk91dHB1dHMsIG91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgY29uc3QgcGFyYW1ldGVycyA9IEFycmF5LmZyb20ocHJveHkucGFyYW1ldGVycy5rZXlzKCkpLnJlZHVjZSgocHJtdHJzLCBuYW1lKSA9PiAoeyAuLi5wcm10cnMsIFtuYW1lXTogbmV3IEZsb2F0MzJBcnJheSgxMjgpIH0pLCB7fSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMTI4KSB7XG4gICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mSW5wdXRzID4gMCAmJiByZW5kZXJlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKHJlbmRlcmVkQnVmZmVyLCBpbnB1dHNbal0sIGssIGssIGkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCAmJiByZW5kZXJlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMuZm9yRWFjaCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKHJlbmRlcmVkQnVmZmVyLCBwYXJhbWV0ZXJzLCBuYW1lLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCwgaSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dHNbal1ba10uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRzW2pdW2tdID0gbmV3IEZsb2F0MzJBcnJheSgxMjgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcG90ZW50aWFsbHlFbXB0eUlucHV0cyA9IGlucHV0cy5tYXAoKGlucHV0LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb05vZGVDb25uZWN0aW9ucy5hY3RpdmVJbnB1dHNbaW5kZXhdLnNpemUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVNvdXJjZUZsYWcgPSBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShpIC8gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGF1ZGlvV29ya2xldFByb2Nlc3Nvci5wcm9jZXNzKHBvdGVudGlhbGx5RW1wdHlJbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpKTtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlUb0NoYW5uZWwocHJvY2Vzc2VkQnVmZmVyLCBvdXRwdXRzW2pdLCBrLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbal07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhY3RpdmVTb3VyY2VGbGFnKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBwcm94eS5kaXNwYXRjaEV2ZW50KG5ldyBFcnJvckV2ZW50KCdwcm9jZXNzb3JlcnJvcicsIHtcbiAgICAgICAgICAgICAgICBjb2xubzogZXJyb3IuY29sbm8sXG4gICAgICAgICAgICAgICAgZmlsZW5hbWU6IGVycm9yLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIGxpbmVubzogZXJyb3IubGluZW5vLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzZWRCdWZmZXI7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKG5hbWUsIG9wdGlvbnMsIHByb2Nlc3NvckNvbnN0cnVjdG9yKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBwcm9jZXNzZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICBsZXQgbmF0aXZlT3V0cHV0Tm9kZXMgPSBudWxsO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbENvdW50ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudClcbiAgICAgICAgICAgICAgICA/IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50XG4gICAgICAgICAgICAgICAgOiBBcnJheS5mcm9tKG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNjE6IE9ubHkgQ2hyb21lLCBFZGdlICYgRmlyZWZveCBoYXZlIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXROb2RlIHlldC5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZk91dHB1dENoYW5uZWxzID0gb3V0cHV0Q2hhbm5lbENvdW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm94eS5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IG91dHB1dENoYW5uZWxDb3VudFtpXVxuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jb25uZWN0ID0gY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcyk7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdCA9IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZU91dHB1dE5vZGVzID0gW291dHB1dENoYW5uZWxTcGxpdHRlck5vZGUsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcywgb3V0cHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU91dHB1dE5vZGVzID09PSBudWxsID8gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA6IG5hdGl2ZU91dHB1dE5vZGVzWzJdKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPdXRwdXROb2RlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHByb2Nlc3NvciBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZ2V0cyBub3QgaW5pdGlhbGl6ZWQgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBwcm94eS5jaGFubmVsQ291bnQgKiBwcm94eS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZQYXJhbWV0ZXJzID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZCA/IDAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlckJ1ZmZlciA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihudW1iZXJPZkNoYW5uZWxzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENlaWwgdGhlIGxlbmd0aCB0byB0aGUgbmV4dCBmdWxsIHJlbmRlciBxdWFudHVtLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguY2VpbChwcm94eS5jb250ZXh0Lmxlbmd0aCAvIDEyOCkgKiAxMjgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnYWluTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGVzLnB1c2goY3JlYXRlTmF0aXZlR2Fpbk5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluOiAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZXMgPSBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKHByb3h5LnBhcmFtZXRlcnMudmFsdWVzKCkpLm1hcChhc3luYyAoYXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBhdWRpb1BhcmFtLnZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW5Ob2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgaiwgaSAqIG9wdGlvbnMuY2hhbm5lbENvdW50ICsgaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGNvbnN0YW50U291cmNlTm9kZV0gb2YgY29uc3RhbnRTb3VyY2VOb2Rlcy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCAwLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGdhaW5Ob2Rlcy5tYXAoKGdhaW5Ob2RlKSA9PiByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIGdhaW5Ob2RlKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRCdWZmZXJQcm9taXNlID0gcHJvY2Vzc0J1ZmZlcihwcm94eSwgbnVtYmVyT2ZDaGFubmVscyA9PT0gMCA/IG51bGwgOiBhd2FpdCByZW5kZXJCdWZmZXIoKSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucywgb3V0cHV0Q2hhbm5lbENvdW50LCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBwcm9jZXNzZWRCdWZmZXIgPSBhd2FpdCBwcm9jZXNzZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLCBvdXRwdXRHYWluTm9kZV0gPSBuYXRpdmVPdXRwdXROb2RlcztcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBwcm9jZXNzZWRCdWZmZXI7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgcHJveHkubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3V0cHV0Q2hhbm5lbENvdW50W2ldOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0R2Fpbk5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbbm0sIGF1ZGlvUGFyYW1dIG9mIHByb3h5LnBhcmFtZXRlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoZSBkZWZpbml0aW9uIHRoYXQgVHlwZVNjcmlwdCB1c2VzIG9mIHRoZSBBdWRpb1BhcmFtTWFwIGlzIGxhY2tpbmcgbWFueSBtZXRob2RzLlxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnMuZ2V0KG5tKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbbm0sIGF1ZGlvUGFyYW1dIG9mIHByb3h5LnBhcmFtZXRlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIFxuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzLmdldChubSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1dvcmtsZXROb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZU9yR2Fpbk5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGFkZEF1ZGlvV29ya2xldE1vZHVsZSwgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yLCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciwgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciwgZGVjb2RlQXVkaW9EYXRhLCBkZWxheU5vZGVDb25zdHJ1Y3RvciwgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yLCBnYWluTm9kZUNvbnN0cnVjdG9yLCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IsIHBhbm5lck5vZGVDb25zdHJ1Y3RvciwgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IsIHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvciwgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBCYXNlQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICBzdXBlcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0ID0gX25hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9hdWRpb1dvcmtsZXQgPVxuICAgICAgICAgICAgICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRkTW9kdWxlOiAobW9kdWxlVVJMLCBvcHRpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEF1ZGlvV29ya2xldE1vZHVsZSh0aGlzLCBtb2R1bGVVUkwsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGdldCBhdWRpb1dvcmtsZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXVkaW9Xb3JrbGV0O1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhbmFseXNlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDaGFubmVsTWVyZ2VyKG51bWJlck9mSW5wdXRzID0gNikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbnVtYmVyT2ZJbnB1dHMgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cyA9IDYpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbnVtYmVyT2ZPdXRwdXRzIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVEZWxheShtYXhEZWxheVRpbWUgPSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGRlbGF5Tm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWF4RGVsYXlUaW1lIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGdhaW5Ob2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlSUlSRmlsdGVyKGZlZWRmb3J3YXJkLCBmZWVkYmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IodGhpcywgeyBmZWVkYmFjaywgZmVlZGZvcndhcmQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlT3NjaWxsYXRvcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVQYW5uZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBhbm5lck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMgPSB7IGRpc2FibGVOb3JtYWxpemF0aW9uOiBmYWxzZSB9KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yKHRoaXMsIHsgLi4uY29uc3RyYWludHMsIGltYWcsIHJlYWwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlU3RlcmVvUGFubmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBkZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGVBdWRpb0RhdGEodGhpcy5fbmF0aXZlQ29udGV4dCwgYXVkaW9EYXRhKS50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3VjY2Vzc0NhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVycm9yQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgUTogMSxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRldHVuZTogMCxcbiAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICBnYWluOiAwLFxuICAgIHR5cGU6ICdsb3dwYXNzJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEJpcXVhZEZpbHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGJpcXVhZEZpbHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzgwOiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fUSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLlEsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9kZXR1bmUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUsIDEyMDAgKiBNYXRoLmxvZzIoTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQpLCAtMTIwMCAqIE1hdGgubG9nMihNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCkpO1xuICAgICAgICAgICAgLy8gQnVnICM3NzogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlIGZvciBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSwgY29udGV4dC5zYW1wbGVSYXRlIC8gMiwgMCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc5OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9nYWluID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2FpbiwgNDAgKiBNYXRoLmxvZzEwKE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUKSwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkZXR1bmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV0dW5lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBnYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dhaW47XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IFEoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fUTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHR5cGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUudHlwZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxODk6IFNhZmFyaSBkb2VzIHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM2ODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBwYXJhbWV0ZXJzIGRpZmZlciBpbiB0aGVpciBsZW5ndGguXG4gICAgICAgICAgICBpZiAoZnJlcXVlbmN5SHoubGVuZ3RoICE9PSBtYWdSZXNwb25zZS5sZW5ndGggfHwgbWFnUmVzcG9uc2UubGVuZ3RoICE9PSBwaGFzZVJlc3BvbnNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUJpcXVhZEZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgUTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRldHVuZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2Fpbi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS50eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuUSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRldHVuZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuUSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ2FjaGVUZXN0UmVzdWx0ID0gKG9uZ29pbmdUZXN0cywgdGVzdFJlc3VsdHMpID0+IHtcbiAgICByZXR1cm4gKHRlc3RlciwgdGVzdCkgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZWRUZXN0UmVzdWx0ID0gdGVzdFJlc3VsdHMuZ2V0KHRlc3Rlcik7XG4gICAgICAgIGlmIChjYWNoZWRUZXN0UmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRUZXN0UmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uZ29pbmdUZXN0ID0gb25nb2luZ1Rlc3RzLmdldCh0ZXN0ZXIpO1xuICAgICAgICBpZiAob25nb2luZ1Rlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG9uZ29pbmdUZXN0O1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQgPSB0ZXN0KCk7XG4gICAgICAgICAgICBpZiAoc3luY2hyb25vdXNUZXN0UmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIG9uZ29pbmdUZXN0cy5zZXQodGVzdGVyLCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBzeW5jaHJvbm91c1Rlc3RSZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoZmluYWxUZXN0UmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG9uZ29pbmdUZXN0cy5kZWxldGUodGVzdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGVzdFJlc3VsdHMuc2V0KHRlc3RlciwgZmluYWxUZXN0UmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmFsVGVzdFJlc3VsdDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIHN5bmNocm9ub3VzVGVzdFJlc3VsdCk7XG4gICAgICAgICAgICByZXR1cm4gc3luY2hyb25vdXNUZXN0UmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2FjaGUtdGVzdC1yZXN1bHQuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBudW1iZXJPZklucHV0czogNlxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENoYW5uZWxNZXJnZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlcik7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtbWVyZ2VyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiA2LFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgIG51bWJlck9mT3V0cHV0czogNlxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ2hhbm5lbFNwbGl0dGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH0pO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtc3BsaXR0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mT3V0cHV0c1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLXNwbGl0dGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ29ubmVjdEF1ZGlvUGFyYW0gPSAocmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIHJldHVybiByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oYXVkaW9QYXJhbSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZSA9IG91dHB1dEF1ZGlvTm9kZXNbb3V0cHV0XTtcbiAgICAgICAgaWYgKG91dHB1dEF1ZGlvTm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgMCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgMCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDIsIDQ0MTAwKTtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHRydWU7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG9mZnNldDogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ29uc3RhbnRTb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSgpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSBjb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzYyICYgIzc0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBDb25zdGFudFNvdXJjZU5vZGVzIGFuZCBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWVcbiAgICAgICAgICAgICAqIGZvciBHYWluTm9kZXMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuX29mZnNldCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9mZnNldCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RhcnQod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlci5zdGFydCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdGFydChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub2Zmc2V0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9mZnNldCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gcmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgPSAodW5pdDMyQXJyYXkpID0+IHtcbiAgICByZXR1cm4gKHZhbHVlKSA9PiB7XG4gICAgICAgIHVuaXQzMkFycmF5WzBdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB1bml0MzJBcnJheVswXTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZlcnQtbnVtYmVyLXRvLXVuc2lnbmVkLWxvbmcuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGJ1ZmZlcjogbnVsbCxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGlzYWJsZU5vcm1hbGl6YXRpb246IGZhbHNlXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENvbnZvbHZlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb252b2x2ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnZvbHZlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNvbnZvbHZlck5vZGUsIGNvbnZvbHZlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZSA9IG5hdGl2ZUNvbnZvbHZlck5vZGU7XG4gICAgICAgICAgICBpZiAobWVyZ2VkT3B0aW9ucy5idWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCBtZXJnZWRPcHRpb25zLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0J1ZmZlck51bGxpZmllZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHNldCBidWZmZXIodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID0gdmFsdWU7XG4gICAgICAgICAgICAvLyBCdWcgIzExNTogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHNldCB0aGUgYnVmZmVyIHRvIG51bGwuXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgJiYgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID09PSBudWxsID8gMCA6IHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgbm9ybWFsaXplKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplO1xuICAgICAgICB9XG4gICAgICAgIHNldCBub3JtYWxpemUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVDb252b2x2ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVDb252b2x2ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUNvbnZvbHZlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVDb252b2x2ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQ29udm9sdmVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUNvbnZvbHZlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVDb252b2x2ZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZU5vcm1hbGl6YXRpb246ICFuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZUNvbnZvbHZlck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnZvbHZlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb252b2x2ZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlID0gcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbnZvbHZlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udm9sdmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE0MywgIzE0NCAmICMxNDY6IFNhZmFyaSB0aHJvd3MgYSBTeW50YXhFcnJvciB3aGVuIG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCBvciBzYW1wbGVSYXRlIGFyZSBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKGVyci5uYW1lID09PSAnU3ludGF4RXJyb3InKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZURhdGFDbG9uZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0RhdGFDbG9uZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhLWNsb25lLWVycm9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBkZXRhY2hBcnJheUJ1ZmZlciA9IChhcnJheUJ1ZmZlcikgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgY29uc3QgY2xvc2VBbmRSZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICAgICAgcG9ydDIub25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0Mi5vbm1lc3NhZ2UgPSAoKSA9PiBjbG9zZUFuZFJlc29sdmUoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGFycmF5QnVmZmVyLCBbYXJyYXlCdWZmZXJdKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgY2xvc2VBbmRSZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZXRhY2gtYXJyYXktYnVmZmVyLmpzLm1hcCIsImltcG9ydCB7IGRldGFjaEFycmF5QnVmZmVyIH0gZnJvbSAnLi4vaGVscGVycy9kZXRhY2gtYXJyYXktYnVmZmVyJztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVjb2RlQXVkaW9EYXRhID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlRGF0YUNsb25lRXJyb3IsIGNyZWF0ZUVuY29kaW5nRXJyb3IsIGRldGFjaGVkQXJyYXlCdWZmZXJzLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUNvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgdGVzdFByb21pc2VTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgcmV0dXJuIChhbnlDb250ZXh0LCBhdWRpb0RhdGEpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGlzTmF0aXZlQ29udGV4dChhbnlDb250ZXh0KSA/IGFueUNvbnRleHQgOiBnZXROYXRpdmVDb250ZXh0KGFueUNvbnRleHQpO1xuICAgICAgICAvLyBCdWcgIzQzOiBPbmx5IENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhIERhdGFDbG9uZUVycm9yLlxuICAgICAgICBpZiAoZGV0YWNoZWRBcnJheUJ1ZmZlcnMuaGFzKGF1ZGlvRGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVyciA9IGNyZWF0ZURhdGFDbG9uZUVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgYXVkaW9EYXRhIHBhcmFtZXRlciBtYXliZSBvZiBhIHR5cGUgd2hpY2ggY2FuJ3QgYmUgYWRkZWQgdG8gYSBXZWFrU2V0LlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGV0YWNoZWRBcnJheUJ1ZmZlcnMuYWRkKGF1ZGlvRGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIGlmIChjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKS50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMzOiBTYWZhcmkgZG9lcyBuZXV0ZXIgdGhlIEFycmF5QnVmZmVyLlxuICAgICAgICAgICAgICAgIGRldGFjaEFycmF5QnVmZmVyKGF1ZGlvRGF0YSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCByZXR1cm4gYSBQcm9taXNlIHlldC5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBsZXRlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMzOiBTYWZhcmkgZG9lcyBuZXV0ZXIgdGhlIEFycmF5QnVmZmVyLlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGRldGFjaEFycmF5QnVmZmVyKGF1ZGlvRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZmFpbCA9IChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICBjb21wbGV0ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMjY6IFNhZmFyaSB0aHJvd3MgYSBzeW5jaHJvbm91cyBlcnJvci5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOiBTYWZhcmkgcmVxdWlyZXMgYSBzdWNjZXNzQ2FsbGJhY2suXG4gICAgICAgICAgICAgICAgbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMDogU2FmYXJpIGRvZXMgdGhyb3cgYSB3cm9uZyBlcnJvciB3aGVuIGNhbGxpbmcgZ2V0Q2hhbm5lbERhdGEoKSB3aXRoIGFuIG91dC1vZi1ib3VuZHMgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGUoKS50aGVuKCgpID0+IHJlc29sdmUoYXVkaW9CdWZmZXIpKTtcbiAgICAgICAgICAgICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDogU2FmYXJpIHJldHVybnMgbnVsbCBpbnN0ZWFkIG9mIGFuIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGNyZWF0ZUVuY29kaW5nRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBmYWlsKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVjb2RlLWF1ZGlvLWRhdGEuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlciA9IChjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGN5Y2xlQ291bnRlcnMsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGdldE5hdGl2ZUNvbnRleHQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgY291bnQpID0+IHtcbiAgICAgICAgY29uc3QgY3ljbGVDb3VudGVyID0gY3ljbGVDb3VudGVycy5nZXQoYXVkaW9Ob2RlKTtcbiAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIGV4cGVjdGVkIGN5Y2xlIGNvdW50LicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGF1ZGlvTm9kZS5jb250ZXh0KTtcbiAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSBjb3VudCkge1xuICAgICAgICAgICAgY3ljbGVDb3VudGVycy5kZWxldGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmIGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBvdXRwdXQgb2Ygb3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0WzFdLCBvdXRwdXRbMl0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtLCBvdXRwdXRbMV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY3ljbGVDb3VudGVycy5zZXQoYXVkaW9Ob2RlLCBjeWNsZUNvdW50ZXIgLSBjb3VudCk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlY3JlbWVudC1jeWNsZS1jb3VudGVyLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRlbGF5VGltZTogMCxcbiAgICBtYXhEZWxheVRpbWU6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRGVsYXlOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVsYXlOb2RlID0gY3JlYXRlTmF0aXZlRGVsYXlOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZGVsYXlOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIobWVyZ2VkT3B0aW9ucy5tYXhEZWxheVRpbWUpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlRGVsYXlOb2RlLCBkZWxheU5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9kZWxheVRpbWUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCBtZXJnZWRPcHRpb25zLm1heERlbGF5VGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRlbGF5VGltZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWxheVRpbWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKG1heERlbGF5VGltZSkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVEZWxheU5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVEZWxheU5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZURlbGF5Tm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZURlbGF5Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRlbGF5VGltZTogbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4RGVsYXlUaW1lXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVEZWxheU5vZGUgPSBjcmVhdGVOYXRpdmVEZWxheU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRlbGF5VGltZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZWxheVRpbWUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlRGVsYXlOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEZWxheU5vZGUgPSByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRGVsYXlOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAocGlja0VsZW1lbnRGcm9tU2V0KSA9PiB7XG4gICAgcmV0dXJuIChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgICAgICByZXR1cm4gcGlja0VsZW1lbnRGcm9tU2V0KGFjdGl2ZUlucHV0c1tpbnB1dF0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSA9IChnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGF1ZGlvV29ya2xldE5vZGUpID0+IHtcbiAgICAgICAgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKG5hdGl2ZUNvbnRleHQpLmRlbGV0ZShhdWRpb1dvcmtsZXROb2RlKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNEZWxheU5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdkZWxheVRpbWUnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNEZWxheU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvZGVsYXktbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGV0ZWN0Q3ljbGVzID0gKGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldFZhbHVlRm9yS2V5KSA9PiB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGRldGVjdEN5Y2xlcyhjaGFpbiwgbmV4dExpbmspIHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlID0gaXNBdWRpb05vZGUobmV4dExpbmspID8gbmV4dExpbmsgOiBnZXRWYWx1ZUZvcktleShhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIG5leHRMaW5rKTtcbiAgICAgICAgaWYgKGlzRGVsYXlOb2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhaW5bMF0gPT09IGF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIFtjaGFpbl07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYWluLmluY2x1ZGVzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKG91dHB1dHMpXG4gICAgICAgICAgICAubWFwKChvdXRwdXRDb25uZWN0aW9uKSA9PiBkZXRlY3RDeWNsZXMoWy4uLmNoYWluLCBhdWRpb05vZGVdLCBvdXRwdXRDb25uZWN0aW9uWzBdKSlcbiAgICAgICAgICAgIC5yZWR1Y2UoKG1lcmdlZEN5Y2xlcywgbmVzdGVkQ3ljbGVzKSA9PiBtZXJnZWRDeWNsZXMuY29uY2F0KG5lc3RlZEN5Y2xlcyksIFtdKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRldGVjdC1jeWNsZXMuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUnO1xuY29uc3QgZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleCA9IChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlID0gb3V0cHV0QXVkaW9Ob2Rlc1tvdXRwdXRdO1xuICAgIGlmIChvdXRwdXRBdWRpb05vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVEaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbk9yT3V0cHV0ID0gdW5kZWZpbmVkLCBvdXRwdXQgPSB1bmRlZmluZWQsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbk9yT3V0cHV0KS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbnB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYXR0YWNrOiAwLjAwMyxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAga25lZTogMzAsXG4gICAgcmF0aW86IDEyLFxuICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgdGhyZXNob2xkOiAtMjRcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIER5bmFtaWNzQ29tcHJlc3Nvck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9hdHRhY2sgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2spO1xuICAgICAgICAgICAgdGhpcy5fa25lZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgICAgICAgICB0aGlzLl9yYXRpbyA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgIHRoaXMuX3JlbGVhc2UgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgIHRoaXMuX3RocmVzaG9sZCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAwLjAwNik7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGF0dGFjaygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdHRhY2s7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDg6IFNhZmFyaSBhbGxvd3MgYSBjaGFubmVsQ291bnQgb2YgdGhyZWUgYW5kIGFib3ZlIHdoaWNoIGlzIHdoeSB0aGUgZ2V0dGVyIGFuZCBzZXR0ZXIgbmVlZHMgdG8gYmUgb3ZlcndyaXR0ZW4gaGVyZS5cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0NoYW5uZWxDb3VudCA9IHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IDIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHByZXZpb3VzQ2hhbm5lbENvdW50O1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDk6IE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IGRpc2FsbG93IGEgY2hhbm5lbENvdW50TW9kZSBvZiAnbWF4JyB5ZXQgd2hpY2ggaXMgd2h5IHRoZSBnZXR0ZXIgYW5kIHNldHRlciBuZWVkcyB0byBiZVxuICAgICAgICAgKiBvdmVyd3JpdHRlbiBoZXJlLlxuICAgICAgICAgKi9cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0NoYW5uZWxDb3VudCA9IHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHByZXZpb3VzQ2hhbm5lbENvdW50O1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGtuZWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fa25lZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmF0aW8oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTExOiBTYWZhcmkgcmV0dXJucyBhbiBBdWRpb1BhcmFtIGluc3RlYWQgb2YgYSBudW1iZXIuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVkdWN0aW9uLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbi52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmVsZWFzZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWxlYXNlO1xuICAgICAgICB9XG4gICAgICAgIGdldCB0aHJlc2hvbGQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGhyZXNob2xkO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlXG4gICAgICAgICAgICAgKiBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBrbmVlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJhdGlvOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZDogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5hdHRhY2ssIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmtuZWUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUua25lZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yYXRpbywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yZWxlYXNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkudGhyZXNob2xkLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5hdHRhY2ssIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5rbmVlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnJhdGlvLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yZWxlYXNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnRocmVzaG9sZCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRW5jb2RpbmdFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdFbmNvZGluZ0Vycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbmNvZGluZy1lcnJvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRXZhbHVhdGVTb3VyY2UgPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChzb3VyY2UpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZCA9IHdpbmRvdy5kb2N1bWVudC5oZWFkO1xuICAgICAgICBpZiAoaGVhZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICAvLyBAdG9kbyBTYWZhcmkgZG9lc24ndCBsaWtlIFVSTHMgd2l0aCBhIHR5cGUgb2YgJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLTgnLlxuICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtzb3VyY2VdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JyB9KTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyID0gd2luZG93Lm9uZXJyb3I7XG4gICAgICAgICAgICBjb25zdCByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgd2luZG93Lm9uZXJyb3IgPSBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyO1xuICAgICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB3aW5kb3cub25lcnJvciA9IChtZXNzYWdlLCBzcmMsIGxpbmVubywgY29sbm8sIGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRWRnZSB0aGlua3MgdGhlIHNvdXJjZSBpcyB0aGUgb25lIG9mIHRoZSBodG1sIGRvY3VtZW50LlxuICAgICAgICAgICAgICAgIGlmIChzcmMgPT09IHVybCB8fCAoc3JjID09PSB3aW5kb3cubG9jYXRpb24uaHJlZiAmJiBsaW5lbm8gPT09IDEgJiYgY29sbm8gPT09IDEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVycm9yRXZlbnRMaXN0ZW5lckFuZFJldm9rZVVybCgpO1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbE9uRXJyb3JIYW5kbGVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyKG1lc3NhZ2UsIHNyYywgbGluZW5vLCBjb2xubywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzY3JpcHQub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0LnNyYyA9IHVybDtcbiAgICAgICAgICAgIHNjcmlwdC50eXBlID0gJ21vZHVsZSc7XG4gICAgICAgICAgICBoZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmFsdWF0ZS1zb3VyY2UuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3IgPSAod3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRXZlbnRUYXJnZXQge1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0ID0gX25hdGl2ZUV2ZW50VGFyZ2V0O1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSB0aGlzLl9saXN0ZW5lcnMuZ2V0KGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICBpZiAod3JhcHBlZEV2ZW50TGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnNldChsaXN0ZW5lciwgd3JhcHBlZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgd3JhcHBlZEV2ZW50TGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRpc3BhdGNoRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IGxpc3RlbmVyID09PSBudWxsID8gdW5kZWZpbmVkIDogdGhpcy5fbGlzdGVuZXJzLmdldChsaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHdyYXBwZWRFdmVudExpc3RlbmVyID09PSB1bmRlZmluZWQgPyBudWxsIDogd3JhcHBlZEV2ZW50TGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC10YXJnZXQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoY3VycmVudFRpbWUsIHNhbXBsZVJhdGUsIGZuKSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdywge1xuICAgICAgICAgICAgY3VycmVudEZyYW1lOiB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoY3VycmVudFRpbWUgKiBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY3VycmVudFRpbWU6IHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBmbigpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKHdpbmRvdyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuY3VycmVudEZyYW1lO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuY3VycmVudFRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV4cG9zZS1jdXJyZW50LWZyYW1lLWFuZC1jdXJyZW50LXRpbWUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUZldGNoU291cmNlID0gKGNyZWF0ZUFib3J0RXJyb3IpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKHVybCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFthd2FpdCByZXNwb25zZS50ZXh0KCksIHJlc3BvbnNlLnVybF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfSAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRocm93IGNyZWF0ZUFib3J0RXJyb3IoKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZldGNoLXNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZ2FpbjogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVHYWluTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEdhaW5Ob2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlR2Fpbk5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlR2Fpbk5vZGUsIGdhaW5Ob2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM3NDogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2dhaW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlR2Fpbk5vZGUuZ2FpbiwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZ2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nYWluO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVHYWluTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUdhaW5Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVHYWluTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUdhaW5Ob2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlR2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IG5hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUdhaW5Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlR2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZSA9IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVHYWluTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVHYWluTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IChhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIGdldFZhbHVlRm9yS2V5KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlKSA9PiBnZXRWYWx1ZUZvcktleShhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIgPSAoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIGlmIChhdWRpb05vZGVDb25uZWN0aW9ucy5yZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSByZW5kZXJlciBvZiB0aGUgZ2l2ZW4gQXVkaW9Ob2RlIGluIHRoZSBhdWRpbyBncmFwaC4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXVkaW9Ob2RlQ29ubmVjdGlvbnMucmVuZGVyZXI7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tbm9kZS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSAoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlKSA9PiB7IHZhciBfYTsgcmV0dXJuIChfYSA9IGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUuZ2V0KGF1ZGlvTm9kZSkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IDA7IH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRBdWRpb1BhcmFtUmVuZGVyZXIgPSAoZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgaWYgKGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5yZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSByZW5kZXJlciBvZiB0aGUgZ2l2ZW4gQXVkaW9QYXJhbSBpbiB0aGUgYXVkaW8gZ3JhcGguJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5yZW5kZXJlcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1wYXJhbS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW52YWxpZFN0YXRlRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludmFsaWQtc3RhdGUtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQgPSAoY29udGV4dFN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBjb250ZXh0U3RvcmUuZ2V0KGNvbnRleHQpO1xuICAgICAgICBpZiAobmF0aXZlQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAobmF0aXZlQ29udGV4dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBsZXQgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgIGlmIChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNDE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNyZWF0aW5nIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aCBsZXNzIHRoYW4gNDQxMDAgSHouXG4gICAgICAgIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLnNldChuYXRpdmVDb250ZXh0LCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9ICh1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAodW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNvbnRleHQgaGFzIG5vIHNldCBvZiBBdWRpb1dvcmtsZXROb2Rlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0ludmFsaWRBY2Nlc3NFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW52YWxpZC1hY2Nlc3MtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtYWNjZXNzLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwSUlSRmlsdGVyTm9kZUdldEZyZXF1ZW5jeVJlc3BvbnNlTWV0aG9kID0gKG5hdGl2ZUlJUkZpbHRlck5vZGUpID0+IHtcbiAgICBuYXRpdmVJSVJGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlID0gKChnZXRGcmVxdWVuY3lSZXNwb25zZSkgPT4ge1xuICAgICAgICByZXR1cm4gKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGZyZXF1ZW5jeUh6Lmxlbmd0aCAhPT0gbWFnUmVzcG9uc2UubGVuZ3RoIHx8IG1hZ1Jlc3BvbnNlLmxlbmd0aCAhPT0gcGhhc2VSZXNwb25zZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lSZXNwb25zZS5jYWxsKG5hdGl2ZUlJUkZpbHRlck5vZGUsIGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgd3JhcElJUkZpbHRlck5vZGVHZXRGcmVxdWVuY3lSZXNwb25zZU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2Vycydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlLCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgSUlSRmlsdGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIGlzT2ZmbGluZSA/IG51bGwgOiBjb250ZXh0LmJhc2VMYXRlbmN5LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlpckZpbHRlck5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyKG1lcmdlZE9wdGlvbnMuZmVlZGJhY2ssIG1lcmdlZE9wdGlvbnMuZmVlZGZvcndhcmQpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUlJUkZpbHRlck5vZGUsIGlpckZpbHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzIzICYgIzI0OiBGaXJlZm94RGV2ZWxvcGVyIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvci5cbiAgICAgICAgICAgIC8vIEB0b2RvIFdyaXRlIGEgdGVzdCB3aGljaCBhbGxvd3Mgb3RoZXIgYnJvd3NlcnMgdG8gcmVtYWluIHVucGF0Y2hlZC5cbiAgICAgICAgICAgIHdyYXBJSVJGaWx0ZXJOb2RlR2V0RnJlcXVlbmN5UmVzcG9uc2VNZXRob2QobmF0aXZlSUlSRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiBhcyBzaGFtZWxlc3NseSBpbnNwaXJlZCBieSBzb3VyY2UgY29kZSBvZlxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuLy8ge0BsaW5rIGh0dHBzOi8vY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMuZ2l0LysvbWFzdGVyL3RoaXJkX3BhcnR5L1dlYktpdC9Tb3VyY2UvcGxhdGZvcm0vYXVkaW8vSUlSRmlsdGVyLmNwcHxDaHJvbWl1bSdzIElJUkZpbHRlcn0uXG5leHBvcnQgY29uc3QgZmlsdGVyQnVmZmVyID0gKGZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXIsIHlCdWZmZXIsIGJ1ZmZlckluZGV4LCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgICBsZXQgaSA9IGJ1ZmZlckluZGV4O1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7IGogKz0gMSkge1xuICAgICAgICBsZXQgeSA9IGZlZWRmb3J3YXJkWzBdICogaW5wdXRbal07XG4gICAgICAgIGZvciAobGV0IGsgPSAxOyBrIDwgbWluTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHggPSAoaSAtIGspICYgKGJ1ZmZlckxlbmd0aCAtIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgICAgIHkgKz0gZmVlZGZvcndhcmRba10gKiB4QnVmZmVyW3hdO1xuICAgICAgICAgICAgeSAtPSBmZWVkYmFja1trXSAqIHlCdWZmZXJbeF07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgayA9IG1pbkxlbmd0aDsgayA8IGZlZWRmb3J3YXJkTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIHkgKz0gZmVlZGZvcndhcmRba10gKiB4QnVmZmVyWyhpIC0gaykgJiAoYnVmZmVyTGVuZ3RoIC0gMSldOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBrID0gbWluTGVuZ3RoOyBrIDwgZmVlZGJhY2tMZW5ndGg7IGsgKz0gMSkge1xuICAgICAgICAgICAgeSAtPSBmZWVkYmFja1trXSAqIHlCdWZmZXJbKGkgLSBrKSAmIChidWZmZXJMZW5ndGggLSAxKV07IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYml0d2lzZVxuICAgICAgICB9XG4gICAgICAgIHhCdWZmZXJbaV0gPSBpbnB1dFtqXTtcbiAgICAgICAgeUJ1ZmZlcltpXSA9IHk7XG4gICAgICAgIGkgPSAoaSArIDEpICYgKGJ1ZmZlckxlbmd0aCAtIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgb3V0cHV0W2pdID0geTtcbiAgICB9XG4gICAgcmV0dXJuIGk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsdGVyLWJ1ZmZlci5qcy5tYXAiLCJpbXBvcnQgeyBmaWx0ZXJCdWZmZXIgfSBmcm9tICcuLi9oZWxwZXJzL2ZpbHRlci1idWZmZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5jb25zdCBmaWx0ZXJGdWxsQnVmZmVyID0gKHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBmZWVkYmFjaywgZmVlZGZvcndhcmQpID0+IHtcbiAgICBjb25zdCBjb252ZXJ0ZWRGZWVkYmFjayA9IGZlZWRiYWNrIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGJhY2sgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRiYWNrKTtcbiAgICBjb25zdCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCA9IGZlZWRmb3J3YXJkIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGZvcndhcmQgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRmb3J3YXJkKTtcbiAgICBjb25zdCBmZWVkYmFja0xlbmd0aCA9IGNvbnZlcnRlZEZlZWRiYWNrLmxlbmd0aDtcbiAgICBjb25zdCBmZWVkZm9yd2FyZExlbmd0aCA9IGNvbnZlcnRlZEZlZWRmb3J3YXJkLmxlbmd0aDtcbiAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbihmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmRMZW5ndGgpO1xuICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSAhPT0gMSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZlZWRiYWNrTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRmb3J3YXJkW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmVlZGZvcndhcmRMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29udmVydGVkRmVlZGJhY2tbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgYnVmZmVyTGVuZ3RoID0gMzI7XG4gICAgY29uc3QgeEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICBjb25zdCB5QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgIGNvbnN0IGZpbHRlcmVkQnVmZmVyID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIocmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVscywgcmVuZGVyZWRCdWZmZXIubGVuZ3RoLCByZW5kZXJlZEJ1ZmZlci5zYW1wbGVSYXRlKTtcbiAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gcmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mQ2hhbm5lbHM7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHJlbmRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBmaWx0ZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgeEJ1ZmZlci5maWxsKDApO1xuICAgICAgICB5QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgIGZpbHRlckJ1ZmZlcihjb252ZXJ0ZWRGZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGNvbnZlcnRlZEZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyLCB5QnVmZmVyLCAwLCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpO1xuICAgIH1cbiAgICByZXR1cm4gZmlsdGVyZWRCdWZmZXI7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGZlZWRiYWNrLCBmZWVkZm9yd2FyZCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgZmlsdGVyZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVJSVJGaWx0ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUlJUkZpbHRlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICM5OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBJSVJGaWx0ZXJOb2Rlcy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUlJUkZpbHRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZUlJUkZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBkZWZpbmVzIHRoZSBwYXJhbWV0ZXJzIG9mIGNyZWF0ZUlJUkZpbHRlcigpIGFzIGFycmF5cyBvZiBudW1iZXJzLlxuICAgICAgICAgICAgICAgIG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUlJUkZpbHRlcihmZWVkZm9yd2FyZCwgZmVlZGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPT09IG51bGwgPyBuYXRpdmVJSVJGaWx0ZXJOb2RlIDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGdldHMgbm90IGluaXRpYWxpemVkIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICAgICAgcHJveHkuY29udGV4dC5kZXN0aW5hdGlvbi5jaGFubmVsQ291bnQsIFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgICAgICAgICBwcm94eS5jb250ZXh0Lmxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWRCdWZmZXJQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWRCdWZmZXIgPSBhd2FpdCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJGdWxsQnVmZmVyKHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBmZWVkYmFjaywgZmVlZGZvcndhcmQpO1xuICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZEJ1ZmZlciA9IGF3YWl0IGZpbHRlcmVkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gZmlsdGVyZWRCdWZmZXI7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlSUlSRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1paXItZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbic7XG5leHBvcnQgY29uc3QgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeSA9IChjeWNsZUNvdW50ZXJzLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgaXNBY3RpdmVBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKGlzT2ZmbGluZSkgPT4ge1xuICAgICAgICByZXR1cm4gKGF1ZGlvTm9kZSwgY291bnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN5Y2xlQ291bnRlciA9IGN5Y2xlQ291bnRlcnMuZ2V0KGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiBpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0WzFdLCBvdXRwdXRbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSwgb3V0cHV0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjeWNsZUNvdW50ZXJzLnNldChhdWRpb05vZGUsIGNvdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuc2V0KGF1ZGlvTm9kZSwgY3ljbGVDb3VudGVyICsgY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQgPSAoY29udGV4dFN0b3JlLCBpc05hdGl2ZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGNvbnRleHRTdG9yZS5nZXQoYW55dGhpbmcpO1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgfHwgaXNOYXRpdmVBdWRpb0NvbnRleHQoYW55dGhpbmcpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYW55LWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55QXVkaW9Ob2RlID0gKGF1ZGlvTm9kZVN0b3JlLCBpc05hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IGF1ZGlvTm9kZVN0b3JlLmhhcyhhbnl0aGluZykgfHwgaXNOYXRpdmVBdWRpb05vZGUoYW55dGhpbmcpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueUF1ZGlvUGFyYW0gPSAoYXVkaW9QYXJhbVN0b3JlLCBpc05hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiBhdWRpb1BhcmFtU3RvcmUuaGFzKGFueXRoaW5nKSB8fCBpc05hdGl2ZUF1ZGlvUGFyYW0oYW55dGhpbmcpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNvbnRleHRTdG9yZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gY29udGV4dFN0b3JlLmdldChhbnl0aGluZyk7XG4gICAgICAgIHJldHVybiBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgfHwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGFueXRoaW5nKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvTm9kZSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB3aW5kb3cgIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvdy5BdWRpb05vZGUgPT09ICdmdW5jdGlvbicgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiB3aW5kb3cuQXVkaW9Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9QYXJhbSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB3aW5kb3cgIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvdy5BdWRpb1BhcmFtID09PSAnZnVuY3Rpb24nICYmIGFueXRoaW5nIGluc3RhbmNlb2Ygd2luZG93LkF1ZGlvUGFyYW07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQ29udGV4dCA9IChpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVBdWRpb0NvbnRleHQoYW55dGhpbmcpIHx8IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChhbnl0aGluZyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCA9ICh3aW5kb3cpID0+IHdpbmRvdyAhPT0gbnVsbCAmJiB3aW5kb3cuaXNTZWN1cmVDb250ZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtc2VjdXJlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgLy8gQnVnICMxNzE6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1lZGlhRWxlbWVudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUubWVkaWFFbGVtZW50O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2Vycydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICAvLyBCdWcgIzE3MzogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0cmVhbSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLnN0cmVhbTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTcyOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtZWRpYVN0cmVhbSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZS5tZWRpYVN0cmVhbTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgaXNWYWxpZExhdGVuY3lIaW50IH0gZnJvbSAnLi4vaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWluaW1hbEF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MiBTYWZhcmkgZG9lcyB0aHJvdyBhIFN5bnRheEVycm9yIGlmIHRoZSBzYW1wbGVSYXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMiAmJiBlcnIubWVzc2FnZSA9PT0gJ3NhbXBsZVJhdGUgaXMgbm90IGluIHJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzEzMSBTYWZhcmkgcmV0dXJucyBudWxsIHdoZW4gdGhlcmUgYXJlIGZvdXIgb3RoZXIgQXVkaW9Db250ZXh0cyBydW5uaW5nIGFscmVhZHkuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlVW5rbm93bkVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzUxIE9ubHkgQ2hyb21lIGFuZCBFZGdlIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiBsYXRlbmN5SGludCBpcyBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgcHJvdmlkZWQgdmFsdWUgJyR7b3B0aW9ucy5sYXRlbmN5SGludH0nIGlzIG5vdCBhIHZhbGlkIGVudW0gdmFsdWUgb2YgdHlwZSBBdWRpb0NvbnRleHRMYXRlbmN5Q2F0ZWdvcnkuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE1MCBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBzZXR0aW5nIHRoZSBzYW1wbGVSYXRlLlxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2FtcGxlUmF0ZSAhPT0gdW5kZWZpbmVkICYmIG5hdGl2ZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlICE9PSBvcHRpb25zLnNhbXBsZVJhdGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlQXVkaW9Db250ZXh0LCAyKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbGF0ZW5jeUhpbnQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHNhbXBsZVJhdGUgfSA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEB0b2RvIFRoZSB2YWx1ZXMgZm9yICdiYWxhbmNlZCcsICdpbnRlcmFjdGl2ZScgYW5kICdwbGF5YmFjaycgYXJlIGp1c3QgY29waWVkIGZyb20gQ2hyb21lJ3MgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgICB0aGlzLl9iYXNlTGF0ZW5jeSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeSA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICAgICAgPyBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3lcbiAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyA1MTIgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnaW50ZXJhY3RpdmUnIHx8IGxhdGVuY3lIaW50ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDI1NiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAncGxheWJhY2snXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMTAyNCAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAvKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEB0b2RvIFRoZSBtaW4gKDI1NikgYW5kIG1heCAoMTYzODQpIHZhbHVlcyBhcmUgdGFrZW4gZnJvbSB0aGUgYWxsb3dlZCBidWZmZXJTaXplIHZhbHVlcyBvZiBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogU2NyaXB0UHJvY2Vzc29yTm9kZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNYXRoLm1heCgyLCBNYXRoLm1pbigxMjgsIE1hdGgucm91bmQoKGxhdGVuY3lIaW50ICogc2FtcGxlUmF0ZSkgLyAxMjgpKSkgKiAxMjgpIC8gc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg4OiBTYWZhcmkgd2lsbCBzZXQgdGhlIGNvbnRleHQncyBzdGF0ZSB0byAnaW50ZXJydXB0ZWQnIGluIGNhc2UgdGhlIHVzZXIgc3dpdGNoZXMgdGFicy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZ2Fpbi52YWx1ZSA9IDFlLTM3O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmNvbm5lY3QodGhpcy5fbmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzM0OiBDaHJvbWUgYW5kIEVkZ2UgcHJldGVuZCB0byBiZSBydW5uaW5nIHJpZ2h0IGF3YXksIGJ1dCBmaXJlIGFuIG9uc3RhdGVjaGFuZ2UgZXZlbnQgd2hlbiB0aGUgc3RhdGUgYWN0dWFsbHkgY2hhbmdlc1xuICAgICAgICAgICAgICogdG8gJ3J1bm5pbmcnLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdzdXNwZW5kZWQnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJldm9rZVN0YXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBiYXNlTGF0ZW5jeSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9iYXNlTGF0ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgIT09IG51bGwgPyB0aGlzLl9zdGF0ZSA6IHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBjbG9zZSgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMzU6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIEF1ZGlvQ29udGV4dCB3YXMgY2xvc2VkIGJlZm9yZS5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMzQ6IElmIHRoZSBzdGF0ZSB3YXMgc2V0IHRvIHN1c3BlbmRlZCBiZWZvcmUgaXQgc2hvdWxkIGJlIHJldm9rZWQgbm93LlxuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlR2Fpbk5vZGUgIT09IG51bGwgJiYgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUF1ZGlvR3JhcGgodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bWUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZVByb21pc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VtZSgpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZXN1bWUoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NTogQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciBpbnN0ZWFkIG9mIGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCB8fCBlcnIuY29kZSA9PT0gMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3VzcGVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3VzcGVuZCgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBDT05URVhUX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0xpc3RlbmVyLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxCYXNlQXVkaW9Db250ZXh0IGV4dGVuZHMgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICBzdXBlcihfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0ID0gX25hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICBDT05URVhUX1NUT1JFLnNldCh0aGlzLCBfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KF9uYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUuc2V0KF9uYXRpdmVDb250ZXh0LCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZGVzdGluYXRpb24gPSBuZXcgYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3Rvcih0aGlzLCBudW1iZXJPZkNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyID0gY3JlYXRlQXVkaW9MaXN0ZW5lcih0aGlzLCBfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLl9vbnN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGVzdGluYXRpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVzdGluYXRpb247XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xpc3RlbmVyO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbnN0YXRlY2hhbmdlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uc3RhdGVjaGFuZ2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uc3RhdGVjaGFuZ2UodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPblN0YXRlQ2hhbmdlID0gdGhpcy5fbmF0aXZlQ29udGV4dC5vbnN0YXRlY2hhbmdlO1xuICAgICAgICAgICAgdGhpcy5fb25zdGF0ZWNoYW5nZSA9IG5hdGl2ZU9uU3RhdGVDaGFuZ2UgIT09IG51bGwgJiYgbmF0aXZlT25TdGF0ZUNoYW5nZSA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPblN0YXRlQ2hhbmdlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RQcm9taXNlU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgLy8gVGhpcyAxMiBudW1iZXJzIHJlcHJlc2VudCB0aGUgNDggYnl0ZXMgb2YgYW4gZW1wdHkgV0FWRSBmaWxlIHdpdGggYSBzaW5nbGUgc2FtcGxlLlxuICAgIGNvbnN0IHVpbnQzMkFycmF5ID0gbmV3IFVpbnQzMkFycmF5KFsxMTc5MDExNDEwLCA0MCwgMTE2MzI4MDcyNywgNTQ0NTAxMDk0LCAxNiwgMTMxMDczLCA0NDEwMCwgMTc2NDAwLCAxMDQ4NTgwLCAxNjM1MDE3MDYwLCA0LCAwXSk7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gQnVnICMxOiBTYWZhcmkgcmVxdWlyZXMgYSBzdWNjZXNzQ2FsbGJhY2suXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuYXRpdmVDb250ZXh0LmRlY29kZUF1ZGlvRGF0YSh1aW50MzJBcnJheS5idWZmZXIsICgpID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgc3VjY2VzcyBjYWxsYmFjay5cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwcm9taXNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBwcm9taXNlLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSByZWplY3RlZCBlcnJvcnMuXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1wcm9taXNlLXN1cHBvcnQuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbnVtYmVyT2ZDaGFubmVsczogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHN0YXJ0UmVuZGVyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vICMyMSBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyBhbmQgdGhlcmVmb3JlIHdvdWxkIGZpcmUgdGhlIHN0YXRlY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgcHJvbWlzZSBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXlTdGF0ZUNoYW5nZUV2ZW50O1xuICAgICAgICAgICAgICAgIH0pKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IG51bGwgPyB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXRlIDogdGhpcy5fc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSZW5kZXJpbmcoKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5ICYgIzU5OiBJdCBpcyB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlIHRoYXQgc3RhcnRSZW5kZXJpbmcoKSB3aWxsIGZpcnN0IHJlbmRlciBhIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LiBUaGVyZWZvcmVcbiAgICAgICAgICAgICAqIHRoZSBzdGF0ZSBvZiB0aGUgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCBtaWdodCBubyB0cmFuc2l0aW9uIHRvIHJ1bm5pbmcgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAncnVubmluZyc7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnRSZW5kZXJpbmcodGhpcy5kZXN0aW5hdGlvbiwgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1vbml0b3JDb25uZWN0aW9ucyA9IChpbnNlcnRFbGVtZW50SW5TZXQsIGlzTmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb05vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0ID0gKChjb25uZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkIG5vLWluZmVycmFibGUtdHlwZXNcbiAgICAgICAgICAgIHJldHVybiAoZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdhc0Rpc2Nvbm5lY3RlZCA9IGNvbm5lY3Rpb25zLnNpemUgPT09IDA7XG4gICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGNvbm5lY3Rpb25zLCBbZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXRdLCAoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0ICYmIGNvbm5lY3Rpb25bMl0gPT09IGlucHV0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdhc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hlbkNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGNvbm5lY3Rpb25zLCBbZGVzdGluYXRpb24sIG91dHB1dF0sIChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmICh3YXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hlbkNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShuYXRpdmVBdWRpb05vZGUuY29ubmVjdCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0ID0gKChkaXNjb25uZWN0KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB3YXNDb25uZWN0ZWQgPSBjb25uZWN0aW9ucy5zaXplID4gMDtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuYXBwbHkobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDEgYXJndW1lbnQgeWV0LlxuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvblsxXSA9PT0gZGVzdGluYXRpb25Pck91dHB1dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDIgYXJndW1lbnRzIHlldC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb25Pck91dHB1dCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvdXRwdXQgPT09IHVuZGVmaW5lZCB8fCBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgY29ubmVjdGlvblsyXSA9PT0gaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlzRGlzY29ubmVjdGVkID0gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMDtcbiAgICAgICAgICAgICAgICBpZiAod2FzQ29ubmVjdGVkICYmIGlzRGlzY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoZW5EaXNjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tb25pdG9yLWNvbm5lY3Rpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCBvcHRpb24pID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbb3B0aW9uXTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbmF0aXZlQXVkaW9Ob2RlW29wdGlvbl0pIHtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlW29wdGlvbl0gPSB2YWx1ZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zKSA9PiB7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxDb3VudCcpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsQ291bnRNb2RlJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQgPSAobmF0aXZlQW5hbHlzZXJOb2RlKSA9PiB7XG4gICAgcmV0dXJuIHR5cGVvZiBuYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSA9PT0gJ2Z1bmN0aW9uJztcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kID0gKG5hdGl2ZUFuYWx5c2VyTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhID0gKGFycmF5KSA9PiB7XG4gICAgICAgIGNvbnN0IGJ5dGVUaW1lRG9tYWluRGF0YSA9IG5ldyBVaW50OEFycmF5KGFycmF5Lmxlbmd0aCk7XG4gICAgICAgIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlVGltZURvbWFpbkRhdGEoYnl0ZVRpbWVEb21haW5EYXRhKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5tYXgoYnl0ZVRpbWVEb21haW5EYXRhLmxlbmd0aCwgbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBhcnJheVtpXSA9IChieXRlVGltZURvbWFpbkRhdGFbaV0gLSAxMjgpICogMC4wMDc4MTI1O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5ID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgICAgICAvLyBCdWcgIzM3OiBGaXJlZm94IGRvZXMgbm90IGNyZWF0ZSBhbiBBbmFseXNlck5vZGUgd2l0aCB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgaWYgKCEob3B0aW9ucy5tYXhEZWNpYmVscyA+IG9wdGlvbnMubWluRGVjaWJlbHMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdmZnRTaXplJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdtYXhEZWNpYmVscycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnbWluRGVjaWJlbHMnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ3Ntb290aGluZ1RpbWVDb25zdGFudCcpO1xuICAgICAgICAvLyBCdWcgIzM2OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBnZXRGbG9hdFRpbWVEb21haW5EYXRhKCkgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQsICgpID0+IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydChuYXRpdmVBbmFseXNlck5vZGUpKSkge1xuICAgICAgICAgICAgd3JhcEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2QobmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb0J1ZmZlcicpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuQXVkaW9CdWZmZXI7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSA9IChuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsIGF1ZGlvUGFyYW0pID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbYXVkaW9QYXJhbV07XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG5hdGl2ZUF1ZGlvTm9kZVthdWRpb1BhcmFtXS52YWx1ZSkge1xuICAgICAgICBuYXRpdmVBdWRpb05vZGVbYXVkaW9QYXJhbV0udmFsdWUgPSB2YWx1ZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMgPSAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0ID0gKChzdGFydCkgPT4ge1xuICAgICAgICBsZXQgaXNTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmIChpc1NjaGVkdWxlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICBpc1NjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyA9IChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RhcnQgPSAoKHN0YXJ0KSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoKHR5cGVvZiBkdXJhdGlvbiA9PT0gJ251bWJlcicgJiYgZHVyYXRpb24gPCAwKSB8fCBvZmZzZXQgPCAwIHx8IHdoZW4gPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgcGFyYW1ldGVycyBjYW4ndCBiZSBuZWdhdGl2ZS5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgPSAobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3AgPSAoKHN0b3ApID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCkgPT4ge1xuICAgICAgICAgICAgaWYgKHdoZW4gPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgcGFyYW1ldGVyIGNhbid0IGJlIG5lZ2F0aXZlLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGxpbmcsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyLCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAncGxheWJhY2tSYXRlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdidWZmZXInKTtcbiAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wRW5kJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wU3RhcnQnKTtcbiAgICAgICAgLy8gQnVnICM2OTogU2FmYXJpIGRvZXMgYWxsb3cgY2FsbHMgdG8gc3RhcnQoKSBvZiBhbiBhbHJlYWR5IHNjaGVkdWxlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE1NCAmICMxNTU6IFNhZmFyaSBkb2VzIG5vdCBoYW5kbGUgb2Zmc2V0cyB3aGljaCBhcmUgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1wbGluZyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTYyOiBTYWZhcmkgZG9lcyB0aHJvdyBhbiBlcnJvciB3aGVuIHN0b3AoKSBpcyBjYWxsZWQgb24gYW4gQXVkaW9CdWZmZXJTb3VyY2VOb2RlIHdoaWNoIGhhcyBubyBidWZmZXIgYXNzaWduZWQgdG8gaXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTk6IFNhZmFyaSBkb2VzIG5vdCBpZ25vcmUgY2FsbHMgdG8gc3RvcCgpIG9mIGFuIGFscmVhZHkgc3RvcHBlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ0F1ZGlvQ29udGV4dCcpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuQXVkaW9Db250ZXh0O1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCd3ZWJraXRBdWRpb0NvbnRleHQnKSA/IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQgOiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICAvLyBCdWcgIzEzMjogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50LlxuICAgICAgICBpZiAobmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ICE9PSBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY5OiBTYWZhcmkgdGhyb3dzIGFuIGVycm9yIG9uIGVhY2ggYXR0ZW1wdCB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzgzOiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnRNb2RlLlxuICAgICAgICBpZiAoaXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ICYmIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZG9lcyBub3QgaW5pdGlhbGl6ZSB0aGUgbWF4Q2hhbm5lbENvdW50IHByb3BlcnR5IGNvcnJlY3RseS5cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLCAnbWF4Q2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBjaGFubmVsQ291bnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTY4OiBObyBicm93c2VyIGRvZXMgeWV0IGhhdmUgYW4gQXVkaW9EZXN0aW5hdGlvbk5vZGUgd2l0aCBhbiBvdXRwdXQuXG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICB9KTtcbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKGdhaW5Ob2RlLCAnY2hhbm5lbENvdW50JywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoZ2Fpbk5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKGdhaW5Ob2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY5OiBTYWZhcmkgdGhyb3dzIGFuIGVycm9yIG9uIGVhY2ggYXR0ZW1wdCB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChnYWluTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwoZ2Fpbk5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGdhaW5Ob2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChnYWluTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2Fpbk5vZGUsICdtYXhDaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQHRvZG8gVGhpcyBzaG91bGQgYmUgZGlzY29ubmVjdGVkIHdoZW4gdGhlIGNvbnRleHQgaXMgY2xvc2VkLlxuICAgICAgICBnYWluTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgcmV0dXJuIGdhaW5Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb1dvcmtsZXROb2RlJykgPyB3aW5kb3cuQXVkaW9Xb3JrbGV0Tm9kZSA6IG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdENsb25hYmlsaXR5T2ZBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDEucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1jbG9uYWJpbGl0eS1vZi1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0Q2xvbmFiaWxpdHlPZkF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWNsb25hYmlsaXR5LW9mLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmFtZSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVDb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICAgICAgbGV0IG9ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHtcbiAgICAgICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgICAgICogQnVnICM2MTogT3ZlcndyaXRpbmcgdGhlIHByb3BlcnR5IGFjY2Vzc29ycyBmb3IgY2hhbm5lbENvdW50IGFuZCBjaGFubmVsQ291bnRNb2RlIGlzIG5lY2Vzc2FyeSBhcyBsb25nIGFzIHNvbWVcbiAgICAgICAgICAgICAgICAgICAgICogYnJvd3NlcnMgaGF2ZSBubyBuYXRpdmUgaW1wbGVtZW50YXRpb24gdG8gYWNoaWV2ZSBhIGNvbnNpc3RlbnQgYmVoYXZpb3IuXG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE1NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCB5ZXQgZmlyZSBhbiBFcnJvckV2ZW50LlxuICAgICAgICAgICAgICAgICAgICBvbnByb2Nlc3NvcmVycm9yOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IG9ucHJvY2Vzc29yZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ucHJvY2Vzc29yZXJyb3IgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUuYWRkRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIgPSAoKGFkZEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ3Byb2Nlc3NvcmVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgYXJnc1sxXSA9PT0gJ29iamVjdCcgJiYgYXJnc1sxXSAhPT0gbnVsbCAmJiB0eXBlb2YgYXJnc1sxXS5oYW5kbGVFdmVudCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdLmhhbmRsZUV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IHBhdGNoZWRFdmVudExpc3RlbmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGV2ZW50LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB7IHZhbHVlOiAncHJvY2Vzc29yZXJyb3InIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lcihuZXcgRXJyb3JFdmVudChhcmdzWzBdLCB7IC4uLmV2ZW50IH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLnNldCh1bnBhdGNoZWRFdmVudExpc3RlbmVyLCBhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsICdlcnJvcicsIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9ICgocmVtb3ZlRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAncHJvY2Vzc29yZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5kZWxldGUoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAnZXJyb3InLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgaW52b2tlIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gaWYgdGhlIGNvcnJlc3BvbmRpbmcgQXVkaW9Xb3JrbGV0Tm9kZSBpcyB1bmNvbm5lY3RlZCBidXRcbiAgICAgICAgICAgICAgICAgKiBoYXMgYW4gb3V0cHV0LlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mT3V0cHV0cyAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBnYWluOiAwXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiBuYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBuYXRpdmVHYWluTm9kZS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBEaXNjb25uZWN0IHRoZSBjb25uZWN0aW9uIHdoZW4gdGhlIHByb2Nlc3MoKSBmdW5jdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSByZXR1cm5zIGZhbHNlLlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYwOiBDaHJvbWUgJiBFZGdlIHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIGluc3RlYWQgb2YgYSBOb3RTdXBwb3J0ZWRFcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDExKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzYxOiBPbmx5IENocm9tZSAmIEVkZ2UgaGF2ZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB5ZXQuXG4gICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHRlc3RDbG9uYWJpbGl0eU9mQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY29tcHV0ZUJ1ZmZlclNpemUgPSAoYmFzZUxhdGVuY3ksIHNhbXBsZVJhdGUpID0+IHtcbiAgICBpZiAoYmFzZUxhdGVuY3kgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDUxMjtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGgubWF4KDUxMiwgTWF0aC5taW4oMTYzODQsIE1hdGgucG93KDIsIE1hdGgucm91bmQoTWF0aC5sb2cyKGJhc2VMYXRlbmN5ICogc2FtcGxlUmF0ZSkpKSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbXB1dGUtYnVmZmVyLXNpemUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIHBvcnQxLm9ubWVzc2FnZSA9ICh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0MS5vbm1lc3NhZ2VlcnJvciA9ICh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZWplY3QoZGF0YSk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDIucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzLm1hcCIsImltcG9ydCB7IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgfSBmcm9tICcuL2Nsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gYXN5bmMgKHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IGNsb25lZEF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gYXdhaXQgY2xvbmVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyhhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgcmV0dXJuIG5ldyBwcm9jZXNzb3JDb25zdHJ1Y3RvcihjbG9uZWRBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSB9IGZyb20gJy4vY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvciA9IChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBsZXQgbm9kZVRvUHJvY2Vzc29yTWFwID0gTk9ERV9UT19QUk9DRVNTT1JfTUFQUy5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgaWYgKG5vZGVUb1Byb2Nlc3Nvck1hcCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG5vZGVUb1Byb2Nlc3Nvck1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIE5PREVfVE9fUFJPQ0VTU09SX01BUFMuc2V0KG5hdGl2ZUNvbnRleHQsIG5vZGVUb1Byb2Nlc3Nvck1hcCk7XG4gICAgfVxuICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlKHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgbm9kZVRvUHJvY2Vzc29yTWFwLnNldChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlKTtcbiAgICByZXR1cm4gYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGNvbXB1dGVCdWZmZXJTaXplIH0gZnJvbSAnLi4vaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplJztcbmltcG9ydCB7IGNvcHlGcm9tQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS1mcm9tLWNoYW5uZWwnO1xuaW1wb3J0IHsgY29weVRvQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS10by1jaGFubmVsJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvciB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yJztcbmltcG9ydCB7IGNyZWF0ZU5lc3RlZEFycmF5cyB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMnO1xuaW1wb3J0IHsgUmVhZE9ubHlNYXAgfSBmcm9tICcuLi9yZWFkLW9ubHktbWFwJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5ID0gKGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMgPT09IDAgJiYgb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbENvdW50ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudClcbiAgICAgICAgICAgID8gb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnRcbiAgICAgICAgICAgIDogQXJyYXkuZnJvbShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgIC8vIEB0b2RvIENoZWNrIGlmIGFueSBvZiB0aGUgY2hhbm5lbENvdW50IHZhbHVlcyBpcyBncmVhdGVyIHRoYW4gdGhlIGltcGxlbWVudGF0aW9uJ3MgbWF4aW11bSBudW1iZXIgb2YgY2hhbm5lbHMuXG4gICAgICAgIGlmIChvdXRwdXRDaGFubmVsQ291bnQuc29tZSgoY2hhbm5lbENvdW50KSA9PiBjaGFubmVsQ291bnQgPCAxKSkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0Q2hhbm5lbENvdW50Lmxlbmd0aCAhPT0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxDb3VudCAqIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgIGNvbnN0IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPSBvdXRwdXRDaGFubmVsQ291bnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCk7XG4gICAgICAgIGNvbnN0IG51bWJlck9mUGFyYW1ldGVycyA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWQgPyAwIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICBpZiAobnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzID4gNiB8fCBudW1iZXJPZk91dHB1dENoYW5uZWxzID4gNikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXNzYWdlQ2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjb25zdCBnYWluTm9kZXMgPSBbXTtcbiAgICAgICAgY29uc3QgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2RlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgZ2Fpbk5vZGVzLnB1c2goY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZXMgPSBbXTtcbiAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgeyBkZWZhdWx0VmFsdWUsIG1heFZhbHVlLCBtaW5WYWx1ZSwgbmFtZSB9IG9mIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy5wYXJhbWV0ZXJEYXRhW25hbWVdICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3B0aW9ucy5wYXJhbWV0ZXJEYXRhW25hbWVdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAoZGVmYXVsdFZhbHVlID09PSB1bmRlZmluZWQgPyAwIDogZGVmYXVsdFZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBtYXhWYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAobWF4VmFsdWUgPT09IHVuZGVmaW5lZCA/IE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIDogbWF4VmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIG1pblZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IChtaW5WYWx1ZSA9PT0gdW5kZWZpbmVkID8gTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQgOiBtaW5WYWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZXMucHVzaChjb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycylcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlclNpemUgPSBjb21wdXRlQnVmZmVyU2l6ZShiYXNlTGF0ZW5jeSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgYnVmZmVyU2l6ZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzLCBcbiAgICAgICAgLy8gQnVnICM4NzogT25seSBGaXJlZm94IHdpbGwgZmlyZSBhbiBBdWRpb1Byb2Nlc3NpbmdFdmVudCBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgb3V0cHV0LlxuICAgICAgICBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSk7XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyksXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogb3V0cHV0Q2hhbm5lbENvdW50W2ldXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGdhaW5Ob2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0pO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGosIGkgKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlck1hcCA9IG5ldyBSZWFkT25seU1hcChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLm1hcCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY29uc3RhbnRTb3VyY2VOb2Rlc1tpbmRleF07XG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgpO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25hbWUsIGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXRdO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICBpbnB1dENoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgIGxldCBjaGFubmVsSW50ZXJwcmV0YXRpb24gPSBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgbGV0IG9ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAvLyBCdWcgIzg3OiBFeHBvc2UgYXQgbGVhc3Qgb25lIG91dHB1dCB0byBtYWtlIHRoaXMgbm9kZSBjb25uZWN0YWJsZS5cbiAgICAgICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlcyA9IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAwID8gW3NjcmlwdFByb2Nlc3Nvck5vZGVdIDogb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyU2l6ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KF8pIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZShfKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBnYWluTm9kZSBvZiBnYWluTm9kZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGVzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb25wcm9jZXNzb3JlcnJvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb25wcm9jZXNzb3JlcnJvcih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb25wcm9jZXNzb3JlcnJvciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwYXJhbWV0ZXJzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJhbWV0ZXJNYXA7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvcnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VDaGFubmVsLnBvcnQyO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29ubmVjdDogY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dEF1ZGlvTm9kZXMpLFxuICAgICAgICAgICAgZGlzY29ubmVjdDogZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dEF1ZGlvTm9kZXMpLFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIgPSAoKGFkZEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHR5cGVvZiBhcmdzWzFdID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIGFyZ3NbMV0gPT09ICdvYmplY3QnICYmIGFyZ3NbMV0gIT09IG51bGwgJiYgdHlwZW9mIGFyZ3NbMV0uaGFuZGxlRXZlbnQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV0uaGFuZGxlRXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1bnBhdGNoZWRFdmVudExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHBhdGNoZWRFdmVudExpc3RlbmVycy5nZXQoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiB1bnBhdGNoZWRFdmVudExpc3RlbmVyKGV2ZW50KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuc2V0KHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIsIGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhZGRFdmVudExpc3RlbmVyLmNhbGwobWVzc2FnZUNoYW5uZWwucG9ydDEsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSAoKHJlbW92ZUV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmRlbGV0ZShhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKG1lc3NhZ2VDaGFubmVsLnBvcnQxLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIpO1xuICAgICAgICBsZXQgb25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1lc3NhZ2VDaGFubmVsLnBvcnQxLCAnb25tZXNzYWdlJywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiBvbm1lc3NhZ2UsXG4gICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbm1lc3NhZ2UgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbm1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9ubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucHJvdG90eXBlLnBvcnQgPSBtZXNzYWdlQ2hhbm5lbC5wb3J0MTtcbiAgICAgICAgbGV0IGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IG51bGw7XG4gICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucyk7XG4gICAgICAgIGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UudGhlbigoZFdya2x0UHJjc3NyKSA9PiAoYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gZFdya2x0UHJjc3NyKSk7XG4gICAgICAgIGNvbnN0IGlucHV0cyA9IGNyZWF0ZU5lc3RlZEFycmF5cyhvcHRpb25zLm51bWJlck9mSW5wdXRzLCBvcHRpb25zLmNoYW5uZWxDb3VudCk7XG4gICAgICAgIGNvbnN0IG91dHB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZk91dHB1dHMsIG91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLnJlZHVjZSgocHJtdHJzLCB7IG5hbWUgfSkgPT4gKHsgLi4ucHJtdHJzLCBbbmFtZV06IG5ldyBGbG9hdDMyQXJyYXkoMTI4KSB9KSwge30pO1xuICAgICAgICBsZXQgaXNBY3RpdmUgPSB0cnVlO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0T3V0cHV0c0dyYXBoID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID4gMCkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG91dHB1dENoYW5uZWxDb3VudFtpXTsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYWN0aXZlSW5wdXRJbmRleGVzID0gbmV3IE1hcCgpO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyLCBvdXRwdXRCdWZmZXIgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKGF1ZGlvV29ya2xldFByb2Nlc3NvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0cyA9IGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlclNpemU7IGkgKz0gMTI4KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwoaW5wdXRCdWZmZXIsIGlucHV0c1tqXSwgaywgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmZvckVhY2goKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChpbnB1dEJ1ZmZlciwgcGFyYW1ldGVycywgbmFtZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRwdXRzW2pdW2tdLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0c1tqXVtrXSA9IG5ldyBGbG9hdDMyQXJyYXkoMTI4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvdGVudGlhbGx5RW1wdHlJbnB1dHMgPSBpbnB1dHMubWFwKChpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbnB1dCA9IGFjdGl2ZUlucHV0c1tpbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUlucHV0LnNpemUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5zZXQoaW5kZXgsIGJ1ZmZlclNpemUgLyAxMjgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gYWN0aXZlSW5wdXRJbmRleGVzLmdldChpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZXZlcnkoKGNoYW5uZWxEYXRhKSA9PiBjaGFubmVsRGF0YS5ldmVyeSgoc2FtcGxlKSA9PiBzYW1wbGUgPT09IDApKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5kZWxldGUoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlSW5wdXRJbmRleGVzLnNldChpbmRleCwgY291bnQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVNvdXJjZUZsYWcgPSBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lICsgaSAvIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBhdWRpb1dvcmtsZXRQcm9jZXNzb3IucHJvY2Vzcyhwb3RlbnRpYWxseUVtcHR5SW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IGFjdGl2ZVNvdXJjZUZsYWc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5VG9DaGFubmVsKG91dHB1dEJ1ZmZlciwgb3V0cHV0c1tqXSwgaywgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIuZGlzcGF0Y2hFdmVudChuZXcgRXJyb3JFdmVudCgncHJvY2Vzc29yZXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbm86IGVycm9yLmNvbG5vLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBlcnJvci5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lbm86IGVycm9yLmxpbmVubyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluTm9kZXNbal0uZGlzY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2pdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5kaXNjb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGssIGogKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGspO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY29uc3RhbnRTb3VyY2VOb2Rlc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5kaXNjb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gQnVnICM4NzogT25seSBGaXJlZm94IHdpbGwgZmlyZSBhbiBBdWRpb1Byb2Nlc3NpbmdFdmVudCBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgb3V0cHV0LlxuICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjb25uZWN0RmFrZUdyYXBoID0gKCkgPT4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0RmFrZUdyYXBoID0gKCkgPT4ge1xuICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdXRwdXRDaGFubmVsQ291bnRbaV07IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxNZXJnZXJOb2RlLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaiwgaik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdEZha2VHcmFwaCgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGgoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIGNvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ1EnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ2RldHVuZScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnZnJlcXVlbmN5Jyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdnYWluJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICd0eXBlJyk7XG4gICAgcmV0dXJuIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWJpcXVhZC1maWx0ZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGVGYWN0b3J5ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIob3B0aW9ucy5udW1iZXJPZklucHV0cyk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMjA6IFNhZmFyaSByZXF1aXJlcyBhIGNvbm5lY3Rpb24gb2YgYW55IGtpbmQgdG8gdHJlYXQgdGhlIGlucHV0IHNpZ25hbCBjb3JyZWN0bHkuXG4gICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGUgZXhpc3RlbmNlIG9mXG4gICAgICAgICAqIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgd3JhcENoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNoYW5uZWwtbWVyZ2VyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IChjaGFubmVsU3BsaXR0ZXJOb2RlKSA9PiB7XG4gICAgY29uc3QgY2hhbm5lbENvdW50ID0gY2hhbm5lbFNwbGl0dGVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgLy8gQnVnICM5NzogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudCB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBpdHMgaW5pdGlhbCB2YWx1ZS5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiBjaGFubmVsQ291bnQsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBCdWcgIzMwOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbENvdW50TW9kZSB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBleHBsaWNpdC5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBCdWcgIzMyOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbEludGVycHJldGF0aW9uIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGRpc2NyZXRlLlxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsU3BsaXR0ZXJOb2RlLCAnY2hhbm5lbEludGVycHJldGF0aW9uJywge1xuICAgICAgICBnZXQ6ICgpID0+ICdkaXNjcmV0ZScsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09ICdkaXNjcmV0ZScpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtY2hhbm5lbC1zcGxpdHRlci1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIob3B0aW9ucy5udW1iZXJPZk91dHB1dHMpO1xuICAgIC8vIEJ1ZyAjOTY6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudC5cbiAgICAvLyBCdWcgIzI5OiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnRNb2RlLlxuICAgIC8vIEJ1ZyAjMzE6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxJbnRlcnByZXRhdGlvbi5cbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIG9wdGlvbnMpO1xuICAgIC8vIEJ1ZyAjMjksICMzMCwgIzMxLCAjMzIsICM5NiAmICM5NzogT25seSBDaHJvbWUsIEVkZ2UgJiBGaXJlZm94IHBhcnRpYWxseSBzdXBwb3J0IHRoZSBzcGVjIHlldC5cbiAgICB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICByZXR1cm4gbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNjI6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IENvbnN0YW50U291cmNlTm9kZXMuXG4gICAgICAgIGlmIChuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgb3B0aW9ucywgJ29mZnNldCcpO1xuICAgICAgICAvLyBCdWcgIzQ0OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzU6IFNhZmFyaSB3aWxsIG5vdCBmaXJlIGFuIGVuZGVkIGV2ZW50IGlmIHRoZSBDb25zdGFudFNvdXJjZU5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpbnRlcmNlcHRDb25uZWN0aW9ucyA9IChvcmlnaW5hbCwgaW50ZXJjZXB0b3IpID0+IHtcbiAgICBvcmlnaW5hbC5jb25uZWN0ID0gaW50ZXJjZXB0b3IuY29ubmVjdC5iaW5kKGludGVyY2VwdG9yKTtcbiAgICBvcmlnaW5hbC5kaXNjb25uZWN0ID0gaW50ZXJjZXB0b3IuZGlzY29ubmVjdC5iaW5kKGludGVyY2VwdG9yKTtcbiAgICByZXR1cm4gb3JpZ2luYWw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJjZXB0LWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgb2Zmc2V0LCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAyLCA0NDEwMCk7XG4gICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IG9mZnNldCB9KTtcbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAvLyBCdWcgIzk1OiBTYWZhcmkgZG9lcyBub3QgcGxheSBvciBsb29wIG9uZSBzYW1wbGUgYnVmZmVycy5cbiAgICAgICAgY2hhbm5lbERhdGFbMF0gPSAxO1xuICAgICAgICBjaGFubmVsRGF0YVsxXSA9IDE7XG4gICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBhdWRpb0J1ZmZlcjtcbiAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB0cnVlO1xuICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb2Zmc2V0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3RhcnQod2hlbiA9IDApIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQuY2FsbChhdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcC5jYWxsKGF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIGF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIGdhaW5Ob2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ29udm9sdmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIFRoZSBub3JtYWxpemUgcHJvcGVydHkgbmVlZHMgdG8gYmUgc2V0IGJlZm9yZSBzZXR0aW5nIHRoZSBidWZmZXIuXG4gICAgICAgIGlmIChvcHRpb25zLmRpc2FibGVOb3JtYWxpemF0aW9uID09PSBuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZSkge1xuICAgICAgICAgICAgbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemUgPSAhb3B0aW9ucy5kaXNhYmxlTm9ybWFsaXphdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQ29udm9sdmVyTm9kZSwgb3B0aW9ucywgJ2J1ZmZlcicpO1xuICAgICAgICAvLyBCdWcgIzExMzogU2FmYXJpIGRvZXMgYWxsb3cgdG8gc2V0IHRoZSBjaGFubmVsQ291bnQgdG8gYSB2YWx1ZSBsYXJnZXIgdGhhbiAyLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnQgPiAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVDb252b2x2ZXJOb2RlLCAnY2hhbm5lbENvdW50JywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gMikge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxMTQ6IFNhZmFyaSBhbGxvd3MgdG8gc2V0IHRoZSBjaGFubmVsQ291bnRNb2RlIHRvICdtYXgnLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlQ29udm9sdmVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmF0aXZlQ29udm9sdmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVEZWxheU5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlRGVsYXkob3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlRGVsYXlOb2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRGVsYXlOb2RlLCBvcHRpb25zLCAnZGVsYXlUaW1lJyk7XG4gICAgcmV0dXJuIG5hdGl2ZURlbGF5Tm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZGVsYXktbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkgPSAoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIEJ1ZyAjMTA4OiBTYWZhcmkgYWxsb3dzIGEgY2hhbm5lbENvdW50IG9mIHRocmVlIGFuZCBhYm92ZS5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50ID4gMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzEwOTogT25seSBDaHJvbWUgYW5kIEZpcmVmb3ggZGlzYWxsb3cgYSBjaGFubmVsQ291bnRNb2RlIG9mICdtYXgnLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ2F0dGFjaycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ2tuZWUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdyYXRpbycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ3JlbGVhc2UnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICd0aHJlc2hvbGQnKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlR2Fpbk5vZGUsIG9wdGlvbnMpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVHYWluTm9kZSwgb3B0aW9ucywgJ2dhaW4nKTtcbiAgICByZXR1cm4gbmF0aXZlR2Fpbk5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWdhaW4tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgb3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBCdWcgIzk6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IElJUkZpbHRlck5vZGVzLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBkZWZpbmVzIHRoZSBwYXJhbWV0ZXJzIG9mIGNyZWF0ZUlJUkZpbHRlcigpIGFzIGFycmF5cyBvZiBudW1iZXJzLlxuICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIob3B0aW9ucy5mZWVkZm9yd2FyZCwgb3B0aW9ucy5mZWVkYmFjayk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlSUlSRmlsdGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVJSVJGaWx0ZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGNvbXB1dGVCdWZmZXJTaXplIH0gZnJvbSAnLi4vaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplJztcbmltcG9ydCB7IGZpbHRlckJ1ZmZlciB9IGZyb20gJy4uL2hlbHBlcnMvZmlsdGVyLWJ1ZmZlcic7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmZ1bmN0aW9uIGRpdmlkZShhLCBiKSB7XG4gICAgY29uc3QgZGVub21pbmF0b3IgPSBiWzBdICogYlswXSArIGJbMV0gKiBiWzFdO1xuICAgIHJldHVybiBbKGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0pIC8gZGVub21pbmF0b3IsIChhWzFdICogYlswXSAtIGFbMF0gKiBiWzFdKSAvIGRlbm9taW5hdG9yXTtcbn1cbmZ1bmN0aW9uIG11bHRpcGx5KGEsIGIpIHtcbiAgICByZXR1cm4gW2FbMF0gKiBiWzBdIC0gYVsxXSAqIGJbMV0sIGFbMF0gKiBiWzFdICsgYVsxXSAqIGJbMF1dO1xufVxuZnVuY3Rpb24gZXZhbHVhdGVQb2x5bm9taWFsKGNvZWZmaWNpZW50LCB6KSB7XG4gICAgbGV0IHJlc3VsdCA9IFswLCAwXTtcbiAgICBmb3IgKGxldCBpID0gY29lZmZpY2llbnQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gbXVsdGlwbHkocmVzdWx0LCB6KTtcbiAgICAgICAgcmVzdWx0WzBdICs9IGNvZWZmaWNpZW50W2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCB7IGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50TW9kZSwgY2hhbm5lbEludGVycHJldGF0aW9uLCBmZWVkYmFjaywgZmVlZGZvcndhcmQgfSkgPT4ge1xuICAgICAgICBjb25zdCBidWZmZXJTaXplID0gY29tcHV0ZUJ1ZmZlclNpemUoYmFzZUxhdGVuY3ksIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZEZlZWRiYWNrID0gZmVlZGJhY2sgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBmZWVkYmFjayA6IG5ldyBGbG9hdDY0QXJyYXkoZmVlZGJhY2spO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCA9IGZlZWRmb3J3YXJkIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGZvcndhcmQgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRmb3J3YXJkKTtcbiAgICAgICAgY29uc3QgZmVlZGJhY2tMZW5ndGggPSBjb252ZXJ0ZWRGZWVkYmFjay5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGZlZWRmb3J3YXJkTGVuZ3RoID0gY29udmVydGVkRmVlZGZvcndhcmQubGVuZ3RoO1xuICAgICAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbihmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmRMZW5ndGgpO1xuICAgICAgICBpZiAoZmVlZGJhY2tMZW5ndGggPT09IDAgfHwgZmVlZGJhY2tMZW5ndGggPiAyMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZlZWRmb3J3YXJkTGVuZ3RoID09PSAwIHx8IGZlZWRmb3J3YXJkTGVuZ3RoID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnZlcnRlZEZlZWRmb3J3YXJkWzBdID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSAhPT0gMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmZWVkZm9yd2FyZExlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29udmVydGVkRmVlZGZvcndhcmRbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZlZWRiYWNrTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0ZWRGZWVkYmFja1tpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCBidWZmZXJTaXplLCBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudCk7XG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSBjaGFubmVsQ291bnRNb2RlO1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IGNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgY29uc3QgYnVmZmVyTGVuZ3RoID0gMzI7XG4gICAgICAgIGNvbnN0IGJ1ZmZlckluZGV4ZXMgPSBbXTtcbiAgICAgICAgY29uc3QgeEJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgY29uc3QgeUJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsQ291bnQ7IGkgKz0gMSkge1xuICAgICAgICAgICAgYnVmZmVySW5kZXhlcy5wdXNoKDApO1xuICAgICAgICAgICAgY29uc3QgeEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICAgICAgICAgIGNvbnN0IHlCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgICAgICAgICB4QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgICAgICB5QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgICAgICB4QnVmZmVycy5wdXNoKHhCdWZmZXIpO1xuICAgICAgICAgICAgeUJ1ZmZlcnMucHVzaCh5QnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRCdWZmZXIgPSBldmVudC5pbnB1dEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dEJ1ZmZlciA9IGV2ZW50Lm91dHB1dEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSBpbnB1dEJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNoYW5uZWxzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dCA9IGlucHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgICAgICAgICBidWZmZXJJbmRleGVzW2ldID0gZmlsdGVyQnVmZmVyKGNvbnZlcnRlZEZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgY29udmVydGVkRmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXJzW2ldLCB5QnVmZmVyc1tpXSwgYnVmZmVySW5kZXhlc1tpXSwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbnlxdWlzdCA9IG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXJTaXplO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtzY3JpcHRQcm9jZXNzb3JOb2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRGlzc2FsbG93IGFkZGluZyBhbiBhdWRpb3Byb2Nlc3MgbGlzdGVuZXIuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChmcmVxdWVuY3lIei5sZW5ndGggIT09IG1hZ1Jlc3BvbnNlLmxlbmd0aCB8fCBtYWdSZXNwb25zZS5sZW5ndGggIT09IHBoYXNlUmVzcG9uc2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBsZW5ndGggPSBmcmVxdWVuY3lIei5sZW5ndGg7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYSA9IC1NYXRoLlBJICogKGZyZXF1ZW5jeUh6W2ldIC8gbnlxdWlzdCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHogPSBbTWF0aC5jb3Mob21lZ2EpLCBNYXRoLnNpbihvbWVnYSldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmF0b3IgPSBldmFsdWF0ZVBvbHlub21pYWwoY29udmVydGVkRmVlZGZvcndhcmQsIHopO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZW5vbWluYXRvciA9IGV2YWx1YXRlUG9seW5vbWlhbChjb252ZXJ0ZWRGZWVkYmFjaywgeik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZGl2aWRlKG51bWVyYXRvciwgZGVub21pbmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICBtYWdSZXNwb25zZVtpXSA9IE1hdGguc3FydChyZXNwb25zZVswXSAqIHJlc3BvbnNlWzBdICsgcmVzcG9uc2VbMV0gKiByZXNwb25zZVsxXSk7XG4gICAgICAgICAgICAgICAgICAgIHBoYXNlUmVzcG9uc2VbaV0gPSBNYXRoLmF0YW4yKHJlc3BvbnNlWzFdLCByZXNwb25zZVswXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIsIHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSAobmF0aXZlQXVkaW9Db250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2Uob3B0aW9ucy5tZWRpYUVsZW1lbnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgb3B0aW9ucyk7XG4gICAgLy8gQnVnICMxNzQ6IFNhZmFyaSBkb2VzIGV4cG9zZSBhIHdyb25nIG51bWJlck9mT3V0cHV0cy5cbiAgICBpZiAobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZS5udW1iZXJPZk91dHB1dHMgPT09IDEpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsICdudW1iZXJPZk91dHB1dHMnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IChuYXRpdmVBdWRpb0NvbnRleHQsIHsgbWVkaWFTdHJlYW0gfSkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvU3RyZWFtVHJhY2tzID0gbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKTtcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTUxOiBTYWZhcmkgZG9lcyBub3QgdXNlIHRoZSBhdWRpbyB0cmFjayBhcyBpbnB1dCBhbnltb3JlIGlmIGl0IGdldHMgcmVtb3ZlZCBmcm9tIHRoZSBtZWRpYVN0cmVhbSBhZnRlciBjb25zdHJ1Y3Rpb24uXG4gICAgICogQnVnICMxNTk6IFNhZmFyaSBwaWNrcyB0aGUgZmlyc3QgYXVkaW8gdHJhY2sgaWYgdGhlIE1lZGlhU3RyZWFtIGhhcyBtb3JlIHRoYW4gb25lIGF1ZGlvIHRyYWNrLlxuICAgICAqL1xuICAgIGF1ZGlvU3RyZWFtVHJhY2tzLnNvcnQoKGEsIGIpID0+IChhLmlkIDwgYi5pZCA/IC0xIDogYS5pZCA+IGIuaWQgPyAxIDogMCkpO1xuICAgIGNvbnN0IGZpbHRlcmVkQXVkaW9TdHJlYW1UcmFja3MgPSBhdWRpb1N0cmVhbVRyYWNrcy5zbGljZSgwLCAxKTtcbiAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShuZXcgTWVkaWFTdHJlYW0oZmlsdGVyZWRBdWRpb1N0cmVhbVRyYWNrcykpO1xuICAgIC8qXG4gICAgICogQnVnICMxNTEgJiAjMTU5OiBUaGUgZ2l2ZW4gbWVkaWFTdHJlYW0gZ2V0cyByZWNvbnN0cnVjdGVkIGJlZm9yZSBpdCBnZXRzIHBhc3NlZCB0byB0aGUgbmF0aXZlIG5vZGUgd2hpY2ggaXMgd2h5IHRoZSBhY2Nlc3NvciBuZWVkc1xuICAgICAqIHRvIGJlIG92ZXJ3cml0dGVuIGFzIGl0IHdvdWxkIG90aGVyd2lzZSBleHBvc2UgdGhlIHJlY29uc3RydWN0ZWQgdmVyc2lvbi5cbiAgICAgKi9cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsICdtZWRpYVN0cmVhbScsIHsgdmFsdWU6IG1lZGlhU3RyZWFtIH0pO1xuICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb0NvbnRleHQsIHsgbWVkaWFTdHJlYW1UcmFjayB9KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTIxOiBPbmx5IEZpcmVmb3ggZG9lcyB5ZXQgc3VwcG9ydCB0aGUgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZS5cbiAgICAgICAgaWYgKHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1UcmFja1NvdXJjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVRyYWNrU291cmNlKG1lZGlhU3RyZWFtVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFttZWRpYVN0cmVhbVRyYWNrXSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgLy8gQnVnICMxMjA6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG1lZGlhU3RyZWFtIGhhcyBubyBhdWRpbyB0cmFjay5cbiAgICAgICAgaWYgKG1lZGlhU3RyZWFtVHJhY2sua2luZCAhPT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3MjogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQXVkaW9Db250ZXh0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ09mZmxpbmVBdWRpb0NvbnRleHQnKSkge1xuICAgICAgICByZXR1cm4gd2luZG93Lk9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgfVxuICAgIHJldHVybiB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ3dlYmtpdE9mZmxpbmVBdWRpb0NvbnRleHQnKSA/IHdpbmRvdy53ZWJraXRPZmZsaW5lQXVkaW9Db250ZXh0IDogbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zLCAnZGV0dW5lJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ2ZyZXF1ZW5jeScpO1xuICAgICAgICBpZiAob3B0aW9ucy5wZXJpb2RpY1dhdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUuc2V0UGVyaW9kaWNXYXZlKG9wdGlvbnMucGVyaW9kaWNXYXZlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ3R5cGUnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IENocm9tZSAmIEVkZ2UgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxOTogU2FmYXJpIGRvZXMgbm90IGlnbm9yZSBjYWxscyB0byBzdG9wKCkgb2YgYW4gYWxyZWFkeSBzdG9wcGVkIEF1ZGlvQnVmZmVyU291cmNlTm9kZS5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyhuYXRpdmVPc2NpbGxhdG9yTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgT3NjaWxsYXRvck5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlT3NjaWxsYXRvck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgICAgIC8vIEJ1ZyAjMTI0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZnlpbmcgdGhlIG9yaWVudGF0aW9uIGFuZCB0aGUgcG9zaXRpb24gd2l0aCBBdWRpb1BhcmFtcy5cbiAgICAgICAgaWYgKG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblgnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblknKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblonKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblgnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblknKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblonKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdjb25lSW5uZXJBbmdsZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2NvbmVPdXRlckFuZ2xlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnY29uZU91dGVyR2FpbicpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2Rpc3RhbmNlTW9kZWwnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdtYXhEaXN0YW5jZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3Bhbm5pbmdNb2RlbCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3JlZkRpc3RhbmNlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncm9sbG9mZkZhY3RvcicpO1xuICAgICAgICByZXR1cm4gbmF0aXZlUGFubmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1wYW5uZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkgPSAoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRGaXJzdFNhbXBsZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGNvbmVJbm5lckFuZ2xlLCBjb25lT3V0ZXJBbmdsZSwgY29uZU91dGVyR2FpbiwgZGlzdGFuY2VNb2RlbCwgbWF4RGlzdGFuY2UsIG9yaWVudGF0aW9uWCwgb3JpZW50YXRpb25ZLCBvcmllbnRhdGlvblosIHBhbm5pbmdNb2RlbCwgcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWiwgcmVmRGlzdGFuY2UsIHJvbGxvZmZGYWN0b3IsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBwYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICAgICAgLy8gQnVnICMxMjU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgIGlmIChhdWRpb05vZGVPcHRpb25zLmNoYW5uZWxDb3VudCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMjY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgIGlmIChhdWRpb05vZGVPcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMocGFubmVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX09QVElPTlMgPSB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA2XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBvcmllbnRhdGlvblhHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3Qgb3JpZW50YXRpb25ZR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uWkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBwb3NpdGlvblhHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25ZR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uWkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCAyNTYsIDYsIDEpO1xuICAgICAgICBjb25zdCB3YXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbmV3IEZsb2F0MzJBcnJheShbMSwgMV0pLFxuICAgICAgICAgICAgb3ZlcnNhbXBsZTogJ25vbmUnXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbGFzdE9yaWVudGF0aW9uID0gW29yaWVudGF0aW9uWCwgb3JpZW50YXRpb25ZLCBvcmllbnRhdGlvblpdO1xuICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gW3Bvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblpdO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW1xuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDApLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDEpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDIpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRPcmllbnRhdGlvbiguLi5vcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBvc2l0b24gPSBbXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMyksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNCksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNSlcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAocG9zaXRvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0UG9zaXRpb24oLi4ucG9zaXRvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3NpdG9uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3JpZW50YXRpb25ZR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3JpZW50YXRpb25aR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25YR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25ZR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25aR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyNTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lT3V0ZXJHYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lT3V0ZXJHYWluKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjc6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jb25lT3V0ZXJHYWluID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgZGlzdGFuY2VNb2RlbCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtYXhEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5tYXhEaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgbWF4RGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUubWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9yaWVudGF0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb25YR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3JpZW50YXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvbllHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvcmllbnRhdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWVudGF0aW9uWkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5wYW5uaW5nTW9kZWw7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHBhbm5pbmdNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucGFubmluZ01vZGVsID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25YR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbllHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnJlZkRpc3RhbmNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCByZWZEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI5OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5yZWZEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHJvbGxvZmZGYWN0b3IodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMDogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucm9sbG9mZkZhY3RvciA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY29uZUlubmVyQW5nbGUgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lSW5uZXJBbmdsZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVJbm5lckFuZ2xlID0gY29uZUlubmVyQW5nbGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmVPdXRlckFuZ2xlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyQW5nbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJBbmdsZSA9IGNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25lT3V0ZXJHYWluICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyR2Fpbikge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckdhaW4gPSBjb25lT3V0ZXJHYWluO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXN0YW5jZU1vZGVsICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuZGlzdGFuY2VNb2RlbCkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmRpc3RhbmNlTW9kZWwgPSBkaXN0YW5jZU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXhEaXN0YW5jZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm1heERpc3RhbmNlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIubWF4RGlzdGFuY2UgPSBtYXhEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZW50YXRpb25YICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25YLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25YLnZhbHVlID0gb3JpZW50YXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmllbnRhdGlvblkgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblkudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblkudmFsdWUgPSBvcmllbnRhdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yaWVudGF0aW9uWiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWi52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWi52YWx1ZSA9IG9yaWVudGF0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFubmluZ01vZGVsICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucGFubmluZ01vZGVsKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucGFubmluZ01vZGVsID0gcGFubmluZ01vZGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvblggIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblgudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblgudmFsdWUgPSBwb3NpdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uWSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWS52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWS52YWx1ZSA9IHBvc2l0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb25aICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25aLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25aLnZhbHVlID0gcG9zaXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWZEaXN0YW5jZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnJlZkRpc3RhbmNlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucmVmRGlzdGFuY2UgPSByZWZEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm9sbG9mZkZhY3RvciAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnJvbGxvZmZGYWN0b3IpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yb2xsb2ZmRmFjdG9yID0gcm9sbG9mZkZhY3RvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFzdE9yaWVudGF0aW9uWzBdICE9PSAxIHx8IGxhc3RPcmllbnRhdGlvblsxXSAhPT0gMCB8fCBsYXN0T3JpZW50YXRpb25bMl0gIT09IDApIHtcbiAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0T3JpZW50YXRpb24oLi4ubGFzdE9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICB9XG4gICAgICAgIGlmIChsYXN0UG9zaXRpb25bMF0gIT09IDAgfHwgbGFzdFBvc2l0aW9uWzFdICE9PSAwIHx8IGxhc3RQb3NpdGlvblsyXSAhPT0gMCkge1xuICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRQb3NpdGlvbiguLi5sYXN0UG9zaXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChwYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUoaW5wdXRHYWluTm9kZSwgd2F2ZVNoYXBlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChvcmllbnRhdGlvblhHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KG9yaWVudGF0aW9uWUdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3Qob3JpZW50YXRpb25aR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDIpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChwb3NpdGlvblhHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMyk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KHBvc2l0aW9uWUdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCA0KTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocG9zaXRpb25aR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDUpO1xuICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHBhbm5lck5vZGUpO1xuICAgICAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKGlucHV0R2Fpbk5vZGUsIHdhdmVTaGFwZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3JpZW50YXRpb25YR2Fpbk5vZGUpO1xuICAgICAgICAgICAgb3JpZW50YXRpb25YR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG9yaWVudGF0aW9uWUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWUdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvcmllbnRhdGlvblpHYWluTm9kZSk7XG4gICAgICAgICAgICBvcmllbnRhdGlvblpHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocG9zaXRpb25YR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpb25YR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBvc2l0aW9uWUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHBvc2l0aW9uWUdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwb3NpdGlvblpHYWluTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGlvblpHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmRpc2Nvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlUGFubmVyTm9kZUZha2VyLCBwYW5uZXJOb2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeSA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBkaXNhYmxlTm9ybWFsaXphdGlvbiwgaW1hZywgcmVhbCB9KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTgwOiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gdXNlIG9yZGluYXJ5IGFycmF5cy5cbiAgICAgICAgY29uc3QgY29udmVydGVkSW1hZyA9IGltYWcgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBpbWFnIDogbmV3IEZsb2F0MzJBcnJheShpbWFnKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkUmVhbCA9IHJlYWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyByZWFsIDogbmV3IEZsb2F0MzJBcnJheShyZWFsKTtcbiAgICAgICAgY29uc3QgbmF0aXZlUGVyaW9kaWNXYXZlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUoY29udmVydGVkUmVhbCwgY29udmVydGVkSW1hZywgeyBkaXNhYmxlTm9ybWFsaXphdGlvbiB9KTtcbiAgICAgICAgLy8gQnVnICMxODE6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbmRleFNpemVFcnJvciBzbyBmYXIgaWYgdGhlIGdpdmVuIGFycmF5cyBoYXZlIGxlc3MgdGhhbiB0d28gdmFsdWVzLlxuICAgICAgICBpZiAoQXJyYXkuZnJvbShpbWFnKS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVQZXJpb2RpY1dhdmU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlID0gKG5hdGl2ZUNvbnRleHQsIGJ1ZmZlclNpemUsIG51bWJlck9mSW5wdXRDaGFubmVscywgbnVtYmVyT2ZPdXRwdXRDaGFubmVscykgPT4ge1xuICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmNyZWF0ZVNjcmlwdFByb2Nlc3NvcihidWZmZXJTaXplLCBudW1iZXJPZklucHV0Q2hhbm5lbHMsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lIGRlcHJlY2F0aW9uXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXNjcmlwdC1wcm9jZXNzb3Itbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBjaGFubmVsQ291bnRNb2RlID0gb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzEwNTogVGhlIGNoYW5uZWxDb3VudE1vZGUgb2YgJ2NsYW1wZWQtbWF4JyBzaG91bGQgYmUgc3VwcG9ydGVkLiBIb3dldmVyIGl0IGlzIG5vdCBwb3NzaWJsZSB0byB3cml0ZSBhIHBvbHlmaWxsIGZvciBTYWZhcmlcbiAgICAgICAgICogd2hpY2ggc3VwcG9ydHMgaXQgYW5kIHRoZXJlZm9yZSBpdCBjYW4ndCBiZSBzdXBwb3J0ZWQgYXQgYWxsLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudE1vZGUgPT09ICdjbGFtcGVkLW1heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBTdGVyZW9QYW5uZXJOb2RlLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIG9wdGlvbnMsICdwYW4nKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDU6IFRoZSBjaGFubmVsQ291bnRNb2RlIG9mICdjbGFtcGVkLW1heCcgc2hvdWxkIGJlIHN1cHBvcnRlZC4gSG93ZXZlciBpdCBpcyBub3QgcG9zc2libGUgdG8gd3JpdGUgYSBwb2x5ZmlsbCBmb3IgU2FmYXJpXG4gICAgICAgICAqIHdoaWNoIHN1cHBvcnRzIGl0IGFuZCB0aGVyZWZvcmUgaXQgY2FuJ3QgYmUgc3VwcG9ydGVkIGF0IGFsbC5cbiAgICAgICAgICovXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBjaGFubmVsQ291bnRNb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgLy8gVGhlIGN1cnZlIGhhcyBhIHNpemUgb2YgMTRiaXQgcGx1cyAxIHZhbHVlIHRvIGhhdmUgYW4gZXhhY3QgcmVwcmVzZW50YXRpb24gZm9yIHplcm8uIFRoaXMgdmFsdWUgaGFzIGJlZW4gZGV0ZXJtaW5lZCBleHBlcmltZW50YWxseS5cbiAgICBjb25zdCBDVVJWRV9TSVpFID0gMTYzODU7XG4gICAgY29uc3QgRENfQ1VSVkUgPSBuZXcgRmxvYXQzMkFycmF5KFsxLCAxXSk7XG4gICAgY29uc3QgSEFMRl9QSSA9IE1hdGguUEkgLyAyO1xuICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX09QVElPTlMgPSB7IGNoYW5uZWxDb3VudDogMSwgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JywgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnIH07XG4gICAgY29uc3QgU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyA9IHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgb3ZlcnNhbXBsZTogJ25vbmUnIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoRm9yTW9ubyA9IChuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbGVmdFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBDVVJWRV9TSVpFOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHggPSAoaSAvIChDVVJWRV9TSVpFIC0gMSkpICogSEFMRl9QSTtcbiAgICAgICAgICAgIGxlZnRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbGVmdEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBsZWZ0V2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogbGVmdFdhdmVTaGFwZXJDdXJ2ZSB9KSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHBhbldhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IERDX0NVUlZFIH0pKTtcbiAgICAgICAgY29uc3QgcmlnaHRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRXYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiByaWdodFdhdmVTaGFwZXJDdXJ2ZSB9KSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGxlZnRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChyaWdodEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5jb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IGxlZnRXYXZlU2hhcGVyTm9kZSA6IGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHJpZ2h0V2F2ZVNoYXBlck5vZGUgOiByaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gbGVmdFdhdmVTaGFwZXJOb2RlIDogbGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcmlnaHRXYXZlU2hhcGVyTm9kZSA6IHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBjb25zdCBidWlsZEludGVybmFsR3JhcGhGb3JTdGVyZW8gPSAobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgY2VudGVySW5kZXggPSBNYXRoLmZsb29yKENVUlZFX1NJWkUgLyAyKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBDVVJWRV9TSVpFOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChpID4gY2VudGVySW5kZXgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gKChpIC0gY2VudGVySW5kZXgpIC8gKENVUlZFX1NJWkUgLSAxIC0gY2VudGVySW5kZXgpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguY29zKHgpO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAwO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gKGkgLyAoQ1VSVkVfU0laRSAtIDEgLSBjZW50ZXJJbmRleCkpICogSEFMRl9QSTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDA7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLnNpbih4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiAyXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHBhbldhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IERDX0NVUlZFIH0pKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmNvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoID0gKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGlmIChjaGFubmVsQ291bnQgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZEludGVybmFsR3JhcGhGb3JNb25vKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudCA9PT0gMikge1xuICAgICAgICAgICAgcmV0dXJuIGJ1aWxkSW50ZXJuYWxHcmFwaEZvclN0ZXJlbyhuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgfTtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnRNb2RlLCBwYW4sIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBpZiAoY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5hdWRpb05vZGVPcHRpb25zLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiAyXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudE1vZGUsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IHBhbkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIGdhaW46IHBhblxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IHsgY29ubmVjdEdyYXBoLCBkaXNjb25uZWN0R3JhcGggfSA9IGJ1aWxkSW50ZXJuYWxHcmFwaChuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnbWF4VmFsdWUnLCB7IGdldDogKCkgPT4gMSB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhbkdhaW5Ob2RlLmdhaW4sICdtaW5WYWx1ZScsIHsgZ2V0OiAoKSA9PiAtMSB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAoeyBjb25uZWN0R3JhcGgsIGRpc2Nvbm5lY3RHcmFwaCB9ID0gYnVpbGRJbnRlcm5hbEdyYXBoKG5hdGl2ZUNvbnRleHQsIHZhbHVlLCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09ICdjbGFtcGVkLW1heCcgfHwgdmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcGFuKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5HYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnksIGNoYW5uZWxNZXJnZXJOb2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBjb3JyZWN0bHkgbWFwIHRoZSB2YWx1ZXMuXG4gICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGUgZXhpc3RlbmNlIG9mXG4gICAgICAgICAqIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS4gVGVzdGluZyBmb3IgdGhlIGF1dG9tYXRpb25SYXRlIHByb3BlcnR5IGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoaXMgd29ya2Fyb3VuZFxuICAgICAgICAgKiBpc24ndCBuZWNlc3NhcnkgYW55bW9yZSBzaW5jZSB2MTQuMC4yIG9mIFNhZmFyaS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcgJiZcbiAgICAgICAgICAgIG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpLmdhaW4uYXV0b21hdGlvblJhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGN1cnZlID0gb3B0aW9ucy5jdXJ2ZSA9PT0gbnVsbCB8fCBvcHRpb25zLmN1cnZlIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gb3B0aW9ucy5jdXJ2ZSA6IG5ldyBGbG9hdDMyQXJyYXkob3B0aW9ucy5jdXJ2ZSk7XG4gICAgICAgIC8vIEJ1ZyAjMTA0OiBDaHJvbWUgYW5kIEVkZ2Ugd2lsbCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgaWYgKGN1cnZlICE9PSBudWxsICYmIGN1cnZlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSB2YWx1ZXMgb2YgdHlwZSBGbG9hdDMyQXJyYXkgY2FuIGJlIGFzc2lnbmVkIHRvIHRoZSBjdXJ2ZSBwcm9wZXJ0eS5cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB7IGN1cnZlIH0sICdjdXJ2ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlV2F2ZVNoYXBlck5vZGUsIG9wdGlvbnMsICdvdmVyc2FtcGxlJyk7XG4gICAgICAgIGxldCBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgJ2N1cnZlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlV2F2ZVNoYXBlck5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHZhbHVlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNEQ0N1cnZlKHZhbHVlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChpc0RDQ3VydmUobmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUpKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY3VydmUsIG92ZXJzYW1wbGUsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIGNvbnN0IHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgaW52ZXJ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IC0xIH0pO1xuICAgICAgICBjb25zdCBvdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgcmV2ZXJ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IC0xIH0pO1xuICAgICAgICBsZXQgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgdW5tb2RpZmllZEN1cnZlID0gbnVsbDtcbiAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVubW9kaWZpZWRDdXJ2ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY3VydmUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VydmVMZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZ2F0aXZlQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KGN1cnZlTGVuZ3RoICsgMiAtIChjdXJ2ZUxlbmd0aCAlIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpdmVDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoY3VydmVMZW5ndGggKyAyIC0gKGN1cnZlTGVuZ3RoICUgMikpO1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlWzBdID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlQ3VydmVbMF0gPSAtdmFsdWVbY3VydmVMZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5jZWlsKChjdXJ2ZUxlbmd0aCArIDEpIC8gMik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlckluZGV4ID0gKGN1cnZlTGVuZ3RoICsgMSkgLyAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGhlb3JldGljSW5kZXggPSAoaSAvIGxlbmd0aCkgKiBjZW50ZXJJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvd2VySW5kZXggPSBNYXRoLmZsb29yKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwcGVySW5kZXggPSBNYXRoLmNlaWwodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVtpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHZhbHVlW2xvd2VySW5kZXhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZVtsb3dlckluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIHZhbHVlW3VwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVDdXJ2ZVtpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC12YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSBsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IC0oKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSBsb3dlckluZGV4XSkgLVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgLSAodXBwZXJJbmRleCAtIHRoZW9yZXRpY0luZGV4KSkgKiB2YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSB1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlW2xlbmd0aF0gPSBjdXJ2ZUxlbmd0aCAlIDIgPT09IDEgPyB2YWx1ZVtsZW5ndGggLSAxXSA6ICh2YWx1ZVtsZW5ndGggLSAyXSArIHZhbHVlW2xlbmd0aCAtIDFdKSAvIDI7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBuZWdhdGl2ZUN1cnZlO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gcG9zaXRpdmVDdXJ2ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdW5tb2RpZmllZEN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodW5tb2RpZmllZEN1cnZlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb3ZlcnNhbXBsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY3VydmUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgdmFsdWVzIG9mIHR5cGUgRmxvYXQzMkFycmF5IGNhbiBiZSBhc3NpZ25lZCB0byB0aGUgY3VydmUgcHJvcGVydHkuXG4gICAgICAgICAgICBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLmN1cnZlID0gY3VydmUgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBjdXJ2ZSA6IG5ldyBGbG9hdDMyQXJyYXkoY3VydmUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdmVyc2FtcGxlICE9PSBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLm92ZXJzYW1wbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlKS5jb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChpbnZlcnRHYWluTm9kZSkuY29ubmVjdChwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlKS5jb25uZWN0KHJldmVydEdhaW5Ob2RlKS5jb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodW5tb2RpZmllZEN1cnZlKSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGludmVydEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmRpc2Nvbm5lY3QocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmV2ZXJ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuZGlzY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgb3V0cHV0R2Fpbk5vZGUpLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ05vdFN1cHBvcnRlZEVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub3Qtc3VwcG9ydGVkLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIG51bWJlck9mQ2hhbm5lbHM6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc3RhcnRSZW5kZXJpbmcpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgT2ZmbGluZUF1ZGlvQ29udGV4dCBleHRlbmRzIGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGEsIGIsIGMpIHtcbiAgICAgICAgICAgIGxldCBvcHRpb25zO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhID09PSAnbnVtYmVyJyAmJiBiICE9PSB1bmRlZmluZWQgJiYgYyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgbGVuZ3RoOiBiLCBudW1iZXJPZkNoYW5uZWxzOiBhLCBzYW1wbGVSYXRlOiBjIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gYTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGdpdmVuIHBhcmFtZXRlcnMgYXJlIG5vdCB2YWxpZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vICMyMSBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyBhbmQgdGhlcmVmb3JlIHdvdWxkIGZpcmUgdGhlIHN0YXRlY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgcHJvbWlzZSBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXlTdGF0ZUNoYW5nZUV2ZW50O1xuICAgICAgICAgICAgICAgIH0pKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IG51bGwgPyB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXRlIDogdGhpcy5fc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSZW5kZXJpbmcoKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5ICYgIzU5OiBJdCBpcyB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlIHRoYXQgc3RhcnRSZW5kZXJpbmcoKSB3aWxsIGZpcnN0IHJlbmRlciBhIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LiBUaGVyZWZvcmVcbiAgICAgICAgICAgICAqIHRoZSBzdGF0ZSBvZiB0aGUgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCBtaWdodCBubyB0cmFuc2l0aW9uIHRvIHJ1bm5pbmcgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAncnVubmluZyc7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnRSZW5kZXJpbmcodGhpcy5kZXN0aW5hdGlvbiwgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGV0dW5lOiAwLFxuICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgIHBlcmlvZGljV2F2ZTogdW5kZWZpbmVkLFxuICAgIHR5cGU6ICdzaW5lJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBPc2NpbGxhdG9yTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBvc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgY29uc3QgbnlxdWlzdCA9IGNvbnRleHQuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUsIG9zY2lsbGF0b3JOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM4MTogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZGV0dW5lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSwgMTUzNjAwLCAtMTUzNjAwKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzY6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5LCBueXF1aXN0LCAtbnlxdWlzdCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZU9zY2lsbGF0b3JOb2RlO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gb3NjaWxsYXRvck5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsICYmIG1lcmdlZE9wdGlvbnMucGVyaW9kaWNXYXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlZE9wdGlvbnMucGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBkZXR1bmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV0dW5lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbmF0aXZlT25FbmRlZCAhPT0gbnVsbCAmJiBuYXRpdmVPbkVuZGVkID09PSB3cmFwcGVkTGlzdGVuZXIgPyB2YWx1ZSA6IG5hdGl2ZU9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgdHlwZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZSA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIucGVyaW9kaWNXYXZlID0gcGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5zdGFydCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHBlcmlvZGljV2F2ZSA9IG51bGw7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlT3NjaWxsYXRvck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlT3NjaWxsYXRvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZXR1bmU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5OiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZTogcGVyaW9kaWNXYXZlID09PSBudWxsID8gdW5kZWZpbmVkIDogcGVyaW9kaWNXYXZlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS50eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVPc2NpbGxhdG9yTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBwZXJpb2RpY1dhdmUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUgPSByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlT3NjaWxsYXRvck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgY29uZUlubmVyQW5nbGU6IDM2MCxcbiAgICBjb25lT3V0ZXJBbmdsZTogMzYwLFxuICAgIGNvbmVPdXRlckdhaW46IDAsXG4gICAgZGlzdGFuY2VNb2RlbDogJ2ludmVyc2UnLFxuICAgIG1heERpc3RhbmNlOiAxMDAwMCxcbiAgICBvcmllbnRhdGlvblg6IDEsXG4gICAgb3JpZW50YXRpb25ZOiAwLFxuICAgIG9yaWVudGF0aW9uWjogMCxcbiAgICBwYW5uaW5nTW9kZWw6ICdlcXVhbHBvd2VyJyxcbiAgICBwb3NpdGlvblg6IDAsXG4gICAgcG9zaXRpb25ZOiAwLFxuICAgIHBvc2l0aW9uWjogMCxcbiAgICByZWZEaXN0YW5jZTogMSxcbiAgICByb2xsb2ZmRmFjdG9yOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhbm5lck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFBhbm5lck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHBhbm5lck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZVBhbm5lck5vZGUsIHBhbm5lck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlID0gbmF0aXZlUGFubmVyTm9kZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblggPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblkgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblksIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblogPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblosIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblggPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblkgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblksIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblogPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblosIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lSW5uZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lT3V0ZXJHYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZU91dGVyR2Fpbih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRpc3RhbmNlTW9kZWwoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWwgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4RGlzdGFuY2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWF4RGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25YKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25ZKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25aKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHNldCBwYW5uaW5nTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucmVmRGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHJlZkRpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJvbGxvZmZGYWN0b3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICB9XG4gICAgICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3IgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFubmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHJlbmRlcmVkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBuYXRpdmVQYW5uZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgY29uZUlubmVyQW5nbGU6IG5hdGl2ZVBhbm5lck5vZGUuY29uZUlubmVyQW5nbGUsXG4gICAgICAgICAgICAgICAgY29uZU91dGVyQW5nbGU6IG5hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUsXG4gICAgICAgICAgICAgICAgY29uZU91dGVyR2FpbjogbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluLFxuICAgICAgICAgICAgICAgIGRpc3RhbmNlTW9kZWw6IG5hdGl2ZVBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbCxcbiAgICAgICAgICAgICAgICBtYXhEaXN0YW5jZTogbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZSxcbiAgICAgICAgICAgICAgICBwYW5uaW5nTW9kZWw6IG5hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsLFxuICAgICAgICAgICAgICAgIHJlZkRpc3RhbmNlOiBuYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlLFxuICAgICAgICAgICAgICAgIHJvbGxvZmZGYWN0b3I6IG5hdGl2ZVBhbm5lck5vZGUucm9sbG9mZkZhY3RvclxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVQYW5uZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZVBhbm5lck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxMjQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmeWluZyB0aGUgb3JpZW50YXRpb24gYW5kIHRoZSBwb3NpdGlvbiB3aXRoIEF1ZGlvUGFyYW1zLlxuICAgICAgICAgICAgaWYgKCdidWZmZXJTaXplJyBpbiBuYXRpdmVQYW5uZXJOb2RlKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5jb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWi52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlID09PSBudWxsID8gbmF0aXZlUGFubmVyTm9kZSA6IG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVHYWluTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZEJ1ZmZlclByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoNiwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICAgICAgICAgIHByb3h5LmNvbnRleHQubGVuZ3RoLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDZcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3QocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJlZEJ1ZmZlclByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlcyA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5vcmllbnRhdGlvblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkub3JpZW50YXRpb25ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5Lm9yaWVudGF0aW9uWixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3NpdGlvblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkucG9zaXRpb25ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5LnBvc2l0aW9uWlxuICAgICAgICAgICAgICAgICAgICAgICAgXS5tYXAoYXN5bmMgKGF1ZGlvUGFyYW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGluZGV4ID09PSAwID8gMSA6IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzW2ldLmNvbm5lY3QobmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIDAsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXNbaV0uc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkQnVmZmVyID0gYXdhaXQgcmVuZGVyZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVsczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxEYXRhcy5wdXNoKHJlbmRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RPcmllbnRhdGlvbiA9IFtjaGFubmVsRGF0YXNbMF1bMF0sIGNoYW5uZWxEYXRhc1sxXVswXSwgY2hhbm5lbERhdGFzWzJdWzBdXTtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gW2NoYW5uZWxEYXRhc1szXVswXSwgY2hhbm5lbERhdGFzWzRdWzBdLCBjaGFubmVsRGF0YXNbNV1bMF1dO1xuICAgICAgICAgICAgICAgIGxldCBnYXRlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICAgICAgbGV0IHBhcnRpYWxQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblg6IGxhc3RPcmllbnRhdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBsYXN0T3JpZW50YXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbGFzdE9yaWVudGF0aW9uWzJdLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblg6IGxhc3RQb3NpdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBsYXN0UG9zaXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbGFzdFBvc2l0aW9uWzJdXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGdhdGVHYWluTm9kZSkuY29ubmVjdChwYXJ0aWFsUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxMjg7IGkgPCByZW5kZXJlZEJ1ZmZlci5sZW5ndGg7IGkgKz0gMTI4KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW2NoYW5uZWxEYXRhc1swXVtpXSwgY2hhbm5lbERhdGFzWzFdW2ldLCBjaGFubmVsRGF0YXNbMl1baV1dO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW2NoYW5uZWxEYXRhc1szXVtpXSwgY2hhbm5lbERhdGFzWzRdW2ldLCBjaGFubmVsRGF0YXNbNV1baV1dO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3JpZW50YXRpb24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0b24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gaSAvIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHsgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBsYXN0T3JpZW50YXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBsYXN0T3JpZW50YXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBsYXN0T3JpZW50YXRpb25bMl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBsYXN0UG9zaXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBsYXN0UG9zaXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBsYXN0UG9zaXRpb25bMl1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2F0ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGdhdGVHYWluTm9kZSkuY29ubmVjdChwYXJ0aWFsUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGlhbFBhbm5lck5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuYXRpdmVQYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblksIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblopO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblksIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWik7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVQYW5uZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVQYW5uZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlUGFubmVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlUGFubmVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVPck5hdGl2ZVBhbm5lck5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBkaXNhYmxlTm9ybWFsaXphdGlvbjogZmFsc2Vcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgPSAoY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlLCBnZXROYXRpdmVDb250ZXh0LCBwZXJpb2RpY1dhdmVTdG9yZSwgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFBlcmlvZGljV2F2ZSB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyh7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9KTtcbiAgICAgICAgICAgIGNvbnN0IHBlcmlvZGljV2F2ZSA9IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIHBlcmlvZGljV2F2ZVN0b3JlLmFkZChwZXJpb2RpY1dhdmUpO1xuICAgICAgICAgICAgLy8gVGhpcyBkb2VzIHZpb2xhdGUgYWxsIGdvb2QgcHJhdGljZXMgYnV0IGl0IGlzIHVzZWQgaGVyZSB0byBzaW1wbGlmeSB0aGUgaGFuZGxpbmcgb2YgcGVyaW9kaWMgd2F2ZXMuXG4gICAgICAgICAgICByZXR1cm4gcGVyaW9kaWNXYXZlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShpbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuICgoaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlID09PSAnb2JqZWN0JyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpID09PSBQZXJpb2RpY1dhdmUucHJvdG90eXBlKSB8fFxuICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZVN0b3JlLmhhcyhpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wZXJpb2RpYy13YXZlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJBdXRvbWF0aW9uID0gKGdldEF1ZGlvUGFyYW1SZW5kZXJlciwgcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1SZW5kZXJlciA9IGdldEF1ZGlvUGFyYW1SZW5kZXJlcihhdWRpb1BhcmFtKTtcbiAgICAgICAgYXVkaW9QYXJhbVJlbmRlcmVyLnJlcGxheShuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgcmV0dXJuIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbShhdWRpb1BhcmFtLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1hdXRvbWF0aW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSA9IChnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGlzUGFydE9mQUN5Y2xlKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChhdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGF1ZGlvTm9kZUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0c1xuICAgICAgICAgICAgLm1hcCgoY29ubmVjdGlvbnMsIGlucHV0KSA9PiBBcnJheS5mcm9tKGNvbm5lY3Rpb25zKS5tYXAoYXN5bmMgKFtzb3VyY2UsIG91dHB1dF0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvTm9kZVJlbmRlcmVyID0gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gYXdhaXQgYXVkaW9Ob2RlUmVuZGVyZXIucmVuZGVyKHNvdXJjZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IGF1ZGlvTm9kZS5jb250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgaWYgKCFpc1BhcnRPZkFDeWNsZShzb3VyY2UpICYmIChhdWRpb05vZGUgIT09IGRlc3RpbmF0aW9uIHx8ICFpc1BhcnRPZkFDeWNsZShhdWRpb05vZGUpKSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpXG4gICAgICAgICAgICAucmVkdWNlKChhbGxSZW5kZXJpbmdQcm9taXNlcywgcmVuZGVyaW5nUHJvbWlzZXMpID0+IFsuLi5hbGxSZW5kZXJpbmdQcm9taXNlcywgLi4ucmVuZGVyaW5nUHJvbWlzZXNdLCBbXSkpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gPSAoZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgaXNQYXJ0T2ZBQ3ljbGUpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGF1ZGlvUGFyYW0sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0pO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5hY3RpdmVJbnB1dHMpLm1hcChhc3luYyAoW3NvdXJjZSwgb3V0cHV0XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Ob2RlUmVuZGVyZXIgPSBnZXRBdWRpb05vZGVSZW5kZXJlcihzb3VyY2UpO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSBhd2FpdCBhdWRpb05vZGVSZW5kZXJlci5yZW5kZXIoc291cmNlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWlucHV0cy1vZi1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIHRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIHlldC5cbiAgICAgICAgaWYgKGNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGFkdmFuY2UgY3VycmVudFRpbWUgaWYgaXQgaXMgbm90IGFjY2Vzc2VkIHdoaWxlIHJlbmRlcmluZyB0aGUgYXVkaW8uXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlVGVzdFJlc3VsdCh0ZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCwgdGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQpKS50aGVuKChpc09mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnRlZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgNTEyLCAwLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKCkgPT4gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jdXJyZW50VGltZTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbm5lY3QobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNDg6IFNhZmFyaSBkb2VzIG5vdCByZW5kZXIgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRob3V0IGFueSBjb25uZWN0ZWQgbm9kZS5cbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICBnYWluOiAwXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGV2ZW50LnJlbmRlcmVkQnVmZmVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBnYWluTm9kZS5jb25uZWN0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKSA9PiB7XG4gICAgICAgIGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZS5zZXQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSAoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCB0YWlsVGltZSkgPT4gYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZS5zZXQoYXVkaW9Ob2RlLCB0YWlsVGltZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzLm1hcCIsImltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlU3RhcnRSZW5kZXJpbmcgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiBnZXRBdWRpb05vZGVSZW5kZXJlcihkZXN0aW5hdGlvbilcbiAgICAgICAgLnJlbmRlcihkZXN0aW5hdGlvbiwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dClcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICM4NiAmICM4NzogSW52b2tpbmcgdGhlIHJlbmRlcmVyIG9mIGFuIEF1ZGlvV29ya2xldE5vZGUgbWlnaHQgYmUgbmVjZXNzYXJ5IGlmIGl0IGhhcyBubyBkaXJlY3Qgb3IgaW5kaXJlY3QgY29ubmVjdGlvbiB0byB0aGVcbiAgICAgICAgICogZGVzdGluYXRpb24uXG4gICAgICAgICAqL1xuICAgICAgICAudGhlbigoKSA9PiBQcm9taXNlLmFsbChBcnJheS5mcm9tKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkubWFwKChhdWRpb1dvcmtsZXROb2RlKSA9PiBnZXRBdWRpb05vZGVSZW5kZXJlcihhdWRpb1dvcmtsZXROb2RlKS5yZW5kZXIoYXVkaW9Xb3JrbGV0Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSlcbiAgICAgICAgLnRoZW4oKCkgPT4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSlcbiAgICAgICAgLnRoZW4oKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgLy8gQnVnICMxMDA6IFNhZmFyaSBkb2VzIHRocm93IGEgd3JvbmcgZXJyb3Igd2hlbiBjYWxsaW5nIGdldENoYW5uZWxEYXRhKCkgd2l0aCBhbiBvdXQtb2YtYm91bmRzIHZhbHVlLlxuICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0KGF1ZGlvQnVmZmVyKSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGFydC1yZW5kZXJpbmcuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTA1OiBUaGUgY2hhbm5lbENvdW50TW9kZSBzaG91bGQgYmUgJ2NsYW1wZWQtbWF4JyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgYnV0IGlzIHNldCB0byAnZXhwbGljaXQnIHRvIGFjaGlldmUgY29uc2lzdGVudFxuICAgICAqIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIHBhbjogMFxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFN0ZXJlb1Bhbm5lck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIHN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9wYW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFuO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlU3RlcmVvUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIHBhbjogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4udmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wYW4sIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBhbiwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlU3RlcmVvUGFubmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlU3RlcmVvUGFubmVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCIvLyBCdWcgIzMzOiBTYWZhcmkgZXhwb3NlcyBhbiBBdWRpb0J1ZmZlciBidXQgaXQgY2FuJ3QgYmUgdXNlZCBhcyBhIGNvbnN0cnVjdG9yLlxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydCA9IChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGg6IDEsIHNhbXBsZVJhdGU6IDQ0MTAwIH0pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLXVudXNlZC1leHByZXNzaW9uXG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItY29uc3RydWN0b3Itc3VwcG9ydC5qcy5tYXAiLCIvLyBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gQnVnICM2MTogSWYgdGhlcmUgaXMgbm8gbmF0aXZlIEF1ZGlvV29ya2xldE5vZGUgaXQgZ2V0cyBmYWtlZCBhbmQgdGhlcmVmb3JlIGl0IGlzIG5vIHByb2JsZW0gaWYgdGhlIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoWydjbGFzcyBBIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29ye3Byb2Nlc3MoaSl7dGhpcy5wb3J0LnBvc3RNZXNzYWdlKGksW2lbMF1bMF0uYnVmZmVyXSl9fXJlZ2lzdGVyUHJvY2Vzc29yKFwiYVwiLEEpJ10sIHtcbiAgICAgICAgICAgIHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04J1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxNDE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNyZWF0aW5nIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aCBsZXNzIHRoYW4gNDQxMDAgSHouXG4gICAgICAgIGNvbnN0IG9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEyOCwgNDQxMDApO1xuICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBsZXQgaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgbGV0IGlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgb2ZmbGluZUF1ZGlvQ29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihvZmZsaW5lQXVkaW9Db250ZXh0LCAnYScsIHsgbnVtYmVyT2ZPdXRwdXRzOiAwIH0pO1xuICAgICAgICAgICAgY29uc3Qgb3NjaWxsYXRvciA9IG9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgYXVkaW9Xb3JrbGV0Tm9kZS5wb3J0Lm9ubWVzc2FnZSA9ICgpID0+IChpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyA9IHRydWUpO1xuICAgICAgICAgICAgYXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gKCkgPT4gKGlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cyA9IHRydWUpO1xuICAgICAgICAgICAgb3NjaWxsYXRvci5jb25uZWN0KGF1ZGlvV29ya2xldE5vZGUpO1xuICAgICAgICAgICAgb3NjaWxsYXRvci5zdGFydCgwKTtcbiAgICAgICAgICAgIGF3YWl0IG9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyAmJiAhaXNFbWl0dGluZ1Byb2Nlc3NvckVycm9yRXZlbnRzO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlVGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQgPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgLy8gQnVnICM0ODogU2FmYXJpIGRvZXMgbm90IHJlbmRlciBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGhvdXQgYW55IGNvbm5lY3RlZCBub2RlLlxuICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3VycmVudFRpbWUgIT09IDApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LW9mZmxpbmUtYXVkaW8tY29udGV4dC1jdXJyZW50LXRpbWUtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlVW5rbm93bkVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ1Vua25vd25FcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dW5rbm93bi1lcnJvci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBjdXJ2ZTogbnVsbCxcbiAgICBvdmVyc2FtcGxlOiAnbm9uZSdcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFdhdmVTaGFwZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHdhdmVTaGFwZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICAvLyBAdG9kbyBBZGQgYSBtZWNoYW5pc20gdG8gb25seSBzd2l0Y2ggYSBXYXZlU2hhcGVyTm9kZSB0byBhY3RpdmUgd2hpbGUgaXQgaXMgY29ubmVjdGVkLlxuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlV2F2ZVNoYXBlck5vZGUsIHdhdmVTaGFwZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVXYXZlU2hhcGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY3VydmUodmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTAzOiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gc2V0IHRoZSBjdXJ2ZSB0byBudWxsLlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KFswLCAwXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDQ6IENocm9tZSBhbmQgRWRnZSB3aWxsIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG92ZXJzYW1wbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2F2ZS1zaGFwZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVXYXZlU2hhcGVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlV2F2ZVNoYXBlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVXYXZlU2hhcGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcnNhbXBsZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVXYXZlU2hhcGVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlV2F2ZVNoYXBlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVdhdmVTaGFwZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdmUtc2hhcGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV2luZG93ID0gKCkgPT4gKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IHdpbmRvdyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD13aW5kb3cuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyA9IChjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPSAoZGVzdGluYXRpb24sIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxOdW1iZXIgPj0gYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlckxlbmd0aCA9IGF1ZGlvQnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcik7XG4gICAgICAgICAgICBjb25zdCBkZXN0aW5hdGlvbkxlbmd0aCA9IGRlc3RpbmF0aW9uLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBidWZmZXJPZmZzZXQgPCAwID8gLWJ1ZmZlck9mZnNldCA6IDA7IGkgKyBidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlckxlbmd0aCAmJiBpIDwgZGVzdGluYXRpb25MZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uW2ldID0gY2hhbm5lbERhdGFbaSArIGJ1ZmZlck9mZnNldF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwgPSAoc291cmNlLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgIGlmIChjaGFubmVsTnVtYmVyID49IGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJMZW5ndGggPSBhdWRpb0J1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlTGVuZ3RoID0gc291cmNlLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBidWZmZXJPZmZzZXQgPCAwID8gLWJ1ZmZlck9mZnNldCA6IDA7IGkgKyBidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlckxlbmd0aCAmJiBpIDwgc291cmNlTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsRGF0YVtpICsgYnVmZmVyT2Zmc2V0XSA9IHNvdXJjZVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyA9IChjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9ICgoY29weUZyb21DaGFubmVsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGlmIChidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvcHlGcm9tQ2hhbm5lbC5jYWxsKGF1ZGlvQnVmZmVyLCBkZXN0aW5hdGlvbiwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwpO1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID0gKChjb3B5VG9DaGFubmVsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKHNvdXJjZSwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5VG9DaGFubmVsLmNhbGwoYXVkaW9CdWZmZXIsIHNvdXJjZSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyID0gKG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG51bGxpZmllZEJ1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBudWxsaWZpZWRCdWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgJ2J1ZmZlcicsIChnZXQpID0+ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbGlmaWVkQnVmZmVyID8gbnVsbCA6IHZhbHVlO1xuICAgICAgICB9LCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHZhbHVlID09PSBudWxsID8gbnVsbGlmaWVkQnVmZmVyIDogdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzE1OiBTYWZhcmkgZG9lcyBub3QgcmV0dXJuIHRoZSBkZWZhdWx0IHByb3BlcnRpZXMuXG4gICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuICAgICAgICAvLyBCdWcgIzE2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBzZXR0aW5nIGEgZGlmZmVyZW50IGNoYW5uZWxDb3VudCBvciBjaGFubmVsQ291bnRNb2RlLlxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbE1lcmdlck5vZGUsICdjaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IDEsXG4gICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxNZXJnZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzIwOiBTYWZhcmkgcmVxdWlyZXMgYSBjb25uZWN0aW9uIG9mIGFueSBraW5kIHRvIHRyZWF0IHRoZSBpbnB1dCBzaWduYWwgY29ycmVjdGx5LlxuICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gY2hhbm5lbE1lcmdlck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICBtb25pdG9yQ29ubmVjdGlvbnMoY2hhbm5lbE1lcmdlck5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1jaGFubmVsLW1lcmdlci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBnZXRGaXJzdFNhbXBsZSA9IChhdWRpb0J1ZmZlciwgYnVmZmVyLCBjaGFubmVsTnVtYmVyKSA9PiB7XG4gICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgIGlmIChhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcilbMF07XG4gICAgfVxuICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbChidWZmZXIsIGNoYW5uZWxOdW1iZXIpO1xuICAgIHJldHVybiBidWZmZXJbMF07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWZpcnN0LXNhbXBsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNEQ0N1cnZlID0gKGN1cnZlKSA9PiB7XG4gICAgaWYgKGN1cnZlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgbGVuZ3RoID0gY3VydmUubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggJSAyICE9PSAwKSB7XG4gICAgICAgIHJldHVybiBjdXJ2ZVtNYXRoLmZsb29yKGxlbmd0aCAvIDIpXSAhPT0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnZlW2xlbmd0aCAvIDIgLSAxXSArIGN1cnZlW2xlbmd0aCAvIDJdICE9PSAwO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWRjLWN1cnZlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBvdmVyd3JpdGVBY2Nlc3NvcnMgPSAob2JqZWN0LCBwcm9wZXJ0eSwgY3JlYXRlR2V0dGVyLCBjcmVhdGVTZXR0ZXIpID0+IHtcbiAgICBsZXQgcHJvdG90eXBlID0gb2JqZWN0O1xuICAgIHdoaWxlICghcHJvdG90eXBlLmhhc093blByb3BlcnR5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICB9XG4gICAgY29uc3QgeyBnZXQsIHNldCB9ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90b3R5cGUsIHByb3BlcnR5KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgeyBnZXQ6IGNyZWF0ZUdldHRlcihnZXQpLCBzZXQ6IGNyZWF0ZVNldHRlcihzZXQpIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW92ZXJ3cml0ZS1hY2Nlc3NvcnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAob3B0aW9ucykgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIG91dHB1dENoYW5uZWxDb3VudDogb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudFxuICAgICAgICAgICAgOiBvcHRpb25zLm51bWJlck9mSW5wdXRzID09PSAxICYmIG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAxXG4gICAgICAgICAgICAgICAgPyAvKlxuICAgICAgICAgICAgICAgICAgICogQnVnICM2MTogVGhpcyBzaG91bGQgYmUgdGhlIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscywgYnV0IHVuZm9ydHVuYXRlbHkgdGhhdCBpcyBhbG1vc3QgaW1wb3NzaWJsZSB0byBmYWtlLiBUaGF0J3Mgd2h5XG4gICAgICAgICAgICAgICAgICAgKiB0aGUgY2hhbm5lbENvdW50TW9kZSBpcyByZXF1aXJlZCB0byBiZSAnZXhwbGljaXQnIGFzIGxvbmcgYXMgdGhlcmUgaXMgbm90IGEgbmF0aXZlIGltcGxlbWVudGF0aW9uIGluIGV2ZXJ5IGJyb3dzZXIuIFRoYXRcbiAgICAgICAgICAgICAgICAgICAqIG1ha2VzIHN1cmUgdGhlIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyBlcXVpdmlsYW50IHRvIHRoZSBjaGFubmVsQ291bnQgd2hpY2ggbWFrZXMgaXQgbXVjaCBlYXNpZXIgdG8gY29tcHV0ZS5cbiAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBbb3B0aW9ucy5jaGFubmVsQ291bnRdXG4gICAgICAgICAgICAgICAgOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyB9LCAoKSA9PiAxKVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2FuaXRpemUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgY2hhbm5lbENvdW50OiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNhbml0aXplLWNoYW5uZWwtc3BsaXR0ZXItb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IGltYWcsIHJlYWwgfSA9IG9wdGlvbnM7XG4gICAgaWYgKGltYWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAocmVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnOiBbMCwgMF0sIHJlYWw6IFswLCAwXSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWc6IEFycmF5LmZyb20ocmVhbCwgKCkgPT4gMCksIHJlYWwgfTtcbiAgICB9XG4gICAgaWYgKHJlYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnLCByZWFsOiBBcnJheS5mcm9tKGltYWcsICgpID0+IDApIH07XG4gICAgfVxuICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWcsIHJlYWwgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zYW5pdGl6ZS1wZXJpb2RpYy13YXZlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSA9IChhdWRpb1BhcmFtLCB2YWx1ZSwgc3RhcnRUaW1lKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZXJyLmNvZGUgIT09IDkpIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUoYXVkaW9QYXJhbSwgdmFsdWUsIHN0YXJ0VGltZSArIDFlLTcpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtdmFsdWUtYXQtdGltZS11bnRpbC1wb3NzaWJsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgNDQxMDApO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlcjtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoMCwgMSk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoLTEpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiBlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCA0NDEwMCk7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXI7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoLTEpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiBlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHkuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nID0gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCA9ICgoc3RhcnQpID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXI7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NDogU2FmYXJpIGRvZXMgbm90IGNsYW1wIHRoZSBvZmZzZXQgaWYgaXQgaXMgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLlxuICAgICAgICAgICAgY29uc3QgY2xhbXBlZE9mZnNldCA9IGJ1ZmZlciA9PT0gbnVsbCA/IG9mZnNldCA6IE1hdGgubWluKGJ1ZmZlci5kdXJhdGlvbiwgb2Zmc2V0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU1OiBTYWZhcmkgZG9lcyBub3QgaGFuZGxlIHRoZSBvZmZzZXQgY29ycmVjdGx5IGlmIGl0IHdvdWxkIGNhdXNlIHRoZSBidWZmZXIgdG8gYmUgbm90IGJlIHBsYXllZCBhdCBhbGwuXG4gICAgICAgICAgICBpZiAoYnVmZmVyICE9PSBudWxsICYmIGNsYW1wZWRPZmZzZXQgPiBidWZmZXIuZHVyYXRpb24gLSAwLjUgLyBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29udGV4dC5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIDAsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIGNsYW1wZWRPZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzID0gKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgIGNvbnN0IGRpc2Nvbm5lY3RHYWluTm9kZSA9ICgoZGlzY29ubmVjdCkgPT4ge1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMSBhcmd1bWVudCB5ZXQuXG4gICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0R2Fpbk5vZGUpO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5kaXNjb25uZWN0KTtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0R2Fpbk5vZGUpO1xuICAgIGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wID0gKChzdG9wKSA9PiB7XG4gICAgICAgIGxldCBpc1N0b3BwZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzU3RvcHBlZCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgd2hlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICAgICAgaXNTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBFdmVudExpc3RlbmVyID0gKHRhcmdldCwgZXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiAoZXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsgdmFsdWU6IHRhcmdldCB9O1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhldmVudCwge1xuICAgICAgICAgICAgY3VycmVudFRhcmdldDogZGVzY3JpcHRvcixcbiAgICAgICAgICAgIHRhcmdldDogZGVzY3JpcHRvclxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRMaXN0ZW5lci5jYWxsKHRhcmdldCwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBldmVudExpc3RlbmVyLmhhbmRsZUV2ZW50LmNhbGwodGFyZ2V0LCBldmVudCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWV2ZW50LWxpc3RlbmVyLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgfSBmcm9tICdhdXRvbWF0aW9uLWV2ZW50cyc7XG5pbXBvcnQgeyBjcmVhdGVBYm9ydEVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWJvcnQtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlQWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGNyZWF0ZUFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb1dvcmtsZXRNb2R1bGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8td29ya2xldC1tb2R1bGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkU2lsZW50Q29ubmVjdGlvbiB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1zaWxlbnQtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBbmFseXNlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1saXN0ZW5lci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tcGFyYW0tcmVuZGVyZXInO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDYWNoZVRlc3RSZXN1bHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9jYWNoZS10ZXN0LXJlc3VsdCc7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdC1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzJztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nJztcbmltcG9ydCB7IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9jcmVhdGUtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVEYXRhQ2xvbmVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2RhdGEtY2xvbmUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlRGVjb2RlQXVkaW9EYXRhIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVjb2RlLWF1ZGlvLWRhdGEnO1xuaW1wb3J0IHsgY3JlYXRlRGVjcmVtZW50Q3ljbGVDb3VudGVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVjcmVtZW50LWN5Y2xlLWNvdW50ZXInO1xuaW1wb3J0IHsgY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxheS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVEZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZURlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsZXRlLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZURldGVjdEN5Y2xlcyB9IGZyb20gJy4vZmFjdG9yaWVzL2RldGVjdC1jeWNsZXMnO1xuaW1wb3J0IHsgY3JlYXRlRGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2Rpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2R5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUVuY29kaW5nRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9lbmNvZGluZy1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVFdmFsdWF0ZVNvdXJjZSB9IGZyb20gJy4vZmFjdG9yaWVzL2V2YWx1YXRlLXNvdXJjZSc7XG5pbXBvcnQgeyBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXhwb3NlLWN1cnJlbnQtZnJhbWUtYW5kLWN1cnJlbnQtdGltZSc7XG5pbXBvcnQgeyBjcmVhdGVGZXRjaFNvdXJjZSB9IGZyb20gJy4vZmFjdG9yaWVzL2ZldGNoLXNvdXJjZSc7XG5pbXBvcnQgeyBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2Fpbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2Fpbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb05vZGVSZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXJlbmRlcmVyJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvUGFyYW1SZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1wYXJhbS1yZW5kZXJlcic7XG5pbXBvcnQgeyBjcmVhdGVHZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0TmF0aXZlQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1uYXRpdmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcyc7XG5pbXBvcnQgeyBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbmNyZW1lbnQtY3ljbGUtY291bnRlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUluZGV4U2l6ZUVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbnZhbGlkLWFjY2Vzcy1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueUF1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUlzQW55QXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVDb250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc1NlY3VyZUNvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1zZWN1cmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc1N1cHBvcnRlZFByb21pc2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1zdXBwb3J0ZWQtcHJvbWlzZSc7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9taW5pbWFsLWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTW9uaXRvckNvbm5lY3Rpb25zIH0gZnJvbSAnLi9mYWN0b3JpZXMvbW9uaXRvci1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYmlxdWFkLWZpbHRlci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLW1lcmdlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLXNwbGl0dGVyLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNvbnZvbHZlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlRGVsYXlOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWRlbGF5LW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlR2Fpbk5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZ2Fpbi1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtcGFubmVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1wZXJpb2RpYy13YXZlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zY3JpcHQtcHJvY2Vzc29yLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL25vdC1zdXBwb3J0ZWQtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVQZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3BlcmlvZGljLXdhdmUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVyQXV0b21hdGlvbiB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1hdXRvbWF0aW9uJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9zZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUgfSBmcm9tICcuL2ZhY3Rvcmllcy9zZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlU3RhcnRSZW5kZXJpbmcgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGFydC1yZW5kZXJpbmcnO1xuaW1wb3J0IHsgY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc1N1YmFycmF5U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLXN1YmFycmF5LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dENsb3NlTWV0aG9kU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1jbG9zZS1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Db250ZXh0RGVjb2RlQXVkaW9EYXRhTWV0aG9kVHlwZUVycm9yU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1kZWNvZGUtYXVkaW8tZGF0YS1tZXRob2QtdHlwZS1lcnJvci1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRPcHRpb25zU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1vcHRpb25zLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvTm9kZUNvbm5lY3RNZXRob2RTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1ub2RlLWNvbm5lY3QtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3Nvck5vT3V0cHV0c1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLW5vLW91dHB1dHMtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q2hhbm5lbE1lcmdlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1jaGFubmVsLW1lcmdlci1ub2RlLWNoYW5uZWwtY291bnQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29uc3RhbnRTb3VyY2VOb2RlQWNjdXJhdGVTY2hlZHVsaW5nU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29uc3RhbnQtc291cmNlLW5vZGUtYWNjdXJhdGUtc2NoZWR1bGluZy1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQnVmZmVyUmVhc3NpZ25hYmlsaXR5U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29udm9sdmVyLW5vZGUtYnVmZmVyLXJlYXNzaWduYWJpbGl0eS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29udm9sdmVyLW5vZGUtY2hhbm5lbC1jb3VudC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RJc1NlY3VyZUNvbnRleHRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1pcy1zZWN1cmUtY29udGV4dC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZU1lZGlhU3RyZWFtV2l0aG91dEF1ZGlvVHJhY2tTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtbWVkaWEtc3RyZWFtLXdpdGhvdXQtYXVkaW8tdHJhY2stc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3Qtb2ZmbGluZS1hdWRpby1jb250ZXh0LWN1cnJlbnQtdGltZS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RTdGVyZW9QYW5uZXJOb2RlRGVmYXVsdFZhbHVlU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3Qtc3RlcmVvLXBhbm5lci1ub2RlLWRlZmF1bHQtdmFsdWUtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVVbmtub3duRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy91bmtub3duLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZVdpbmRvdyB9IGZyb20gJy4vZmFjdG9yaWVzL3dpbmRvdyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyJztcbmltcG9ydCB7IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtY2hhbm5lbC1tZXJnZXItbm9kZSc7XG5pbXBvcnQgeyBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFLCBBVURJT19OT0RFX1NUT1JFLCBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSwgQVVESU9fUEFSQU1fU1RPUkUsIENPTlRFWFRfU1RPUkUsIENZQ0xFX0NPVU5URVJTIH0gZnJvbSAnLi9nbG9iYWxzJztcbmltcG9ydCB7IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEZpcnN0U2FtcGxlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1maXJzdC1zYW1wbGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb1BhcmFtIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBpc0RDQ3VydmUgfSBmcm9tICcuL2hlbHBlcnMvaXMtZGMtY3VydmUnO1xuaW1wb3J0IHsgaXNQYXJ0T2ZBQ3ljbGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtcGFydC1vZi1hLWN5Y2xlJztcbmltcG9ydCB7IGlzUGFzc2l2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9pcy1wYXNzaXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgb3ZlcndyaXRlQWNjZXNzb3JzIH0gZnJvbSAnLi9oZWxwZXJzL292ZXJ3cml0ZS1hY2Nlc3NvcnMnO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9oZWxwZXJzL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5pbXBvcnQgeyBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLXBlcmlvZGljLXdhdmUtb3B0aW9ucyc7XG5pbXBvcnQgeyBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUgfSBmcm9tICcuL2hlbHBlcnMvc2V0LXZhbHVlLWF0LXRpbWUtdW50aWwtcG9zc2libGUnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHknO1xuaW1wb3J0IHsgdGVzdERvbUV4Y2VwdGlvbkNvbnN0cnVjdG9yU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWRvbS1leGNlcHRpb24tY29uc3RydWN0b3Itc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdFRyYW5zZmVyYWJsZXNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtdHJhbnNmZXJhYmxlcy1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzJztcbmltcG9ydCB7IHdyYXBFdmVudExpc3RlbmVyIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtZXZlbnQtbGlzdGVuZXInO1xuLypcbiAqIEB0b2RvIEV4cGxpY2l0bHkgcmVmZXJlbmNpbmcgdGhlIGJhcnJlbCBmaWxlIHNlZW1zIHRvIGJlIG5lY2Vzc2FyeSB3aGVuIGVuYWJsaW5nIHRoZVxuICogaXNvbGF0ZWRNb2R1bGVzIGNvbXBpbGVyIG9wdGlvbi5cbiAqL1xuZXhwb3J0ICogZnJvbSAnLi9pbnRlcmZhY2VzL2luZGV4JztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMvaW5kZXgnO1xuY29uc3QgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBjcmVhdGVBZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShpbnNlcnRFbGVtZW50SW5TZXQpO1xuY29uc3QgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gY3JlYXRlQWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGluc2VydEVsZW1lbnRJblNldCk7XG5jb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGNyZWF0ZURlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBpY2tFbGVtZW50RnJvbVNldCk7XG5jb25zdCBhdWRpb05vZGVUYWlsVGltZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldEF1ZGlvTm9kZVRhaWxUaW1lID0gY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSk7XG5jb25zdCBjYWNoZVRlc3RSZXN1bHQgPSBjcmVhdGVDYWNoZVRlc3RSZXN1bHQobmV3IE1hcCgpLCBuZXcgV2Vha01hcCgpKTtcbmNvbnN0IHdpbmRvdyA9IGNyZWF0ZVdpbmRvdygpO1xuY29uc3QgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGdldEF1ZGlvTm9kZVJlbmRlcmVyID0gY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMpO1xuY29uc3QgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUgPSBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGlzUGFydE9mQUN5Y2xlKTtcbmNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyID0gY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBnZXROYXRpdmVDb250ZXh0ID0gY3JlYXRlR2V0TmF0aXZlQ29udGV4dChDT05URVhUX1NUT1JFKTtcbmNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciA9IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3Iod3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBpc05hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZUlzTmF0aXZlQXVkaW9Ob2RlKHdpbmRvdyk7XG5jb25zdCBpc05hdGl2ZUF1ZGlvUGFyYW0gPSBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0od2luZG93KTtcbmNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgYXVkaW9Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvcihjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyhBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFKSwgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlKGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlVGFpbFRpbWUsIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgaW5zZXJ0RWxlbWVudEluU2V0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNQYXJ0T2ZBQ3ljbGUsIGlzUGFzc2l2ZUF1ZGlvTm9kZSksIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeShDWUNMRV9DT1VOVEVSUywgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGlzQWN0aXZlQXVkaW9Ob2RlKSwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlcihjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIENZQ0xFX0NPVU5URVJTLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBnZXROYXRpdmVDb250ZXh0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSwgY3JlYXRlRGV0ZWN0Q3ljbGVzKGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldFZhbHVlRm9yS2V5KSwgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZUF1ZGlvUGFyYW0sIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKTtcbmNvbnN0IGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQW5hbHlzZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IHsgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgYXMgQW5hbHlzZXJOb2RlIH07XG5jb25zdCBhdWRpb0J1ZmZlclN0b3JlID0gbmV3IFdlYWtTZXQoKTtcbmNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHdpbmRvdyk7XG5jb25zdCBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgPSBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcobmV3IFVpbnQzMkFycmF5KDEpKTtcbmNvbnN0IHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyA9IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzID0gY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKTtcbmNvbnN0IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0KG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IpLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmV4cG9ydCB7IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgYXMgQXVkaW9CdWZmZXIgfTtcbmNvbnN0IGFkZFNpbGVudENvbm5lY3Rpb24gPSBjcmVhdGVBZGRTaWxlbnRDb25uZWN0aW9uKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKTtcbmNvbnN0IHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSA9IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbShnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBpc1BhcnRPZkFDeWNsZSk7XG5jb25zdCBjb25uZWN0QXVkaW9QYXJhbSA9IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtKHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nLCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlcihvdmVyd3JpdGVBY2Nlc3NvcnMpLCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpO1xuY29uc3QgcmVuZGVyQXV0b21hdGlvbiA9IGNyZWF0ZVJlbmRlckF1dG9tYXRpb24oY3JlYXRlR2V0QXVkaW9QYXJhbVJlbmRlcmVyKGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyksIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSk7XG5jb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeShjcmVhdGVBZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUpLCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIEFVRElPX1BBUkFNX1NUT1JFLCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIsIGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUpO1xuY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuZXhwb3J0IHsgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIH07XG5jb25zdCBhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG92ZXJ3cml0ZUFjY2Vzc29ycyksIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBzZXRBdWRpb05vZGVUYWlsVGltZSA9IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpO1xuY29uc3QgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBtb25pdG9yQ29ubmVjdGlvbnMgPSBjcmVhdGVNb25pdG9yQ29ubmVjdGlvbnMoaW5zZXJ0RWxlbWVudEluU2V0LCBpc05hdGl2ZUF1ZGlvTm9kZSk7XG5jb25zdCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeShuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgd3JhcENoYW5uZWxNZXJnZXJOb2RlKTtcbmNvbnN0IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXJGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCk7XG5jb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciA9IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpO1xuY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyID0gY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZGVsYXlOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVEZWxheU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyID0gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciA9IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBnYWluTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZVRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpKTtcbmNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcik7XG5jb25zdCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUsIGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVBdWRpb0xpc3RlbmVyID0gY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkoY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldEZpcnN0U2FtcGxlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG92ZXJ3cml0ZUFjY2Vzc29ycyk7XG5jb25zdCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvTGlzdGVuZXIsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUgPSBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyk7XG5jb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcik7XG5jb25zdCBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5KGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3ZlcndyaXRlQWNjZXNzb3JzKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRGaXJzdFNhbXBsZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIpO1xuY29uc3QgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBwYW5uZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUgPSBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmVGYWN0b3J5KGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yID0gY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IoY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlLCBnZXROYXRpdmVDb250ZXh0LCBuZXcgV2Vha1NldCgpLCBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMpO1xuY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkobmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGlzU2VjdXJlQ29udGV4dCA9IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCh3aW5kb3cpO1xuY29uc3QgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUgPSBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSh3aW5kb3cpO1xuY29uc3QgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG4vLyBUaGUgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKCkgZnVuY3Rpb24gaXMgb25seSBhdmFpbGFibGUgaW4gYSBTZWN1cmVDb250ZXh0LlxuZXhwb3J0IGNvbnN0IGFkZEF1ZGlvV29ya2xldE1vZHVsZSA9IGlzU2VjdXJlQ29udGV4dFxuICAgID8gY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZUV2YWx1YXRlU291cmNlKHdpbmRvdyksIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBjcmVhdGVGZXRjaFNvdXJjZShjcmVhdGVBYm9ydEVycm9yKSwgZ2V0TmF0aXZlQ29udGV4dCwgZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmV3IFdlYWtNYXAoKSwgbmV3IFdlYWtNYXAoKSwgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIFxuICAgIC8vIEB0b2RvIHdpbmRvdyBpcyBndWFyYW50ZWVkIHRvIGJlIGRlZmluZWQgYmVjYXVzZSBpc1NlY3VyZUNvbnRleHQgY2hlY2tzIHRoYXQgYXMgd2VsbC5cbiAgICB3aW5kb3cpXG4gICAgOiB1bmRlZmluZWQ7XG5jb25zdCBpc05hdGl2ZUNvbnRleHQgPSBjcmVhdGVJc05hdGl2ZUNvbnRleHQoaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgY29uc3QgZGVjb2RlQXVkaW9EYXRhID0gY3JlYXRlRGVjb2RlQXVkaW9EYXRhKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlRGF0YUNsb25lRXJyb3IsIGNyZWF0ZUVuY29kaW5nRXJyb3IsIG5ldyBXZWFrU2V0KCksIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB0ZXN0UHJvbWlzZVN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpO1xuY29uc3QgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGFkZEF1ZGlvV29ya2xldE1vZHVsZSwgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yLCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciwgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciwgZGVjb2RlQXVkaW9EYXRhLCBkZWxheU5vZGVDb25zdHJ1Y3RvciwgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yLCBnYWluTm9kZUNvbnN0cnVjdG9yLCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IsIHBhbm5lck5vZGVDb25zdHJ1Y3RvciwgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IsIHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvciwgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3Rvcik7XG5jb25zdCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQpO1xuY29uc3QgYXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmV4cG9ydCB7IGF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIEF1ZGlvQ29udGV4dCB9O1xuY29uc3QgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID0gY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUpO1xuY29uc3QgYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpO1xuY29uc3QgY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IGNyZWF0ZUNvbm5lY3RNdWx0aXBsZU91dHB1dHMoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpO1xuY29uc3QgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IGNyZWF0ZURpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSBjcmVhdGVHZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSwgZ2V0VmFsdWVGb3JLZXkpO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeShjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyID0gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUpO1xuY29uc3Qgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlKTtcbi8vIFRoZSBBdWRpb1dvcmtsZXROb2RlIGNvbnN0cnVjdG9yIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgU2VjdXJlQ29udGV4dC5cbmNvbnN0IGF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IGlzU2VjdXJlQ29udGV4dFxuICAgID8gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMsIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5LCB3cmFwRXZlbnRMaXN0ZW5lcilcbiAgICA6IHVuZGVmaW5lZDtcbmV4cG9ydCB7IGF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciBhcyBBdWRpb1dvcmtsZXROb2RlIH07XG5leHBvcnQgeyBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgYXMgQmlxdWFkRmlsdGVyTm9kZSB9O1xuZXhwb3J0IHsgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciBhcyBDaGFubmVsTWVyZ2VyTm9kZSB9O1xuZXhwb3J0IHsgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yIGFzIENoYW5uZWxTcGxpdHRlck5vZGUgfTtcbmV4cG9ydCB7IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciBhcyBDb252b2x2ZXJOb2RlIH07XG5leHBvcnQgeyBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBDb25zdGFudFNvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IGRlbGF5Tm9kZUNvbnN0cnVjdG9yIGFzIERlbGF5Tm9kZSB9O1xuZXhwb3J0IHsgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yIGFzIER5bmFtaWNzQ29tcHJlc3Nvck5vZGUgfTtcbmV4cG9ydCB7IGdhaW5Ob2RlQ29uc3RydWN0b3IgYXMgR2Fpbk5vZGUgfTtcbmV4cG9ydCB7IGlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciBhcyBJSVJGaWx0ZXJOb2RlIH07XG5leHBvcnQgeyBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSB9O1xuY29uc3QgbWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5leHBvcnQgeyBtaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgTWluaW1hbEF1ZGlvQ29udGV4dCB9O1xuY29uc3QgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBzdGFydFJlbmRlcmluZyA9IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcywgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmNvbnN0IG1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHN0YXJ0UmVuZGVyaW5nKTtcbmV4cG9ydCB7IG1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHQgfTtcbmNvbnN0IG9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHN0YXJ0UmVuZGVyaW5nKTtcbmV4cG9ydCB7IG9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBPZmZsaW5lQXVkaW9Db250ZXh0IH07XG5leHBvcnQgeyBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yIGFzIE9zY2lsbGF0b3JOb2RlIH07XG5leHBvcnQgeyBwYW5uZXJOb2RlQ29uc3RydWN0b3IgYXMgUGFubmVyTm9kZSB9O1xuZXhwb3J0IHsgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgYXMgUGVyaW9kaWNXYXZlIH07XG5leHBvcnQgeyBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgYXMgU3RlcmVvUGFubmVyTm9kZSB9O1xuZXhwb3J0IHsgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciBhcyBXYXZlU2hhcGVyTm9kZSB9O1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9Db250ZXh0ID0gY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQoQ09OVEVYVF9TVE9SRSwgaXNOYXRpdmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9Ob2RlID0gY3JlYXRlSXNBbnlBdWRpb05vZGUoQVVESU9fTk9ERV9TVE9SRSwgaXNOYXRpdmVBdWRpb05vZGUpO1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9QYXJhbSA9IGNyZWF0ZUlzQW55QXVkaW9QYXJhbShBVURJT19QQVJBTV9TVE9SRSwgaXNOYXRpdmVBdWRpb1BhcmFtKTtcbmV4cG9ydCBjb25zdCBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQoQ09OVEVYVF9TVE9SRSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmV4cG9ydCBjb25zdCBpc1N1cHBvcnRlZCA9ICgpID0+IGNyZWF0ZUlzU3VwcG9ydGVkUHJvbWlzZShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc1N1YmFycmF5U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Db250ZXh0Q2xvc2VNZXRob2RTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dERlY29kZUF1ZGlvRGF0YU1ldGhvZFR5cGVFcnJvclN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dE9wdGlvbnNTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvTm9kZUNvbm5lY3RNZXRob2RTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JOb091dHB1dHNTdXBwb3J0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENoYW5uZWxNZXJnZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29uc3RhbnRTb3VyY2VOb2RlQWNjdXJhdGVTY2hlZHVsaW5nU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUJ1ZmZlclJlYXNzaWduYWJpbGl0eVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIHRlc3REb21FeGNlcHRpb25Db25zdHJ1Y3RvclN1cHBvcnQsIGNyZWF0ZVRlc3RJc1NlY3VyZUNvbnRleHRTdXBwb3J0KHdpbmRvdyksIGNyZWF0ZVRlc3RNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZU1lZGlhU3RyZWFtV2l0aG91dEF1ZGlvVHJhY2tTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdFN0ZXJlb1Bhbm5lck5vZGVEZWZhdWx0VmFsdWVTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIHRlc3RUcmFuc2ZlcmFibGVzU3VwcG9ydCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tb2R1bGUuanMubWFwIiwiLyoqXG4gKiBBc3NlcnQgdGhhdCB0aGUgc3RhdGVtZW50IGlzIHRydWUsIG90aGVyd2lzZSBpbnZva2UgdGhlIGVycm9yLlxuICogQHBhcmFtIHN0YXRlbWVudFxuICogQHBhcmFtIGVycm9yIFRoZSBtZXNzYWdlIHdoaWNoIGlzIHBhc3NlZCBpbnRvIGFuIEVycm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoc3RhdGVtZW50LCBlcnJvcikge1xuICAgIGlmICghc3RhdGVtZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgaXMgd2l0aGluIHRoZSByYW5nZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UmFuZ2UodmFsdWUsIGd0ZSwgbHRlID0gSW5maW5pdHkpIHtcbiAgICBpZiAoIShndGUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gbHRlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVmFsdWUgbXVzdCBiZSB3aXRoaW4gWyR7Z3RlfSwgJHtsdGV9XSwgZ290OiAke3ZhbHVlfWApO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIHdpdGhpbiB0aGUgcmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydENvbnRleHRSdW5uaW5nKGNvbnRleHQpIHtcbiAgICAvLyBhZGQgYSB3YXJuaW5nIGlmIHRoZSBjb250ZXh0IGlzIG5vdCBzdGFydGVkXG4gICAgaWYgKCFjb250ZXh0LmlzT2ZmbGluZSAmJiBjb250ZXh0LnN0YXRlICE9PSBcInJ1bm5pbmdcIikge1xuICAgICAgICB3YXJuKFwiVGhlIEF1ZGlvQ29udGV4dCBpcyBcXFwic3VzcGVuZGVkXFxcIi4gSW52b2tlIFRvbmUuc3RhcnQoKSBmcm9tIGEgdXNlciBhY3Rpb24gdG8gc3RhcnQgdGhlIGF1ZGlvLlwiKTtcbiAgICB9XG59XG4vKipcbiAqIFRoZSBkZWZhdWx0IGxvZ2dlciBpcyB0aGUgY29uc29sZVxuICovXG5sZXQgZGVmYXVsdExvZ2dlciA9IGNvbnNvbGU7XG4vKipcbiAqIFNldCB0aGUgbG9nZ2luZyBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihsb2dnZXIpIHtcbiAgICBkZWZhdWx0TG9nZ2VyID0gbG9nZ2VyO1xufVxuLyoqXG4gKiBMb2cgYW55dGhpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG4gICAgZGVmYXVsdExvZ2dlci5sb2coLi4uYXJncyk7XG59XG4vKipcbiAqIFdhcm4gYW55dGhpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdhcm4oLi4uYXJncykge1xuICAgIGRlZmF1bHRMb2dnZXIud2FybiguLi5hcmdzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlYnVnLmpzLm1hcCIsIi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIHVuZGVmaW5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNVbmRlZihhcmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJ1bmRlZmluZWRcIjtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIG5vdCB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmaW5lZChhcmcpIHtcbiAgICByZXR1cm4gIWlzVW5kZWYoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGEgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwiZnVuY3Rpb25cIjtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBhbiBvYmplY3QgbGl0ZXJhbCAoaS5lLiBge31gKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICAgIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykgPT09IFwiW29iamVjdCBPYmplY3RdXCIgJiYgYXJnLmNvbnN0cnVjdG9yID09PSBPYmplY3QpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhIGJvb2xlYW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcImJvb2xlYW5cIik7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGFuIEFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICAgIHJldHVybiAoQXJyYXkuaXNBcnJheShhcmcpKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBpbiB0aGUgZm9ybSBvZiBhIG5vdGUgaW4gc2NpZW50aWZpYyBwaXRjaCBub3RhdGlvbi5cbiAqIGUuZy4gXCJDNFwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vdGUoYXJnKSB7XG4gICAgcmV0dXJuIGlzU3RyaW5nKGFyZykgJiYgL14oW2EtZ117MX0oPzpifCN8eHxiYik/KSgtP1swLTldKykvaS50ZXN0KGFyZyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UeXBlQ2hlY2suanMubWFwIiwiaW1wb3J0IHsgQXVkaW9Db250ZXh0IGFzIHN0ZEF1ZGlvQ29udGV4dCwgQXVkaW9Xb3JrbGV0Tm9kZSBhcyBzdGRBdWRpb1dvcmtsZXROb2RlLCBPZmZsaW5lQXVkaW9Db250ZXh0IGFzIHN0ZE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwic3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogQ3JlYXRlIGEgbmV3IEF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXVkaW9Db250ZXh0KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IHN0ZEF1ZGlvQ29udGV4dChvcHRpb25zKTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IE9mZmxpbmVBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHQoY2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkge1xuICAgIHJldHVybiBuZXcgc3RkT2ZmbGluZUF1ZGlvQ29udGV4dChjaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbn1cbi8qKlxuICogQSByZWZlcmVuY2UgdG8gdGhlIHdpbmRvdyBvYmplY3RcbiAqIEBoaWRkZW5cbiAqL1xuZXhwb3J0IGNvbnN0IHRoZVdpbmRvdyA9IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IG51bGw7XG4vKipcbiAqIElmIHRoZSBicm93c2VyIGhhcyBhIHdpbmRvdyBvYmplY3Qgd2hpY2ggaGFzIGFuIEF1ZGlvQ29udGV4dFxuICogQGhpZGRlblxuICovXG5leHBvcnQgY29uc3QgaGFzQXVkaW9Db250ZXh0ID0gdGhlV2luZG93ICYmXG4gICAgKHRoZVdpbmRvdy5oYXNPd25Qcm9wZXJ0eShcIkF1ZGlvQ29udGV4dFwiKSB8fCB0aGVXaW5kb3cuaGFzT3duUHJvcGVydHkoXCJ3ZWJraXRBdWRpb0NvbnRleHRcIikpO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUoY29udGV4dCwgbmFtZSwgb3B0aW9ucykge1xuICAgIGFzc2VydChpc0RlZmluZWQoc3RkQXVkaW9Xb3JrbGV0Tm9kZSksIFwiVGhpcyBub2RlIG9ubHkgd29ya3MgaW4gYSBzZWN1cmUgY29udGV4dCAoaHR0cHMgb3IgbG9jYWxob3N0KVwiKTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIG5ldyBzdGRBdWRpb1dvcmtsZXROb2RlKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpO1xufVxuLyoqXG4gKiBUaGlzIHByb21pc2UgcmVzb2x2ZXMgdG8gYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyBpZiB0aGVcbiAqIGZ1bmN0aW9uYWxpdHkgaXMgc3VwcG9ydGVkIHdpdGhpbiB0aGUgY3VycmVudGx5IHVzZWQgYnJvd3NlLlxuICogVGFrZW4gZnJvbSBbc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRdKGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dCNpc3N1cHBvcnRlZClcbiAqL1xuZXhwb3J0IHsgaXNTdXBwb3J0ZWQgYXMgc3VwcG9ydGVkIH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdWRpb0NvbnRleHQuanMubWFwIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnB1c2goXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcclxuICAgIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRJbihzdGF0ZSwgcmVjZWl2ZXIpIHtcclxuICAgIGlmIChyZWNlaXZlciA9PT0gbnVsbCB8fCAodHlwZW9mIHJlY2VpdmVyICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZWNlaXZlciAhPT0gXCJmdW5jdGlvblwiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB1c2UgJ2luJyBvcGVyYXRvciBvbiBub24tb2JqZWN0XCIpO1xyXG4gICAgcmV0dXJuIHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgPT09IHN0YXRlIDogc3RhdGUuaGFzKHJlY2VpdmVyKTtcclxufVxyXG4iLCIvKipcbiAqIEEgY2xhc3Mgd2hpY2ggcHJvdmlkZXMgYSByZWxpYWJsZSBjYWxsYmFjayB1c2luZyBlaXRoZXJcbiAqIGEgV2ViIFdvcmtlciwgb3IgaWYgdGhhdCBpc24ndCBzdXBwb3J0ZWQsIGZhbGxzIGJhY2sgdG8gc2V0VGltZW91dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tlciB7XG4gICAgY29uc3RydWN0b3IoY2FsbGJhY2ssIHR5cGUsIHVwZGF0ZUludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl91cGRhdGVJbnRlcnZhbCA9IHVwZGF0ZUludGVydmFsO1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGNsb2NrIHNvdXJjZSBmb3IgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgdGhpcy5fY3JlYXRlQ2xvY2soKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSB3ZWIgd29ya2VyXG4gICAgICovXG4gICAgX2NyZWF0ZVdvcmtlcigpIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtcbiAgICAgICAgICAgIC8qIGphdmFzY3JpcHQgKi8gYFxuXHRcdFx0Ly8gdGhlIGluaXRpYWwgdGltZW91dCB0aW1lXG5cdFx0XHRsZXQgdGltZW91dFRpbWUgPSAgJHsodGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKS50b0ZpeGVkKDEpfTtcblx0XHRcdC8vIG9ubWVzc2FnZSBjYWxsYmFja1xuXHRcdFx0c2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbihtc2cpe1xuXHRcdFx0XHR0aW1lb3V0VGltZSA9IHBhcnNlSW50KG1zZy5kYXRhKTtcblx0XHRcdH07XG5cdFx0XHQvLyB0aGUgdGljayBmdW5jdGlvbiB3aGljaCBwb3N0cyBhIG1lc3NhZ2Vcblx0XHRcdC8vIGFuZCBzY2hlZHVsZXMgYSBuZXcgdGlja1xuXHRcdFx0ZnVuY3Rpb24gdGljaygpe1xuXHRcdFx0XHRzZXRUaW1lb3V0KHRpY2ssIHRpbWVvdXRUaW1lKTtcblx0XHRcdFx0c2VsZi5wb3N0TWVzc2FnZSgndGljaycpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gY2FsbCB0aWNrIGluaXRpYWxseVxuXHRcdFx0dGljaygpO1xuXHRcdFx0YFxuICAgICAgICBdLCB7IHR5cGU6IFwidGV4dC9qYXZhc2NyaXB0XCIgfSk7XG4gICAgICAgIGNvbnN0IGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBjb25zdCB3b3JrZXIgPSBuZXcgV29ya2VyKGJsb2JVcmwpO1xuICAgICAgICB3b3JrZXIub25tZXNzYWdlID0gdGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5fd29ya2VyID0gd29ya2VyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSB0aW1lb3V0IGxvb3BcbiAgICAgKi9cbiAgICBfY3JlYXRlVGltZW91dCgpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVGltZW91dCgpO1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2soKTtcbiAgICAgICAgfSwgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHRoZSBjbG9jayBzb3VyY2UuXG4gICAgICovXG4gICAgX2NyZWF0ZUNsb2NrKCkge1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVXb3JrZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gd29ya2VycyBub3Qgc3VwcG9ydGVkLCBmYWxsYmFjayB0byB0aW1lb3V0XG4gICAgICAgICAgICAgICAgdGhpcy5fdHlwZSA9IFwidGltZW91dFwiO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJ0aW1lb3V0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRpbWVvdXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cCB0aGUgY3VycmVudCBjbG9jayBzb3VyY2VcbiAgICAgKi9cbiAgICBfZGlzcG9zZUNsb2NrKCkge1xuICAgICAgICBpZiAodGhpcy5fdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5fdGltZW91dCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3dvcmtlcikge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLm9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHJhdGUgaW4gc2Vjb25kcyB0aGUgdGlja2VyIHdpbGwgdXBkYXRlXG4gICAgICovXG4gICAgZ2V0IHVwZGF0ZUludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlSW50ZXJ2YWw7XG4gICAgfVxuICAgIHNldCB1cGRhdGVJbnRlcnZhbChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl91cGRhdGVJbnRlcnZhbCA9IE1hdGgubWF4KGludGVydmFsLCAxMjggLyA0NDEwMCk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcIndvcmtlclwiKSB7XG4gICAgICAgICAgICB0aGlzLl93b3JrZXIucG9zdE1lc3NhZ2UoTWF0aC5tYXgoaW50ZXJ2YWwgKiAxMDAwLCAxKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIHRpY2tlciwgZWl0aGVyIGEgd29ya2VyIG9yIGEgdGltZW91dFxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9kaXNwb3NlQ2xvY2soKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZUNsb2NrKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja2VyLmpzLm1hcCIsImltcG9ydCB7IGlzQW55QXVkaW9Db250ZXh0LCBpc0FueUF1ZGlvTm9kZSwgaXNBbnlBdWRpb1BhcmFtLCBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQsIH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG4vKipcbiAqIFRlc3QgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9QYXJhbVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb1BhcmFtKGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvUGFyYW0oYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb05vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9Ob2RlKGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvTm9kZShhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgaW5zdGFuY2VvZiBhbiBPZmZsaW5lQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJnKSB7XG4gICAgcmV0dXJuIGlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dChhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9Db250ZXh0KGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvQ29udGV4dChhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgaW5zdGFuY2VvZiBhbiBBdWRpb0J1ZmZlclxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb0J1ZmZlcihhcmcpIHtcbiAgICByZXR1cm4gYXJnIGluc3RhbmNlb2YgQXVkaW9CdWZmZXI7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BZHZhbmNlZFR5cGVDaGVjay5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvQnVmZmVyLCBpc0F1ZGlvTm9kZSwgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4vQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNPYmplY3QsIGlzVW5kZWYgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogU29tZSBvYmplY3RzIHNob3VsZCBub3QgYmUgbWVyZ2VkXG4gKi9cbmZ1bmN0aW9uIG5vQ29weShrZXksIGFyZykge1xuICAgIHJldHVybiBrZXkgPT09IFwidmFsdWVcIiB8fCBpc0F1ZGlvUGFyYW0oYXJnKSB8fCBpc0F1ZGlvTm9kZShhcmcpIHx8IGlzQXVkaW9CdWZmZXIoYXJnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkZWVwTWVyZ2UodGFyZ2V0LCAuLi5zb3VyY2VzKSB7XG4gICAgaWYgKCFzb3VyY2VzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgaWYgKGlzT2JqZWN0KHRhcmdldCkgJiYgaXNPYmplY3Qoc291cmNlKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChub0NvcHkoa2V5LCBzb3VyY2Vba2V5XSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXRba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRhcmdldCwgeyBba2V5XToge30gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZXBNZXJnZSh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHNvdXJjZVtrZXldIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gZGVlcE1lcmdlKHRhcmdldCwgLi4uc291cmNlcyk7XG59XG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdHdvIGFycmF5cyBoYXZlIHRoZSBzYW1lIHZhbHVlIGZvciBlYWNoIG9mIHRoZSBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcEVxdWFscyhhcnJheUEsIGFycmF5Qikge1xuICAgIHJldHVybiBhcnJheUEubGVuZ3RoID09PSBhcnJheUIubGVuZ3RoICYmIGFycmF5QS5ldmVyeSgoZWxlbWVudCwgaW5kZXgpID0+IGFycmF5QltpbmRleF0gPT09IGVsZW1lbnQpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGFuIGFyZ3MgYXJyYXkgaW50byBhbiBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25zRnJvbUFyZ3VtZW50cyhkZWZhdWx0cywgYXJnc0FycmF5LCBrZXlzID0gW10sIG9iaktleSkge1xuICAgIGNvbnN0IG9wdHMgPSB7fTtcbiAgICBjb25zdCBhcmdzID0gQXJyYXkuZnJvbShhcmdzQXJyYXkpO1xuICAgIC8vIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhbiBvYmplY3QgYW5kIGhhcyBhbiBvYmplY3Qga2V5XG4gICAgaWYgKGlzT2JqZWN0KGFyZ3NbMF0pICYmIG9iaktleSAmJiAhUmVmbGVjdC5oYXMoYXJnc1swXSwgb2JqS2V5KSkge1xuICAgICAgICAvLyBpZiBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBkZWZhdWx0c1xuICAgICAgICBjb25zdCBwYXJ0T2ZEZWZhdWx0cyA9IE9iamVjdC5rZXlzKGFyZ3NbMF0pLnNvbWUoa2V5ID0+IFJlZmxlY3QuaGFzKGRlZmF1bHRzLCBrZXkpKTtcbiAgICAgICAgaWYgKCFwYXJ0T2ZEZWZhdWx0cykge1xuICAgICAgICAgICAgLy8gbWVyZ2UgdGhhdCBrZXlcbiAgICAgICAgICAgIGRlZXBNZXJnZShvcHRzLCB7IFtvYmpLZXldOiBhcmdzWzBdIH0pO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBvYmoga2V5IGZyb20gdGhlIGtleXNcbiAgICAgICAgICAgIGtleXMuc3BsaWNlKGtleXMuaW5kZXhPZihvYmpLZXkpLCAxKTtcbiAgICAgICAgICAgIC8vIHNoaWZ0IHRoZSBmaXJzdCBhcmd1bWVudCBvZmZcbiAgICAgICAgICAgIGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNPYmplY3QoYXJnc1swXSkpIHtcbiAgICAgICAgZGVlcE1lcmdlKG9wdHMsIGFyZ3NbMF0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKGFyZ3NbaV0pKSB7XG4gICAgICAgICAgICAgICAgb3B0c1trZXlzW2ldXSA9IGFyZ3NbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlZXBNZXJnZShkZWZhdWx0cywgb3B0cyk7XG59XG4vKipcbiAqIFJldHVybiB0aGlzIGluc3RhbmNlcyBkZWZhdWx0IHZhbHVlcyBieSBjYWxsaW5nIENvbnN0cnVjdG9yLmdldERlZmF1bHRzKClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRzRnJvbUluc3RhbmNlKGluc3RhbmNlKSB7XG4gICAgcmV0dXJuIGluc3RhbmNlLmNvbnN0cnVjdG9yLmdldERlZmF1bHRzKCk7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGZhbGxiYWNrIGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgdW5kZWZpbmVkLlxuICogVGFrZSBhbiBhcnJheSBvZiBhcmd1bWVudHMgYW5kIHJldHVybiBhIGZvcm1hdHRlZCBvcHRpb25zIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRBcmcoZ2l2ZW4sIGZhbGxiYWNrKSB7XG4gICAgaWYgKGlzVW5kZWYoZ2l2ZW4pKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBnaXZlbjtcbiAgICB9XG59XG4vKipcbiAqIFJlbW92ZSBhbGwgb2YgdGhlIHByb3BlcnRpZXMgYmVsb25naW5nIHRvIG9taXQgZnJvbSBvYmouXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbWl0RnJvbU9iamVjdChvYmosIG9taXQpIHtcbiAgICBvbWl0LmZvckVhY2gocHJvcCA9PiB7XG4gICAgICAgIGlmIChSZWZsZWN0LmhhcyhvYmosIHByb3ApKSB7XG4gICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BdO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG9iajtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlZmF1bHRzLmpzLm1hcCIsIi8qKlxuICogVG9uZS5qc1xuICogQGF1dGhvciBZb3RhbSBNYW5uXG4gKiBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiBAY29weXJpZ2h0IDIwMTQtMjAxOSBZb3RhbSBNYW5uXG4gKi9cbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tIFwiLi4vdmVyc2lvblwiO1xuaW1wb3J0IHsgdGhlV2luZG93IH0gZnJvbSBcIi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCIuL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQGNsYXNzICBUb25lIGlzIHRoZSBiYXNlIGNsYXNzIG9mIGFsbCBvdGhlciBjbGFzc2VzLlxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgY2xhc3MgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdERFQlVHR0lOR1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldCB0aGlzIGRlYnVnIGZsYWcgdG8gbG9nIGFsbCBldmVudHMgdGhhdCBoYXBwZW4gaW4gdGhpcyBjbGFzcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFx0RElTUE9TSU5HXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBpbnN0YW5jZSB3YXMgZGlzcG9zZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3dhc0Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYWxsIG9mIHRoZSBkZWZhdWx0IG9wdGlvbnMgYmVsb25naW5nIHRvIHRoZSBjbGFzcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJpbnRzIHRoZSBvdXRwdXRzIHRvIHRoZSBjb25zb2xlIGxvZyBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLlxuICAgICAqIFByaW50cyB0aGUgY29udGVudHMgb25seSBpZiBlaXRoZXIgdGhlIG9iamVjdCBoYXMgYSBwcm9wZXJ0eVxuICAgICAqIGNhbGxlZCBgZGVidWdgIHNldCB0byB0cnVlLCBvciBhIHZhcmlhYmxlIGNhbGxlZCBUT05FX0RFQlVHX0NMQVNTXG4gICAgICogaXMgc2V0IHRvIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiAvLyBwcmludHMgYWxsIGxvZ3Mgb3JpZ2luYXRpbmcgZnJvbSB0aGlzIG9zY2lsbGF0b3JcbiAgICAgKiBvc2MuZGVidWcgPSB0cnVlO1xuICAgICAqIC8vIGNhbGxzIHRvIHN0YXJ0L3N0b3Agd2lsbCBwcmludCBpbiB0aGUgY29uc29sZVxuICAgICAqIG9zYy5zdGFydCgpO1xuICAgICAqL1xuICAgIGxvZyguLi5hcmdzKSB7XG4gICAgICAgIC8vIGlmIHRoZSBvYmplY3QgaXMgZWl0aGVyIHNldCB0byBkZWJ1ZyA9IHRydWVcbiAgICAgICAgLy8gb3IgaWYgdGhlcmUgaXMgYSBzdHJpbmcgb24gdGhlIFRvbmUuZ2xvYmFsLndpdGggdGhlIGNsYXNzIG5hbWVcbiAgICAgICAgaWYgKHRoaXMuZGVidWcgfHwgKHRoZVdpbmRvdyAmJiB0aGlzLnRvU3RyaW5nKCkgPT09IHRoZVdpbmRvdy5UT05FX0RFQlVHX0NMQVNTKSkge1xuICAgICAgICAgICAgbG9nKHRoaXMsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGRpc2Nvbm5lY3QgYW5kIGRpc3Bvc2UuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5fd2FzRGlzcG9zZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIGlmIHRoZSBpbnN0YW5jZSB3YXMgZGlzcG9zZWQuICdEaXNwb3NpbmcnIGFuXG4gICAgICogaW5zdGFuY2UgbWVhbnMgdGhhdCBhbGwgb2YgdGhlIFdlYiBBdWRpbyBub2RlcyB0aGF0IHdlcmVcbiAgICAgKiBjcmVhdGVkIGZvciB0aGUgaW5zdGFuY2UgYXJlIGRpc2Nvbm5lY3RlZCBhbmQgZnJlZWQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgZGlzcG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93YXNEaXNwb3NlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgY2xhc3MgdG8gYSBzdHJpbmdcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvc2MudG9TdHJpbmcoKSk7XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgfVxufVxuLyoqXG4gKiBUaGUgdmVyc2lvbiBudW1iZXIgc2VtdmVyXG4gKi9cblRvbmUudmVyc2lvbiA9IHZlcnNpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lLmpzLm1hcCIsIi8qKlxuICogVGhlIHRocmVzaG9sZCBmb3IgY29ycmVjdG5lc3MgZm9yIG9wZXJhdG9ycy4gTGVzcyB0aGFuIG9uZSBzYW1wbGUgZXZlblxuICogYXQgdmVyeSBoaWdoIHNhbXBsaW5nIHJhdGVzIChlLmcuIGAxZS02IDwgMSAvIDE5MjAwMGApLlxuICovXG5jb25zdCBFUFNJTE9OID0gMWUtNjtcbi8qKlxuICogVGVzdCBpZiBBIGlzIGdyZWF0ZXIgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHVChhLCBiKSB7XG4gICAgcmV0dXJuIGEgPiBiICsgRVBTSUxPTjtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHVEUoYSwgYikge1xuICAgIHJldHVybiBHVChhLCBiKSB8fCBFUShhLCBiKTtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGxlc3MgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMVChhLCBiKSB7XG4gICAgcmV0dXJuIGEgKyBFUFNJTE9OIDwgYjtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGxlc3MgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFUShhLCBiKSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8IEVQU0lMT047XG59XG4vKipcbiAqIENsYW1wIHRoZSB2YWx1ZSB3aXRoaW4gdGhlIGdpdmVuIHJhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGFtcCh2YWx1ZSwgbWluLCBtYXgpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4odmFsdWUsIG1heCksIG1pbik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NYXRoLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4vRGVidWdcIjtcbmltcG9ydCB7IEVRLCBHVCwgR1RFLCBMVCB9IGZyb20gXCIuL01hdGhcIjtcbi8qKlxuICogQSBUaW1lbGluZSBjbGFzcyBmb3Igc2NoZWR1bGluZyBhbmQgbWFpbnRhaW5pbmcgc3RhdGVcbiAqIGFsb25nIGEgdGltZWxpbmUuIEFsbCBldmVudHMgbXVzdCBoYXZlIGEgXCJ0aW1lXCIgcHJvcGVydHkuXG4gKiBJbnRlcm5hbGx5LCBldmVudHMgYXJlIHN0b3JlZCBpbiB0aW1lIG9yZGVyIGZvciBmYXN0XG4gKiByZXRyaWV2YWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lbGluZSBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVsaW5lXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXJyYXkgb2Ygc2NoZWR1bGVkIHRpbWVsaW5lIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpbWVsaW5lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWVtb3J5XCJdKTtcbiAgICAgICAgdGhpcy5tZW1vcnkgPSBvcHRpb25zLm1lbW9yeTtcbiAgICAgICAgdGhpcy5pbmNyZWFzaW5nID0gb3B0aW9ucy5pbmNyZWFzaW5nO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtZW1vcnk6IEluZmluaXR5LFxuICAgICAgICAgICAgaW5jcmVhc2luZzogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc2VydCBhbiBldmVudCBvYmplY3Qgb250byB0aGUgdGltZWxpbmUuIEV2ZW50cyBtdXN0IGhhdmUgYSBcInRpbWVcIiBhdHRyaWJ1dGUuXG4gICAgICogQHBhcmFtIGV2ZW50ICBUaGUgZXZlbnQgb2JqZWN0IHRvIGluc2VydCBpbnRvIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBhZGQoZXZlbnQpIHtcbiAgICAgICAgLy8gdGhlIGV2ZW50IG5lZWRzIHRvIGhhdmUgYSB0aW1lIGF0dHJpYnV0ZVxuICAgICAgICBhc3NlcnQoUmVmbGVjdC5oYXMoZXZlbnQsIFwidGltZVwiKSwgXCJUaW1lbGluZTogZXZlbnRzIG11c3QgaGF2ZSBhIHRpbWUgYXR0cmlidXRlXCIpO1xuICAgICAgICBldmVudC50aW1lID0gZXZlbnQudGltZS52YWx1ZU9mKCk7XG4gICAgICAgIGlmICh0aGlzLmluY3JlYXNpbmcgJiYgdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RWYWx1ZSA9IHRoaXMuX3RpbWVsaW5lW3RoaXMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBhc3NlcnQoR1RFKGV2ZW50LnRpbWUsIGxhc3RWYWx1ZS50aW1lKSwgXCJUaGUgdGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbGFzdCBzY2hlZHVsZWQgdGltZVwiKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnB1c2goZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2goZXZlbnQudGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXggKyAxLCAwLCBldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBtb3JlIHRoYW4gdGhlIG1lbW9yeSwgcmVtb3ZlIHRoZSBwcmV2aW91cyBvbmVzXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCA+IHRoaXMubWVtb3J5KSB7XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gdGhpcy5sZW5ndGggLSB0aGlzLm1lbW9yeTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZSgwLCBkaWZmKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGZyb20gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIGV2ZW50ICBUaGUgZXZlbnQgb2JqZWN0IHRvIHJlbW92ZSBmcm9tIHRoZSBsaXN0LlxuICAgICAqIEByZXR1cm5zIHtUaW1lbGluZX0gdGhpc1xuICAgICAqL1xuICAgIHJlbW92ZShldmVudCkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3RpbWVsaW5lLmluZGV4T2YoZXZlbnQpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG5lYXJlc3QgZXZlbnQgd2hvc2UgdGltZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXQodGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lLCBwYXJhbSk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGV2ZW50IGluIHRoZSB0aW1lbGluZSB3aXRob3V0IHJlbW92aW5nIGl0XG4gICAgICogQHJldHVybnMge09iamVjdH0gVGhlIGZpcnN0IGV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVswXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgYW5kIHJlbW92ZSBpdFxuICAgICAqL1xuICAgIHNoaWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmUuc2hpZnQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBldmVudCB3aGljaCBpcyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRBZnRlcih0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUsIHBhcmFtKTtcbiAgICAgICAgaWYgKGluZGV4ICsgMSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4ICsgMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGV2ZW50IGJlZm9yZSB0aGUgZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRCZWZvcmUodGltZSkge1xuICAgICAgICBjb25zdCBsZW4gPSB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgICAgIC8vIGlmIGl0J3MgYWZ0ZXIgdGhlIGxhc3QgaXRlbSwgcmV0dXJuIHRoZSBsYXN0IGl0ZW1cbiAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV0udGltZSA8IHRpbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4IC0gMSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgYXQgYW5kIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLl9zZWFyY2goYWZ0ZXIpO1xuICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAoRVEodGhpcy5fdGltZWxpbmVbaW5kZXhdLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGZpcnN0IGl0ZW0gd2l0aCB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2ldLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZSgwLCBpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyB0aGUgZmlyc3QgaXRlbSdzIHRpbWVcbiAgICAgICAgICAgIGlmIChHVEUodGhpcy5fdGltZWxpbmVbMF0udGltZSwgYWZ0ZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGV2ZW50cyBiZWZvcmUgb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBjYW5jZWwgYmVmb3JlLlxuICAgICAqL1xuICAgIGNhbmNlbEJlZm9yZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZShpbmRleCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBldmVudCBpZiB0aGVyZSBpcyBvbmUuIG51bGwgb3RoZXJ3aXNlXG4gICAgICogQHBhcmFtICBldmVudCBUaGUgZXZlbnQgdG8gZmluZCB0aGUgcHJldmlvdXMgb25lIG9mXG4gICAgICogQHJldHVybiBUaGUgZXZlbnQgcmlnaHQgYmVmb3JlIHRoZSBnaXZlbiBldmVudFxuICAgICAqL1xuICAgIHByZXZpb3VzRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl90aW1lbGluZS5pbmRleE9mKGV2ZW50KTtcbiAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb2VzIGEgYmluYXJ5IHNlYXJjaCBvbiB0aGUgdGltZWxpbmUgYXJyYXkgYW5kIHJldHVybnMgdGhlXG4gICAgICogbmVhcmVzdCBldmVudCBpbmRleCB3aG9zZSB0aW1lIGlzIGFmdGVyIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIElmIGEgdGltZSBpcyBzZWFyY2hlZCBiZWZvcmUgdGhlIGZpcnN0IGluZGV4IGluIHRoZSB0aW1lbGluZSwgLTEgaXMgcmV0dXJuZWQuXG4gICAgICogSWYgdGhlIHRpbWUgaXMgYWZ0ZXIgdGhlIGVuZCwgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGl0ZW0gaXMgcmV0dXJuZWQuXG4gICAgICovXG4gICAgX3NlYXJjaCh0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYmVnaW5uaW5nID0gMDtcbiAgICAgICAgY29uc3QgbGVuID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgICAgICBsZXQgZW5kID0gbGVuO1xuICAgICAgICBpZiAobGVuID4gMCAmJiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXVtwYXJhbV0gPD0gdGltZSkge1xuICAgICAgICAgICAgcmV0dXJuIGxlbiAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGJlZ2lubmluZyA8IGVuZCkge1xuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBtaWRwb2ludCBmb3Igcm91Z2hseSBlcXVhbCBwYXJ0aXRpb25cbiAgICAgICAgICAgIGxldCBtaWRQb2ludCA9IE1hdGguZmxvb3IoYmVnaW5uaW5nICsgKGVuZCAtIGJlZ2lubmluZykgLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbbWlkUG9pbnRdO1xuICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fdGltZWxpbmVbbWlkUG9pbnQgKyAxXTtcbiAgICAgICAgICAgIGlmIChFUShldmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gY2hvb3NlIHRoZSBsYXN0IG9uZSB0aGF0IGhhcyB0aGUgc2FtZSB0aW1lXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IG1pZFBvaW50OyBpIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVzdEV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChFUSh0ZXN0RXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWlkUG9pbnQgPSBpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pZFBvaW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoTFQoZXZlbnRbcGFyYW1dLCB0aW1lKSAmJiBHVChuZXh0RXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKEdUKGV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBzZWFyY2ggbG93ZXJcbiAgICAgICAgICAgICAgICBlbmQgPSBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHNlYXJjaCB1cHBlclxuICAgICAgICAgICAgICAgIGJlZ2lubmluZyA9IG1pZFBvaW50ICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGl0ZXJhdG9yLiBBcHBsaWVzIGV4dHJhIHNhZmV0eSBjaGVja3MgZm9yXG4gICAgICogcmVtb3ZpbmcgaXRlbXMgZnJvbSB0aGUgYXJyYXkuXG4gICAgICovXG4gICAgX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgPSAwLCB1cHBlckJvdW5kID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5zbGljZShsb3dlckJvdW5kLCB1cHBlckJvdW5kICsgMSkuZm9yRWFjaChjYWxsYmFjayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IG9yIGJlZm9yZSB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQmVmb3JlKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgY29uc3QgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKHVwcGVyQm91bmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCAwLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBZnRlcih0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBiZXR3ZWVuIHRoZSBzdGFydFRpbWUgYW5kIGVuZFRpbWUuXG4gICAgICogVGhlIHRpbWVyYW5nZSBpcyBpbmNsdXNpdmUgb2YgdGhlIHN0YXJ0VGltZSwgYnV0IGV4Y2x1c2l2ZSBvZiB0aGUgZW5kVGltZS5cbiAgICAgKiByYW5nZSA9IFtzdGFydFRpbWUsIGVuZFRpbWUpLlxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGVuZFRpbWUgVGhlIGVuZCBvZiB0aGUgdGVzdCBpbnRlcnZhbC5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEJldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBjYWxsYmFjaykge1xuICAgICAgICBsZXQgbG93ZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChzdGFydFRpbWUpO1xuICAgICAgICBsZXQgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChlbmRUaW1lKTtcbiAgICAgICAgaWYgKGxvd2VyQm91bmQgIT09IC0xICYmIHVwcGVyQm91bmQgIT09IC0xKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fdGltZWxpbmVbbG93ZXJCb3VuZF0udGltZSAhPT0gc3RhcnRUaW1lKSB7XG4gICAgICAgICAgICAgICAgbG93ZXJCb3VuZCArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXhjbHVzaXZlIG9mIHRoZSBlbmQgdGltZVxuICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW3VwcGVyQm91bmRdLnRpbWUgPT09IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICB1cHBlckJvdW5kIC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChsb3dlckJvdW5kID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgMCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCBvciBhZnRlciB0aGUgZ2l2ZW4gdGltZS4gU2ltaWxhciB0b1xuICAgICAqIGZvckVhY2hBZnRlciwgYnV0IGluY2x1ZGVzIHRoZSBpdGVtKHMpIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hGcm9tKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIC8vIHdvcmsgYmFja3dhcmRzIHVudGlsIHRoZSBldmVudCB0aW1lIGlzIGxlc3MgdGhhbiB0aW1lXG4gICAgICAgIHdoaWxlIChsb3dlckJvdW5kID49IDAgJiYgdGhpcy5fdGltZWxpbmVbbG93ZXJCb3VuZF0udGltZSA+PSB0aW1lKSB7XG4gICAgICAgICAgICBsb3dlckJvdW5kLS07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEF0VGltZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmICh1cHBlckJvdW5kICE9PSAtMSAmJiBFUSh0aGlzLl90aW1lbGluZVt1cHBlckJvdW5kXS50aW1lLCB0aW1lKSkge1xuICAgICAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB1cHBlckJvdW5kO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHVwcGVyQm91bmQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2ldLnRpbWUsIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvd2VyQm91bmQgPSBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgfSwgbG93ZXJCb3VuZCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZWxpbmUuanMubWFwIiwiLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBJTklUSUFMSVpJTkcgTkVXIENPTlRFWFRcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBBcnJheSBvZiBjYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkXG4gKi9cbmNvbnN0IG5vdGlmeU5ld0NvbnRleHQgPSBbXTtcbi8qKlxuICogVXNlZCBpbnRlcm5hbGx5IHRvIHNldHVwIGEgbmV3IENvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ29udGV4dEluaXQoY2IpIHtcbiAgICBub3RpZnlOZXdDb250ZXh0LnB1c2goY2IpO1xufVxuLyoqXG4gKiBJbnZva2UgYW55IGNsYXNzZXMgd2hpY2ggbmVlZCB0byBhbHNvIGJlIGluaXRpYWxpemVkIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZUNvbnRleHQoY3R4KSB7XG4gICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICBub3RpZnlOZXdDb250ZXh0LmZvckVhY2goY2IgPT4gY2IoY3R4KSk7XG59XG4vKipcbiAqIEFycmF5IG9mIGNhbGxiYWNrcyB0byBpbnZva2Ugd2hlbiBhIG5ldyBjb250ZXh0IGlzIGNyZWF0ZWRcbiAqL1xuY29uc3Qgbm90aWZ5Q2xvc2VDb250ZXh0ID0gW107XG4vKipcbiAqIFVzZWQgaW50ZXJuYWxseSB0byB0ZWFyIGRvd24gYSBDb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkNvbnRleHRDbG9zZShjYikge1xuICAgIG5vdGlmeUNsb3NlQ29udGV4dC5wdXNoKGNiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZUNvbnRleHQoY3R4KSB7XG4gICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICBub3RpZnlDbG9zZUNvbnRleHQuZm9yRWFjaChjYiA9PiBjYihjdHgpKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnRleHRJbml0aWFsaXphdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzVW5kZWYgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogRW1pdHRlciBnaXZlcyBjbGFzc2VzIHdoaWNoIGV4dGVuZCBpdFxuICogdGhlIGFiaWxpdHkgdG8gbGlzdGVuIGZvciBhbmQgZW1pdCBldmVudHMuXG4gKiBJbnNwaXJhdGlvbiBhbmQgcmVmZXJlbmNlIGZyb20gSmVyb21lIEV0aWVubmUncyBbTWljcm9FdmVudF0oaHR0cHM6Ly9naXRodWIuY29tL2plcm9tZWV0aWVubmUvbWljcm9ldmVudC5qcykuXG4gKiBNSVQgKGMpIDIwMTEgSmVyb21lIEV0aWVubmUuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRW1pdHRlciBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVtaXR0ZXJcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGNhbGxiYWNrIHRvIGEgc3BlY2lmaWMgZXZlbnQuXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gICAgICovXG4gICAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIHNwbGl0IHRoZSBldmVudFxuICAgICAgICBjb25zdCBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuICAgICAgICBldmVudHMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fZXZlbnRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudE5hbWVdID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZlbnROYW1lXS5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgY2FsbGJhY2sgd2hpY2ggaXMgb25seSBpbnZva2VkIG9uY2VcbiAgICAgKiBAcGFyYW0gIGV2ZW50ICAgICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIGZvci5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWRcbiAgICAgKi9cbiAgICBvbmNlKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBjb25zdCBib3VuZENhbGxiYWNrID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBldmVudFxuICAgICAgICAgICAgdGhpcy5vZmYoZXZlbnQsIGJvdW5kQ2FsbGJhY2spO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9uKGV2ZW50LCBib3VuZENhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgZXZlbnQgbGlzdGVuZXIuXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIGV2ZW50IHRvIHN0b3AgbGlzdGVuaW5nIHRvLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB3aGljaCB3YXMgYm91bmQgdG8gdGhlIGV2ZW50IHdpdGggRW1pdHRlci5vbi5cbiAgICAgKiAgICAgICAgICAgICAgICAgICBJZiBubyBjYWxsYmFjayBpcyBnaXZlbiwgYWxsIGNhbGxiYWNrcyBldmVudHMgYXJlIHJlbW92ZWQuXG4gICAgICovXG4gICAgb2ZmKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBjb25zdCBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuICAgICAgICBldmVudHMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fZXZlbnRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNVbmRlZihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50XSA9IFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnRMaXN0ID0gdGhpcy5fZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGV2ZW50TGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50TGlzdFtpXSA9PT0gY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSBhbGwgb2YgdGhlIGNhbGxiYWNrcyBib3VuZCB0byB0aGUgZXZlbnRcbiAgICAgKiB3aXRoIGFueSBhcmd1bWVudHMgcGFzc2VkIGluLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cbiAgICAgKiBAcGFyYW0gYXJncyBUaGUgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGZ1bmN0aW9ucyBsaXN0ZW5pbmcuXG4gICAgICovXG4gICAgZW1pdChldmVudCwgLi4uYXJncykge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF0uc2xpY2UoMCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGV2ZW50TGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBldmVudExpc3RbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgRW1pdHRlciBmdW5jdGlvbnMgKG9uL29mZi9lbWl0KSB0byB0aGUgb2JqZWN0XG4gICAgICovXG4gICAgc3RhdGljIG1peGluKGNvbnN0cikge1xuICAgICAgICAvLyBpbnN0YW5jZS5fZXZlbnRzID0ge307XG4gICAgICAgIFtcIm9uXCIsIFwib25jZVwiLCBcIm9mZlwiLCBcImVtaXRcIl0uZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihFbWl0dGVyLnByb3RvdHlwZSwgbmFtZSk7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RyLnByb3RvdHlwZSwgbmFtZSwgcHJvcGVydHkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RW1pdHRlci5qcy5tYXAiLCJpbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuZXhwb3J0IGNsYXNzIEJhc2VDb250ZXh0IGV4dGVuZHMgRW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgfVxuICAgIC8qXG4gICAgICogVGhpcyBpcyBhIHBsYWNlaG9sZGVyIHNvIHRoYXQgSlNPTi5zdHJpbmdpZnkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3JcbiAgICAgKiBUaGlzIG1hdGNoZXMgd2hhdCBKU09OLnN0cmluZ2lmeShhdWRpb0NvbnRleHQpIHJldHVybnMgb24gYSBuYXRpdmVcbiAgICAgKiBhdWRpb0NvbnRleHQgaW5zdGFuY2UuXG4gICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QmFzZUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUaWNrZXIgfSBmcm9tIFwiLi4vY2xvY2svVGlja2VyXCI7XG5pbXBvcnQgeyBpc0F1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0NvbnRleHQsIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUsIH0gZnJvbSBcIi4vQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBjbG9zZUNvbnRleHQsIGluaXRpYWxpemVDb250ZXh0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG5pbXBvcnQgeyBCYXNlQ29udGV4dCB9IGZyb20gXCIuL0Jhc2VDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250ZXh0IGV4dGVuZHMgQmFzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbnRleHRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBvZiB0aGUgY29uc3RhbnRzIEF1ZGlvQnVmZmVyU291cmNlTm9kZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnN0YW50cyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgc2V0VGltZW91dCBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lb3V0cyA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVvdXQgaWQgY291bnRlclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dElkcyA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIGluZGljYXRvciBpZiB0aGUgY29udGV4dCBoYXMgYmVlbiBpbml0aWFsaXplZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgY29udGV4dCBpcyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IG9yIGFuIEF1ZGlvQ29udGV4dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc09mZmxpbmUgPSBmYWxzZTtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBBVURJTyBXT1JLTEVUXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1hcHMgYSBtb2R1bGUgbmFtZSB0byBwcm9taXNlIG9mIHRoZSBhZGRNb2R1bGUgbWV0aG9kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbnRleHQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXG4gICAgICAgICAgICBcImNvbnRleHRcIixcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChvcHRpb25zLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHQgPSBvcHRpb25zLmNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY3JlYXRlQXVkaW9Db250ZXh0KHtcbiAgICAgICAgICAgICAgICBsYXRlbmN5SGludDogb3B0aW9ucy5sYXRlbmN5SGludCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RpY2tlciA9IG5ldyBUaWNrZXIodGhpcy5lbWl0LmJpbmQodGhpcywgXCJ0aWNrXCIpLCBvcHRpb25zLmNsb2NrU291cmNlLCBvcHRpb25zLnVwZGF0ZUludGVydmFsKTtcbiAgICAgICAgdGhpcy5vbihcInRpY2tcIiwgdGhpcy5fdGltZW91dExvb3AuYmluZCh0aGlzKSk7XG4gICAgICAgIC8vIGZ3ZCBldmVudHMgZnJvbSB0aGUgY29udGV4dFxuICAgICAgICB0aGlzLl9jb250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGF0ZWNoYW5nZVwiLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fc2V0TGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCk7XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gb3B0aW9ucy5sb29rQWhlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNsb2NrU291cmNlOiBcIndvcmtlclwiLFxuICAgICAgICAgICAgbGF0ZW5jeUhpbnQ6IFwiaW50ZXJhY3RpdmVcIixcbiAgICAgICAgICAgIGxvb2tBaGVhZDogMC4xLFxuICAgICAgICAgICAgdXBkYXRlSW50ZXJ2YWw6IDAuMDUsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBzZXR0aW5nIHVwIHRoZSBjb250ZXh0LiAqKllvdSB1c3VhbGx5IGRvIG5vdCBuZWVkIHRvIGRvIHRoaXMgbWFudWFsbHkuKipcbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAvLyBhZGQgYW55IGFkZGl0aW9uYWwgbW9kdWxlc1xuICAgICAgICAgICAgaW5pdGlhbGl6ZUNvbnRleHQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQkFTRSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgIH1cbiAgICBjcmVhdGVPc2NpbGxhdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxNZXJnZXIobnVtYmVyT2ZJbnB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ2hhbm5lbE1lcmdlcihudW1iZXJPZklucHV0cyk7XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cyk7XG4gICAgfVxuICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgIH1cbiAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgIH1cbiAgICBjcmVhdGVEZWxheShtYXhEZWxheVRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lKTtcbiAgICB9XG4gICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKTtcbiAgICB9XG4gICAgY3JlYXRlR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIH1cbiAgICBjcmVhdGVJSVJGaWx0ZXIoZmVlZEZvcndhcmQsIGZlZWRiYWNrKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlSUlSRmlsdGVyKGZlZWRGb3J3YXJkLCBmZWVkYmFjayk7XG4gICAgfVxuICAgIGNyZWF0ZVBhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnLCBjb25zdHJhaW50cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMpO1xuICAgIH1cbiAgICBjcmVhdGVTdGVyZW9QYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgIH1cbiAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnQoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCksIFwiTm90IGF2YWlsYWJsZSBpZiBPZmZsaW5lQXVkaW9Db250ZXh0XCIpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKGVsZW1lbnQpIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShlbGVtZW50KTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKTtcbiAgICB9XG4gICAgZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0ZW5lclxuICAgICAqL1xuICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9saXN0ZW5lcjtcbiAgICB9XG4gICAgc2V0IGxpc3RlbmVyKGwpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgbGlzdGVuZXIgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyID0gbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlcmUgaXMgb25seSBvbmUgVHJhbnNwb3J0IHBlciBDb250ZXh0LiBJdCBpcyBjcmVhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuICAgICAqL1xuICAgIGdldCB0cmFuc3BvcnQoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0O1xuICAgIH1cbiAgICBzZXQgdHJhbnNwb3J0KHQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgdHJhbnNwb3J0IGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnQgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIHRoZSBEcmF3IG9iamVjdCBmb3IgdGhlIGNvbnRleHQgd2hpY2ggaXMgdXNlZnVsIGZvciBzeW5jaHJvbml6aW5nIHRoZSBkcmF3IGZyYW1lIHdpdGggdGhlIFRvbmUuanMgY2xvY2suXG4gICAgICovXG4gICAgZ2V0IGRyYXcoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZHJhdztcbiAgICB9XG4gICAgc2V0IGRyYXcoZCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIkRyYXcgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2RyYXcgPSBkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgQ29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICovXG4gICAgZ2V0IGRlc3RpbmF0aW9uKCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3RpbmF0aW9uO1xuICAgIH1cbiAgICBzZXQgZGVzdGluYXRpb24oZCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIlRoZSBkZXN0aW5hdGlvbiBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fZGVzdGluYXRpb24gPSBkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gYXVkaW8gd29ya2xldCBub2RlIGZyb20gYSBuYW1lIGFuZCBvcHRpb25zLiBUaGUgbW9kdWxlXG4gICAgICogbXVzdCBmaXJzdCBiZSBsb2FkZWQgdXNpbmcgW1thZGRBdWRpb1dvcmtsZXRNb2R1bGVdXS5cbiAgICAgKi9cbiAgICBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKG5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUodGhpcy5yYXdDb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIEF1ZGlvV29ya2xldFByb2Nlc3NvciBtb2R1bGVcbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIG1vZHVsZVxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGVcbiAgICAgKi9cbiAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUodXJsLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKHRoaXMucmF3Q29udGV4dC5hdWRpb1dvcmtsZXQpLCBcIkF1ZGlvV29ya2xldE5vZGUgaXMgb25seSBhdmFpbGFibGUgaW4gYSBzZWN1cmUgY29udGV4dCAoaHR0cHMgb3IgbG9jYWxob3N0KVwiKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd29ya2xldE1vZHVsZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMuc2V0KG5hbWUsIHRoaXMucmF3Q29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeWllbGQgdGhpcy5fd29ya2xldE1vZHVsZXMuZ2V0KG5hbWUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIHdvcmtsZXRzIGhhdmUgYmVlbiBsb2FkZWQgb24gdGhpcyBjb250ZXh0XG4gICAgICovXG4gICAgd29ya2xldHNBcmVSZWFkeSgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcy5mb3JFYWNoKChwcm9taXNlKSA9PiBwcm9taXNlcy5wdXNoKHByb21pc2UpKTtcbiAgICAgICAgICAgIHlpZWxkIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVElDS0VSXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBIb3cgb2Z0ZW4gdGhlIGludGVydmFsIGNhbGxiYWNrIGlzIGludm9rZWQuXG4gICAgICogVGhpcyBudW1iZXIgY29ycmVzcG9uZHMgdG8gaG93IHJlc3BvbnNpdmUgdGhlIHNjaGVkdWxpbmdcbiAgICAgKiBjYW4gYmUuIGNvbnRleHQudXBkYXRlSW50ZXJ2YWwgKyBjb250ZXh0Lmxvb2tBaGVhZCBnaXZlcyB5b3UgdGhlXG4gICAgICogdG90YWwgbGF0ZW5jeSBiZXR3ZWVuIHNjaGVkdWxpbmcgYW4gZXZlbnQgYW5kIGhlYXJpbmcgaXQuXG4gICAgICovXG4gICAgZ2V0IHVwZGF0ZUludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsO1xuICAgIH1cbiAgICBzZXQgdXBkYXRlSW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsID0gaW50ZXJ2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoYXQgdGhlIHNvdXJjZSBvZiB0aGUgY2xvY2sgaXMsIGVpdGhlciBcIndvcmtlclwiIChkZWZhdWx0KSxcbiAgICAgKiBcInRpbWVvdXRcIiwgb3IgXCJvZmZsaW5lXCIgKG5vbmUpLlxuICAgICAqL1xuICAgIGdldCBjbG9ja1NvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tlci50eXBlO1xuICAgIH1cbiAgICBzZXQgY2xvY2tTb3VyY2UodHlwZSkge1xuICAgICAgICB0aGlzLl90aWNrZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHBsYXliYWNrLCB3aGljaCBhZmZlY3RzIHRyYWRlb2ZmcyBiZXR3ZWVuIGF1ZGlvXG4gICAgICogb3V0cHV0IGxhdGVuY3kgYW5kIHJlc3BvbnNpdmVuZXNzLlxuICAgICAqIEluIGFkZGl0aW9uIHRvIHNldHRpbmcgdGhlIHZhbHVlIGluIHNlY29uZHMsIHRoZSBsYXRlbmN5SGludCBhbHNvXG4gICAgICogYWNjZXB0cyB0aGUgc3RyaW5ncyBcImludGVyYWN0aXZlXCIgKHByaW9yaXRpemVzIGxvdyBsYXRlbmN5KSxcbiAgICAgKiBcInBsYXliYWNrXCIgKHByaW9yaXRpemVzIHN1c3RhaW5lZCBwbGF5YmFjayksIFwiYmFsYW5jZWRcIiAoYmFsYW5jZXNcbiAgICAgKiBsYXRlbmN5IGFuZCBwZXJmb3JtYW5jZSkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBwcmlvcml0aXplIHN1c3RhaW5lZCBwbGF5YmFja1xuICAgICAqIGNvbnN0IGNvbnRleHQgPSBuZXcgVG9uZS5Db250ZXh0KHsgbGF0ZW5jeUhpbnQ6IFwicGxheWJhY2tcIiB9KTtcbiAgICAgKiAvLyBzZXQgdGhpcyBjb250ZXh0IGFzIHRoZSBnbG9iYWwgQ29udGV4dFxuICAgICAqIFRvbmUuc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgKiAvLyB0aGUgZ2xvYmFsIGNvbnRleHQgaXMgZ2V0dGFibGUgd2l0aCBUb25lLmdldENvbnRleHQoKVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuZ2V0Q29udGV4dCgpLmxhdGVuY3lIaW50KTtcbiAgICAgKi9cbiAgICBnZXQgbGF0ZW5jeUhpbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXRlbmN5SGludDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBsb29rQWhlYWQgYW5kIHVwZGF0ZUludGVydmFsIGJhc2VkIG9uIHRoZSBsYXRlbmN5SGludFxuICAgICAqL1xuICAgIF9zZXRMYXRlbmN5SGludChoaW50KSB7XG4gICAgICAgIGxldCBsb29rQWhlYWRWYWx1ZSA9IDA7XG4gICAgICAgIHRoaXMuX2xhdGVuY3lIaW50ID0gaGludDtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGhpbnQpKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGhpbnQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiaW50ZXJhY3RpdmVcIjpcbiAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkVmFsdWUgPSAwLjE7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwbGF5YmFja1wiOlxuICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWRWYWx1ZSA9IDAuNTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImJhbGFuY2VkXCI6XG4gICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZFZhbHVlID0gMC4yNTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb29rQWhlYWQgPSBsb29rQWhlYWRWYWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVJbnRlcnZhbCA9IGxvb2tBaGVhZFZhbHVlIC8gMjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHVud3JhcHBlZCBBdWRpb0NvbnRleHQgb3IgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICAgICAqL1xuICAgIGdldCByYXdDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIHBsdXMgYSBzaG9ydCBbW2xvb2tBaGVhZF1dLlxuICAgICAqL1xuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWUgKyB0aGlzLmxvb2tBaGVhZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIHdpdGhvdXQgdGhlIFtbbG9va0FoZWFkXV0uXG4gICAgICogSW4gbW9zdCBjYXNlcyBpdCBpcyBiZXR0ZXIgdG8gdXNlIFtbbm93XV0gaW5zdGVhZCBvZiBbW2ltbWVkaWF0ZV1dIHNpbmNlXG4gICAgICogd2l0aCBbW25vd11dIHRoZSBbW2xvb2tBaGVhZF1dIGlzIGFwcGxpZWQgZXF1YWxseSB0byBfYWxsXyBjb21wb25lbnRzIGluY2x1ZGluZyBpbnRlcm5hbCBjb21wb25lbnRzLFxuICAgICAqIHRvIG1ha2luZyBzdXJlIHRoYXQgZXZlcnl0aGluZyBpcyBzY2hlZHVsZWQgaW4gc3luYy4gTWl4aW5nIFtbbm93XV0gYW5kIFtbaW1tZWRpYXRlXV1cbiAgICAgKiBjYW4gY2F1c2Ugc29tZSB0aW1pbmcgaXNzdWVzLiBJZiBubyBsb29rQWhlYWQgaXMgZGVzaXJlZCwgeW91IGNhbiBzZXQgdGhlIFtbbG9va0FoZWFkXV0gdG8gYDBgLlxuICAgICAqL1xuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgYXVkaW8gY29udGV4dCBmcm9tIGEgc3VzcGVuZGVkIHN0YXRlLiBUaGlzIGlzIHJlcXVpcmVkXG4gICAgICogdG8gaW5pdGlhbGx5IHN0YXJ0IHRoZSBBdWRpb0NvbnRleHQuIFNlZSBbW1RvbmUuc3RhcnRdXVxuICAgICAqL1xuICAgIHJlc3VtZSgpIHtcbiAgICAgICAgaWYgKGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5yZXN1bWUoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgY29udGV4dC4gT25jZSBjbG9zZWQsIHRoZSBjb250ZXh0IGNhbiBubyBsb25nZXIgYmUgdXNlZCBhbmRcbiAgICAgKiBhbnkgQXVkaW9Ob2RlcyBjcmVhdGVkIGZyb20gdGhlIGNvbnRleHQgd2lsbCBiZSBzaWxlbnQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCB0aGlzLl9jb250ZXh0LmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICBjbG9zZUNvbnRleHQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqKkludGVybmFsKiogR2VuZXJhdGUgYSBsb29wZWQgYnVmZmVyIGF0IHNvbWUgY29uc3RhbnQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0Q29uc3RhbnQodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLl9jb25zdGFudHMuaGFzKHZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb25zdGFudHMuZ2V0KHZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxMjgsIHRoaXMuX2NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBhcnIgPSBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGFycltpXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50ID0gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgICAgIGNvbnN0YW50LmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgICAgICBjb25zdGFudC5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICAgICAgY29uc3RhbnQuYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICAgICAgY29uc3RhbnQubG9vcCA9IHRydWU7XG4gICAgICAgICAgICBjb25zdGFudC5zdGFydCgwKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50cy5zZXQodmFsLCBjb25zdGFudCk7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RhbnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuIEFsc28gY2xvc2VzIHRoZSBhdWRpbyBjb250ZXh0LlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGlja2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGltZW91dHMuZGlzcG9zZSgpO1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLl9jb25zdGFudHMpLm1hcCgodmFsKSA9PiB0aGlzLl9jb25zdGFudHNbdmFsXS5kaXNjb25uZWN0KCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUSU1FT1VUU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVGhlIHByaXZhdGUgbG9vcCB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgY29udGV4dCBzY2hlZHVsZWQgdGltZW91dHNcbiAgICAgKiBJcyBpbnZva2VkIGZyb20gdGhlIGNsb2NrIHNvdXJjZVxuICAgICAqL1xuICAgIF90aW1lb3V0TG9vcCgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgbGV0IGZpcnN0RXZlbnQgPSB0aGlzLl90aW1lb3V0cy5wZWVrKCk7XG4gICAgICAgIHdoaWxlICh0aGlzLl90aW1lb3V0cy5sZW5ndGggJiYgZmlyc3RFdmVudCAmJiBmaXJzdEV2ZW50LnRpbWUgPD0gbm93KSB7XG4gICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICBmaXJzdEV2ZW50LmNhbGxiYWNrKCk7XG4gICAgICAgICAgICAvLyBzaGlmdCB0aGUgZmlyc3QgZXZlbnQgb2ZmXG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5zaGlmdCgpO1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBuZXh0IG9uZVxuICAgICAgICAgICAgZmlyc3RFdmVudCA9IHRoaXMuX3RpbWVvdXRzLnBlZWsoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHNldFRpbWVvdXQgd2hpY2ggaXMgZ3VhcmFudGVlZCBieSB0aGUgY2xvY2sgc291cmNlLlxuICAgICAqIEFsc28gcnVucyBpbiB0aGUgb2ZmbGluZSBjb250ZXh0LlxuICAgICAqIEBwYXJhbSAgZm4gICAgICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZVxuICAgICAqIEBwYXJhbSAgdGltZW91dCAgVGhlIHRpbWVvdXQgaW4gc2Vjb25kc1xuICAgICAqIEByZXR1cm5zIElEIHRvIHVzZSB3aGVuIGludm9raW5nIENvbnRleHQuY2xlYXJUaW1lb3V0XG4gICAgICovXG4gICAgc2V0VGltZW91dChmbiwgdGltZW91dCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0SWRzKys7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRzLmFkZCh7XG4gICAgICAgICAgICBjYWxsYmFjazogZm4sXG4gICAgICAgICAgICBpZDogdGhpcy5fdGltZW91dElkcyxcbiAgICAgICAgICAgIHRpbWU6IG5vdyArIHRpbWVvdXQsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZW91dElkcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGEgcHJldmlvdXNseSBzY2hlZHVsZWQgdGltZW91dCB3aXRoIFRvbmUuY29udGV4dC5zZXRUaW1lb3V0XG4gICAgICogQHBhcmFtICBpZCAgVGhlIElEIHJldHVybmVkIGZyb20gc2V0VGltZW91dFxuICAgICAqL1xuICAgIGNsZWFyVGltZW91dChpZCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0cy5mb3JFYWNoKChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmlkID09PSBpZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVvdXRzLnJlbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXIgdGhlIGZ1bmN0aW9uIHNjaGVkdWxlZCBieSBbW3NldEludGVydmFsXV1cbiAgICAgKi9cbiAgICBjbGVhckludGVydmFsKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsZWFyVGltZW91dChpZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgYSByZXBlYXRpbmcgZXZlbnQgdG8gdGhlIGNvbnRleHQncyBjYWxsYmFjayBjbG9ja1xuICAgICAqL1xuICAgIHNldEludGVydmFsKGZuLCBpbnRlcnZhbCkge1xuICAgICAgICBjb25zdCBpZCA9ICsrdGhpcy5fdGltZW91dElkcztcbiAgICAgICAgY29uc3QgaW50ZXJ2YWxGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5hZGQoe1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBldmVudCB0byByZXBlYXQgaXRcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWxGbigpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgdGltZTogbm93ICsgaW50ZXJ2YWwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8ga2ljayBpdCBvZmZcbiAgICAgICAgaW50ZXJ2YWxGbigpO1xuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEJhc2VDb250ZXh0IH0gZnJvbSBcIi4vQmFzZUNvbnRleHRcIjtcbmV4cG9ydCBjbGFzcyBEdW1teUNvbnRleHQgZXh0ZW5kcyBCYXNlQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gMDtcbiAgICAgICAgdGhpcy5sYXRlbmN5SGludCA9IDA7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQkFTRSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU9zY2lsbGF0b3IoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXIoX251bWJlck9mQ2hhbm5lbHMsIF9sZW5ndGgsIF9zYW1wbGVSYXRlKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbE1lcmdlcihfbnVtYmVyT2ZJbnB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsU3BsaXR0ZXIoX251bWJlck9mT3V0cHV0cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNvbnZvbHZlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVEZWxheShfbWF4RGVsYXlUaW1lKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlSUlSRmlsdGVyKF9mZWVkRm9yd2FyZCwgX2ZlZWRiYWNrKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlUGFubmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShfcmVhbCwgX2ltYWcsIF9jb25zdHJhaW50cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVN0ZXJlb1Bhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKF9zdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UoX2VsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGRlY29kZUF1ZGlvRGF0YShfYXVkaW9EYXRhKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFRPTkUgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKF9uYW1lLCBfb3B0aW9ucykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCByYXdDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZShfdXJsLCBfbmFtZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVzdW1lKCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHNldFRpbWVvdXQoX2ZuLCBfdGltZW91dCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgY2xlYXJUaW1lb3V0KF9pZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0SW50ZXJ2YWwoX2ZuLCBfaW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoX2lkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRDb25zdGFudChfdmFsKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCB0cmFuc3BvcnQoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IGRyYXcoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgc2V0IGRyYXcoX2QpIHsgfVxuICAgIGdldCBkZXN0aW5hdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBzZXQgZGVzdGluYXRpb24oX2QpIHsgfVxuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RHVtbXlDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IGlzQXJyYXkgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogTWFrZSB0aGUgcHJvcGVydHkgbm90IHdyaXRhYmxlIHVzaW5nIGBkZWZpbmVQcm9wZXJ0eWAuIEludGVybmFsIHVzZSBvbmx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZE9ubHkodGFyZ2V0LCBwcm9wZXJ0eSkge1xuICAgIGlmIChpc0FycmF5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm9wZXJ0eS5mb3JFYWNoKHN0ciA9PiByZWFkT25seSh0YXJnZXQsIHN0cikpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBhbiBhdHRyaWJ1dGUgd3JpdGVhYmxlLiBJbnRlcm5hbCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRhYmxlKHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICBpZiAoaXNBcnJheShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvcGVydHkuZm9yRWFjaChzdHIgPT4gd3JpdGFibGUodGFyZ2V0LCBzdHIpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7XG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuZXhwb3J0IGNvbnN0IG5vT3AgPSAoKSA9PiB7XG4gICAgLy8gbm8gb3BlcmF0aW9uIGhlcmUhXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW50ZXJmYWNlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc051bWJlciwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEF1ZGlvQnVmZmVyIGxvYWRpbmcgYW5kIHN0b3JhZ2UuIFRvbmVBdWRpb0J1ZmZlciBpcyB1c2VkIGludGVybmFsbHkgYnkgYWxsXG4gKiBjbGFzc2VzIHRoYXQgbWFrZSByZXF1ZXN0cyBmb3IgYXVkaW8gZmlsZXMgc3VjaCBhcyBUb25lLlBsYXllcixcbiAqIFRvbmUuU2FtcGxlciBhbmQgVG9uZS5Db252b2x2ZXIuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgYnVmZmVyID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0ExLm1wM1wiLCAoKSA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKFwibG9hZGVkXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUF1ZGlvQnVmZmVyIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvQnVmZmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbmxvYWQgPSBub09wO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUF1ZGlvQnVmZmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCIsIFwib25lcnJvclwiXSk7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9IG9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgdGhpcy5vbmxvYWQgPSBvcHRpb25zLm9ubG9hZDtcbiAgICAgICAgaWYgKG9wdGlvbnMudXJsICYmIGlzQXVkaW9CdWZmZXIob3B0aW9ucy51cmwpIHx8IG9wdGlvbnMudXJsIGluc3RhbmNlb2YgVG9uZUF1ZGlvQnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLnNldChvcHRpb25zLnVybCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcob3B0aW9ucy51cmwpKSB7XG4gICAgICAgICAgICAvLyBpbml0aWF0ZSB0aGUgZG93bmxvYWRcbiAgICAgICAgICAgIHRoaXMubG9hZChvcHRpb25zLnVybCkuY2F0Y2gob3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzYW1wbGUgcmF0ZSBvZiB0aGUgQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbnRleHQoKS5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhc3MgaW4gYW4gQXVkaW9CdWZmZXIgb3IgVG9uZUF1ZGlvQnVmZmVyIHRvIHNldCB0aGUgdmFsdWUgb2YgdGhpcyBidWZmZXIuXG4gICAgICovXG4gICAgc2V0KGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyIGluc3RhbmNlb2YgVG9uZUF1ZGlvQnVmZmVyKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIGxvYWRlZCwgc2V0IGl0XG4gICAgICAgICAgICBpZiAoYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlci5nZXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB3aGVuIGl0J3MgbG9hZGVkLCBpbnZva2UgaXQncyBjYWxsYmFja1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0KGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25sb2FkKHRoaXMpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmV2ZXJzZSBpdCBpbml0aWFsbHlcbiAgICAgICAgaWYgKHRoaXMuX3JldmVyc2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgc3RvcmVkIGluIHRoZSBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhbiBmZXRjaCByZXF1ZXN0IGZvciB0aGUgc2VsZWN0ZWQgdXJsIHRoZW4gZGVjb2RlcyB0aGUgZmlsZSBhcyBhbiBhdWRpbyBidWZmZXIuXG4gICAgICogSW52b2tlcyB0aGUgY2FsbGJhY2sgb25jZSB0aGUgYXVkaW8gYnVmZmVyIGxvYWRzLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuIGZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGUgYnJvd3Nlci5cbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2l0aCB0aGlzIFRvbmVBdWRpb0J1ZmZlclxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBkb25lTG9hZGluZyA9IFRvbmVBdWRpb0J1ZmZlci5sb2FkKHVybCkudGhlbihhdWRpb0J1ZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgb25sb2FkIG1ldGhvZFxuICAgICAgICAgICAgICAgIHRoaXMub25sb2FkKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLnB1c2goZG9uZUxvYWRpbmcpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB5aWVsZCBkb25lTG9hZGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgZG93bmxvYWRlZCBmaWxlXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLmluZGV4T2YoZG9uZUxvYWRpbmcpO1xuICAgICAgICAgICAgICAgIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXVkaW8gYnVmZmVyIGZyb20gdGhlIGFycmF5LlxuICAgICAqIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlciwgcGFzcyBpbiBhIG11bHRpZGltZW5zaW9uYWwgYXJyYXkuXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBmaWxsIHRoZSBhdWRpbyBidWZmZXJcbiAgICAgKi9cbiAgICBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgY29uc3QgaXNNdWx0aWRpbWVuc2lvbmFsID0gaXNBcnJheShhcnJheSkgJiYgYXJyYXlbMF0ubGVuZ3RoID4gMDtcbiAgICAgICAgY29uc3QgY2hhbm5lbHMgPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheS5sZW5ndGggOiAxO1xuICAgICAgICBjb25zdCBsZW4gPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheVswXS5sZW5ndGggOiBhcnJheS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlQnVmZmVyKGNoYW5uZWxzLCBsZW4sIGNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IG11bHRpQ2hhbm5lbEFycmF5ID0gIWlzTXVsdGlkaW1lbnNpb25hbCAmJiBjaGFubmVscyA9PT0gMSA/XG4gICAgICAgICAgICBbYXJyYXldIDogYXJyYXk7XG4gICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY2hhbm5lbHM7IGMrKykge1xuICAgICAgICAgICAgYnVmZmVyLmNvcHlUb0NoYW5uZWwobXVsdGlDaGFubmVsQXJyYXlbY10sIGMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1bXMgbXVsdGlwbGUgY2hhbm5lbHMgaW50byAxIGNoYW5uZWxcbiAgICAgKiBAcGFyYW0gY2hhbk51bSBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIHRvTW9ubyhjaGFuTnVtKSB7XG4gICAgICAgIGlmIChpc051bWJlcihjaGFuTnVtKSkge1xuICAgICAgICAgICAgdGhpcy5mcm9tQXJyYXkodGhpcy50b0FycmF5KGNoYW5OdW0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBvdXRwdXRBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgbnVtQ2hhbm5lbHMgPSB0aGlzLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IG51bUNoYW5uZWxzOyBjaGFubmVsKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsQXJyYXkgPSB0aGlzLnRvQXJyYXkoY2hhbm5lbCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0QXJyYXlbaV0gKz0gY2hhbm5lbEFycmF5W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGRpdmlkZSBieSB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzXG4gICAgICAgICAgICBvdXRwdXRBcnJheSA9IG91dHB1dEFycmF5Lm1hcChzYW1wbGUgPT4gc2FtcGxlIC8gbnVtQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5mcm9tQXJyYXkob3V0cHV0QXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ1ZmZlciBhcyBhbiBhcnJheS4gU2luZ2xlIGNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBhIDEtZGltZW5zaW9uYWxcbiAgICAgKiBGbG9hdDMyQXJyYXksIGFuZCBtdWx0aWNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBtdWx0aWRpbWVuc2lvbmFsIGFycmF5cy5cbiAgICAgKiBAcGFyYW0gY2hhbm5lbCBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIHRvQXJyYXkoY2hhbm5lbCkge1xuICAgICAgICBpZiAoaXNOdW1iZXIoY2hhbm5lbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubnVtYmVyT2ZDaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9BcnJheSgwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGMrKykge1xuICAgICAgICAgICAgICAgIHJldFtjXSA9IHRoaXMuZ2V0Q2hhbm5lbERhdGEoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEZsb2F0MzJBcnJheSByZXByZXNlbnRpbmcgdGhlIFBDTSBhdWRpbyBkYXRhIGZvciB0aGUgc3BlY2lmaWMgY2hhbm5lbC5cbiAgICAgKiBAcGFyYW0gIGNoYW5uZWwgIFRoZSBjaGFubmVsIG51bWJlciB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBhdWRpbyBhcyBhIFR5cGVkQXJyYXlcbiAgICAgKi9cbiAgICBnZXRDaGFubmVsRGF0YShjaGFubmVsKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheSgwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDdXQgYSBzdWJzZWN0aW9uIG9mIHRoZSBhcnJheSBhbmQgcmV0dXJuIGEgYnVmZmVyIG9mIHRoZVxuICAgICAqIHN1YnNlY3Rpb24uIERvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYnVmZmVyXG4gICAgICogQHBhcmFtIHN0YXJ0IFRoZSB0aW1lIHRvIHN0YXJ0IHRoZSBzbGljZVxuICAgICAqIEBwYXJhbSBlbmQgVGhlIGVuZCB0aW1lIHRvIHNsaWNlLiBJZiBub25lIGlzIGdpdmVuIHdpbGwgZGVmYXVsdCB0byB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgICAgKi9cbiAgICBzbGljZShzdGFydCwgZW5kID0gdGhpcy5kdXJhdGlvbikge1xuICAgICAgICBjb25zdCBzdGFydFNhbXBsZXMgPSBNYXRoLmZsb29yKHN0YXJ0ICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgZW5kU2FtcGxlcyA9IE1hdGguZmxvb3IoZW5kICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgYXNzZXJ0KHN0YXJ0U2FtcGxlcyA8IGVuZFNhbXBsZXMsIFwiVGhlIHN0YXJ0IHRpbWUgbXVzdCBiZSBsZXNzIHRoYW4gdGhlIGVuZCB0aW1lXCIpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBlbmRTYW1wbGVzIC0gc3RhcnRTYW1wbGVzO1xuICAgICAgICBjb25zdCByZXRCdWZmZXIgPSBnZXRDb250ZXh0KCkuY3JlYXRlQnVmZmVyKHRoaXMubnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICByZXRCdWZmZXIuY29weVRvQ2hhbm5lbCh0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpLnN1YmFycmF5KHN0YXJ0U2FtcGxlcywgZW5kU2FtcGxlcyksIGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKHJldEJ1ZmZlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldmVyc2UgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBfcmV2ZXJzZSgpIHtcbiAgICAgICAgaWYgKHRoaXMubG9hZGVkKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRDaGFubmVsRGF0YShpKS5yZXZlcnNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgaXMgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgZ2V0IGR1cmF0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyIGluIHNhbXBsZXNcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGlzY3JldGUgYXVkaW8gY2hhbm5lbHMuIFJldHVybnMgMCBpZiBubyBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGdldCBudW1iZXJPZkNoYW5uZWxzKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgZ2V0IHJldmVyc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXZlcnNlZDtcbiAgICB9XG4gICAgc2V0IHJldmVyc2UocmV2KSB7XG4gICAgICAgIGlmICh0aGlzLl9yZXZlcnNlZCAhPT0gcmV2KSB7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlZCA9IHJldjtcbiAgICAgICAgICAgIHRoaXMuX3JldmVyc2UoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBUb25lQXVkaW9CdWZmZXIgZnJvbSB0aGUgYXJyYXkuIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlcixcbiAgICAgKiBwYXNzIGluIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS5cbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwgdGhlIGF1ZGlvIGJ1ZmZlclxuICAgICAqIEByZXR1cm4gQSBUb25lQXVkaW9CdWZmZXIgY3JlYXRlZCBmcm9tIHRoZSBhcnJheVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIChuZXcgVG9uZUF1ZGlvQnVmZmVyKCkpLmZyb21BcnJheShhcnJheSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUb25lQXVkaW9CdWZmZXIgZnJvbSBhIFVSTCwgcmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lQXVkaW9CdWZmZXJcbiAgICAgKiBAcGFyYW0gIHVybCBUaGUgdXJsIHRvIGxvYWQuXG4gICAgICogQHJldHVybiBBIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbVVybCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKTtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBidWZmZXIubG9hZCh1cmwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9hZHMgYSB1cmwgdXNpbmcgZmV0Y2ggYW5kIHJldHVybnMgdGhlIEF1ZGlvQnVmZmVyLlxuICAgICAqL1xuICAgIHN0YXRpYyBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgLy8gdGVzdCBpZiB0aGUgdXJsIGNvbnRhaW5zIG11bHRpcGxlIGV4dGVuc2lvbnNcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSB1cmwubWF0Y2goL1xcWyhbXlxcXVxcW10rXFx8LispXFxdJC8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25zID0gbWF0Y2hlc1sxXS5zcGxpdChcInxcIik7XG4gICAgICAgICAgICAgICAgbGV0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbMF07XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBleHQgb2YgZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoVG9uZUF1ZGlvQnVmZmVyLnN1cHBvcnRzVHlwZShleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24gPSBleHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShtYXRjaGVzWzBdLCBleHRlbnNpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZXJlIGlzIGEgc2xhc2ggYmV0d2VlbiB0aGUgYmFzZVVybCBhbmQgdGhlIHVybFxuICAgICAgICAgICAgY29uc3QgYmFzZVVybCA9IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsID09PSBcIlwiIHx8IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsLmVuZHNXaXRoKFwiL1wiKSA/IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsIDogVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgKyBcIi9cIjtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0geWllbGQgZmV0Y2goYmFzZVVybCArIHVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb3VsZCBub3QgbG9hZCB1cmw6ICR7dXJsfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSB5aWVsZCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSB5aWVsZCBnZXRDb250ZXh0KCkuZGVjb2RlQXVkaW9EYXRhKGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBhIHVybCdzIGV4dGVuc2lvbiB0byBzZWUgaWYgdGhlIGN1cnJlbnQgYnJvd3NlciBjYW4gcGxheSB0aGF0IGZpbGUgdHlwZS5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwvZXh0ZW5zaW9uIHRvIHRlc3RcbiAgICAgKiBAcmV0dXJuIElmIHRoZSBmaWxlIGV4dGVuc2lvbiBjYW4gYmUgcGxheWVkXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5Ub25lQXVkaW9CdWZmZXIuc3VwcG9ydHNUeXBlKFwid2F2XCIpOyAvLyByZXR1cm5zIHRydWVcbiAgICAgKiBUb25lLlRvbmVBdWRpb0J1ZmZlci5zdXBwb3J0c1R5cGUoXCJwYXRoL3RvL2ZpbGUud2F2XCIpOyAvLyByZXR1cm5zIHRydWVcbiAgICAgKi9cbiAgICBzdGF0aWMgc3VwcG9ydHNUeXBlKHVybCkge1xuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gdXJsLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1tleHRlbnNpb25zLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhdWRpb1wiKS5jYW5QbGF5VHlwZShcImF1ZGlvL1wiICsgZXh0ZW5zaW9uKTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlICE9PSBcIlwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgUHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIGFsbCBvZiB0aGUgYnVmZmVycyBoYXZlIGxvYWRlZFxuICAgICAqL1xuICAgIHN0YXRpYyBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAvLyB0aGlzIG1ha2VzIHN1cmUgdGhhdCB0aGUgZnVuY3Rpb24gaXMgYWx3YXlzIGFzeW5jXG4gICAgICAgICAgICB5aWVsZCBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIHdoaWxlIChUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHlpZWxkIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU1RBVElDIE1FVEhPRFNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBBIHBhdGggd2hpY2ggaXMgcHJlZml4ZWQgYmVmb3JlIGV2ZXJ5IHVybC5cbiAqL1xuVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgPSBcIlwiO1xuLyoqXG4gKiBBbGwgb2YgdGhlIGRvd25sb2Fkc1xuICovXG5Ub25lQXVkaW9CdWZmZXIuZG93bmxvYWRzID0gW107XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9CdWZmZXIuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dFwiO1xuaW1wb3J0IHsgaXNPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBleGFtcGxlXG4gKiAvLyBnZW5lcmF0ZSBhIHNpbmdsZSBjaGFubmVsLCAwLjUgc2Vjb25kIGJ1ZmZlclxuICogY29uc3QgY29udGV4dCA9IG5ldyBUb25lLk9mZmxpbmVDb250ZXh0KDEsIDAuNSwgNDQxMDApO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcih7IGNvbnRleHQgfSk7XG4gKiBjb250ZXh0LnJlbmRlcigpLnRoZW4oYnVmZmVyID0+IHtcbiAqIFx0Y29uc29sZS5sb2coYnVmZmVyLm51bWJlck9mQ2hhbm5lbHMsIGJ1ZmZlci5kdXJhdGlvbik7XG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIE9mZmxpbmVDb250ZXh0IGV4dGVuZHMgQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIGNsb2NrU291cmNlOiBcIm9mZmxpbmVcIixcbiAgICAgICAgICAgIGNvbnRleHQ6IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgICAgICBhcmd1bWVudHNbMF0gOiBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdICogYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbMl0pLFxuICAgICAgICAgICAgbG9va0FoZWFkOiAwLFxuICAgICAgICAgICAgdXBkYXRlSW50ZXJ2YWw6IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgICAgICAxMjggLyBhcmd1bWVudHNbMF0uc2FtcGxlUmF0ZSA6IDEyOCAvIGFyZ3VtZW50c1syXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT2ZmbGluZUNvbnRleHRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFuIGFydGlmaWNpYWwgY2xvY2sgc291cmNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jdXJyZW50VGltZSA9IDA7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZHVyYXRpb24gPSBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICBhcmd1bWVudHNbMF0ubGVuZ3RoIC8gYXJndW1lbnRzWzBdLnNhbXBsZVJhdGUgOiBhcmd1bWVudHNbMV07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIHRoZSBub3cgbWV0aG9kIHRvIHBvaW50IHRvIHRoZSBpbnRlcm5hbCBjbG9jayB0aW1lXG4gICAgICovXG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNhbWUgYXMgdGhpcy5ub3coKVxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIganVzdCB0aGUgY2xvY2sgcG9ydGlvbiBvZiB0aGUgYXVkaW8gY29udGV4dC5cbiAgICAgKi9cbiAgICBfcmVuZGVyQ2xvY2soYXN5bmNocm9ub3VzKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICAgICAgd2hpbGUgKHRoaXMuX2R1cmF0aW9uIC0gdGhpcy5fY3VycmVudFRpbWUgPj0gMCkge1xuICAgICAgICAgICAgICAgIC8vIGludm9rZSBhbGwgdGhlIGNhbGxiYWNrcyBvbiB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJ0aWNrXCIpO1xuICAgICAgICAgICAgICAgIC8vIGluY3JlbWVudCB0aGUgY2xvY2sgaW4gYmxvY2stc2l6ZWQgY2h1bmtzXG4gICAgICAgICAgICAgICAgdGhpcy5fY3VycmVudFRpbWUgKz0gMTI4IC8gdGhpcy5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgIC8vIHlpZWxkIG9uY2UgYSBzZWNvbmQgb2YgYXVkaW9cbiAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgICAgIGNvbnN0IHlpZWxkRXZlcnkgPSBNYXRoLmZsb29yKHRoaXMuc2FtcGxlUmF0ZSAvIDEyOCk7XG4gICAgICAgICAgICAgICAgaWYgKGFzeW5jaHJvbm91cyAmJiBpbmRleCAlIHlpZWxkRXZlcnkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgbmV3IFByb21pc2UoZG9uZSA9PiBzZXRUaW1lb3V0KGRvbmUsIDEpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgdGhlIG91dHB1dCBvZiB0aGUgT2ZmbGluZUNvbnRleHRcbiAgICAgKiBAcGFyYW0gYXN5bmNocm9ub3VzIElmIHRoZSBjbG9jayBzaG91bGQgYmUgcmVuZGVyZWQgYXN5bmNocm9ub3VzbHksIHdoaWNoIHdpbGwgbm90IGJsb2NrIHRoZSBtYWluIHRocmVhZCwgYnV0IGJlIHNsaWdodGx5IHNsb3dlci5cbiAgICAgKi9cbiAgICByZW5kZXIoYXN5bmNocm9ub3VzID0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgeWllbGQgdGhpcy53b3JrbGV0c0FyZVJlYWR5KCk7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl9yZW5kZXJDbG9jayhhc3luY2hyb25vdXMpO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgdGhpcy5fY29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBUb25lQXVkaW9CdWZmZXIoYnVmZmVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBjb250ZXh0XG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PZmZsaW5lQ29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4uL3ZlcnNpb25cIjtcbmltcG9ydCB7IGhhc0F1ZGlvQ29udGV4dCwgdGhlV2luZG93IH0gZnJvbSBcIi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L0NvbnRleHRcIjtcbmltcG9ydCB7IER1bW15Q29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvRHVtbXlDb250ZXh0XCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IGlzQXVkaW9Db250ZXh0LCBpc09mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRoaXMgZHVtbXkgY29udGV4dCBpcyB1c2VkIHRvIGF2b2lkIHRocm93aW5nIGltbWVkaWF0ZSBlcnJvcnMgd2hlbiBpbXBvcnRpbmcgaW4gTm9kZS5qc1xuICovXG5jb25zdCBkdW1teUNvbnRleHQgPSBuZXcgRHVtbXlDb250ZXh0KCk7XG4vKipcbiAqIFRoZSBnbG9iYWwgYXVkaW8gY29udGV4dCB3aGljaCBpcyBnZXRhYmxlIGFuZCBhc3NpZ25hYmxlIHRocm91Z2hcbiAqIGdldENvbnRleHQgYW5kIHNldENvbnRleHRcbiAqL1xubGV0IGdsb2JhbENvbnRleHQgPSBkdW1teUNvbnRleHQ7XG4vKipcbiAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3lzdGVtLXdpZGUgW1tDb250ZXh0XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250ZXh0KCkge1xuICAgIGlmIChnbG9iYWxDb250ZXh0ID09PSBkdW1teUNvbnRleHQgJiYgaGFzQXVkaW9Db250ZXh0KSB7XG4gICAgICAgIHNldENvbnRleHQobmV3IENvbnRleHQoKSk7XG4gICAgfVxuICAgIHJldHVybiBnbG9iYWxDb250ZXh0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgYXVkaW8gY29udGV4dFxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldENvbnRleHQoY29udGV4dCkge1xuICAgIGlmIChpc0F1ZGlvQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gbmV3IENvbnRleHQoY29udGV4dCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzT2ZmbGluZUF1ZGlvQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KGNvbnRleHQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxufVxuLyoqXG4gKiBNb3N0IGJyb3dzZXJzIHdpbGwgbm90IHBsYXkgX2FueV8gYXVkaW8gdW50aWwgYSB1c2VyXG4gKiBjbGlja3Mgc29tZXRoaW5nIChsaWtlIGEgcGxheSBidXR0b24pLiBJbnZva2UgdGhpcyBtZXRob2RcbiAqIG9uIGEgY2xpY2sgb3Iga2V5cHJlc3MgZXZlbnQgaGFuZGxlciB0byBzdGFydCB0aGUgYXVkaW8gY29udGV4dC5cbiAqIE1vcmUgYWJvdXQgdGhlIEF1dG9wbGF5IHBvbGljeVxuICogW2hlcmVdKGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3dlYi91cGRhdGVzLzIwMTcvMDkvYXV0b3BsYXktcG9saWN5LWNoYW5nZXMjd2ViYXVkaW8pXG4gKiBAZXhhbXBsZVxuICogZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJ1dHRvblwiKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYXN5bmMgKCkgPT4ge1xuICogXHRhd2FpdCBUb25lLnN0YXJ0KCk7XG4gKiBcdGNvbnNvbGUubG9nKFwiY29udGV4dCBzdGFydGVkXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgcmV0dXJuIGdsb2JhbENvbnRleHQucmVzdW1lKCk7XG59XG4vKipcbiAqIExvZyBUb25lLmpzICsgdmVyc2lvbiBpbiB0aGUgY29uc29sZS5cbiAqL1xuaWYgKHRoZVdpbmRvdyAmJiAhdGhlV2luZG93LlRPTkVfU0lMRU5DRV9MT0dHSU5HKSB7XG4gICAgbGV0IHByZWZpeCA9IFwidlwiO1xuICAgIGlmICh2ZXJzaW9uID09PSBcImRldlwiKSB7XG4gICAgICAgIHByZWZpeCA9IFwiXCI7XG4gICAgfVxuICAgIGNvbnN0IHByaW50U3RyaW5nID0gYCAqIFRvbmUuanMgJHtwcmVmaXh9JHt2ZXJzaW9ufSAqIGA7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJWMke3ByaW50U3RyaW5nfWAsIFwiYmFja2dyb3VuZDogIzAwMDsgY29sb3I6ICNmZmZcIik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HbG9iYWwuanMubWFwIiwiLyoqXG4gKiBFcXVhbCBwb3dlciBnYWluIHNjYWxlLiBHb29kIGZvciBjcm9zcy1mYWRpbmcuXG4gKiBAcGFyYW0gIHBlcmNlbnQgKDAtMSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsUG93ZXJTY2FsZShwZXJjZW50KSB7XG4gICAgY29uc3QgcGlGYWN0b3IgPSAwLjUgKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbihwZXJjZW50ICogcGlGYWN0b3IpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGRlY2liZWxzIGludG8gZ2Fpbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRiVG9HYWluKGRiKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCBkYiAvIDIwKTtcbn1cbi8qKlxuICogQ29udmVydCBnYWluIHRvIGRlY2liZWxzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2FpblRvRGIoZ2Fpbikge1xuICAgIHJldHVybiAyMCAqIChNYXRoLmxvZyhnYWluKSAvIE1hdGguTE4xMCk7XG59XG4vKipcbiAqIENvbnZlcnQgYW4gaW50ZXJ2YWwgKGluIHNlbWl0b25lcykgdG8gYSBmcmVxdWVuY3kgcmF0aW8uXG4gKiBAcGFyYW0gaW50ZXJ2YWwgdGhlIG51bWJlciBvZiBzZW1pdG9uZXMgYWJvdmUgdGhlIGJhc2Ugbm90ZVxuICogQGV4YW1wbGVcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKDApOyAvLyAxXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygxMik7IC8vIDJcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKC0xMik7IC8vIDAuNVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDIsIChpbnRlcnZhbCAvIDEyKSk7XG59XG4vKipcbiAqIFRoZSBHbG9iYWwgW2NvbmNlcnQgdHVuaW5nIHBpdGNoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25jZXJ0X3BpdGNoKSB3aGljaCBpcyB1c2VkXG4gKiB0byBnZW5lcmF0ZSBhbGwgdGhlIG90aGVyIHBpdGNoIHZhbHVlcyBmcm9tIG5vdGVzLiBBNCdzIHZhbHVlcyBpbiBIZXJ0ei5cbiAqL1xubGV0IEE0ID0gNDQwO1xuZXhwb3J0IGZ1bmN0aW9uIGdldEE0KCkge1xuICAgIHJldHVybiBBNDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXRBNChmcmVxKSB7XG4gICAgQTQgPSBmcmVxO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgZnJlcXVlbmN5IHZhbHVlIHRvIGEgTUlESSBub3RlLlxuICogQHBhcmFtIGZyZXF1ZW5jeSBUaGUgdmFsdWUgdG8gZnJlcXVlbmN5IHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAZXhhbXBsZVxuICogVG9uZS5mdG9tKDQ0MCk7IC8vIHJldHVybnMgNjlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZ0b20oZnJlcXVlbmN5KSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoZnRvbWYoZnJlcXVlbmN5KSk7XG59XG4vKipcbiAqIENvbnZlcnQgYSBmcmVxdWVuY3kgdG8gYSBmbG9hdGluZyBwb2ludCBtaWRpIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdG9tZihmcmVxdWVuY3kpIHtcbiAgICByZXR1cm4gNjkgKyAxMiAqIE1hdGgubG9nMihmcmVxdWVuY3kgLyBBNCk7XG59XG4vKipcbiAqIENvbnZlcnQgYSBNSURJIG5vdGUgdG8gZnJlcXVlbmN5IHZhbHVlLlxuICogQHBhcmFtICBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuICogQHJldHVybiBUaGUgY29ycmVzcG9uZGluZyBmcmVxdWVuY3kgdmFsdWVcbiAqIEBleGFtcGxlXG4gKiBUb25lLm10b2YoNjkpOyAvLyA0NDBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG10b2YobWlkaSkge1xuICAgIHJldHVybiBBNCAqIE1hdGgucG93KDIsIChtaWRpIC0gNjkpIC8gMTIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udmVyc2lvbnMuanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1N0cmluZywgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBUaW1lQmFzZSBpcyBhIGZsZXhpYmxlIGVuY29kaW5nIG9mIHRpbWUgd2hpY2ggY2FuIGJlIGV2YWx1YXRlZCB0byBhbmQgZnJvbSBhIHN0cmluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVCYXNlQ2xhc3MgZXh0ZW5kcyBUb25lIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIHRpbWUgdmFsdWUuIFVzZWQgdG8gY29tcHV0ZVxuICAgICAqIFRyYW5zcG9ydCBhbmQgY29udGV4dC1yZWxhdGl2ZSB0aW1pbmcuXG4gICAgICogQHBhcmFtICB2YWx1ZSAgVGhlIHRpbWUgdmFsdWUgYXMgYSBudW1iZXIsIHN0cmluZyBvciBvYmplY3RcbiAgICAgKiBAcGFyYW0gIHVuaXRzICBVbml0IHZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIHZhbHVlLCB1bml0cykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRlZmF1bHQgdW5pdHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJzXCI7XG4gICAgICAgIHRoaXMuX3ZhbCA9IHZhbHVlO1xuICAgICAgICB0aGlzLl91bml0cyA9IHVuaXRzO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0aGlzLl9leHByZXNzaW9ucyA9IHRoaXMuX2dldEV4cHJlc3Npb25zKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFsbCBvZiB0aGUgdGltZSBlbmNvZGluZyBleHByZXNzaW9uc1xuICAgICAqL1xuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGh6OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeVRvVW5pdHMocGFyc2VGbG9hdCh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KWh6JC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGk6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGlja3NUb1VuaXRzKHBhcnNlSW50KHZhbHVlLCAxMCkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKWkkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbToge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VJbnQodmFsdWUsIDEwKSAqIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspbSQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUsIGRvdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2FsYXIgPSBkb3QgPT09IFwiLlwiID8gMS41IDogMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bWVyaWNWYWx1ZSA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpICogc2NhbGFyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg0IC8gbnVtZXJpY1ZhbHVlKSAqIHNjYWxhcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKW4oXFwuPykkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuZGVmYXVsdFVuaXRzXS5tZXRob2QuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pJC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgczoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zZWNvbmRzVG9Vbml0cyhwYXJzZUZsb2F0KHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pcyQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNhbXBsZXM6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUsIDEwKSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKXNhbXBsZXMkLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg4IC8gKE1hdGguZmxvb3IobnVtZXJpY1ZhbHVlKSAqIDMpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyl0JC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAobSwgcSwgcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChxICYmIHEgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHMpIC8gNCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KTooXFxkKyg/OlxcLlxcZCspPyk6PyhcXGQrKD86XFwuXFxkKyk/KT8kLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VkFMVUUgT0ZcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBFdmFsdWF0ZSB0aGUgdGltZSB2YWx1ZS4gUmV0dXJucyB0aGUgdGltZSBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIHZhbHVlT2YoKSB7XG4gICAgICAgIGlmICh0aGlzLl92YWwgaW5zdGFuY2VvZiBUaW1lQmFzZUNsYXNzKSB7XG4gICAgICAgICAgICB0aGlzLmZyb21UeXBlKHRoaXMuX3ZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fdmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25vQXJnKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcodGhpcy5fdmFsKSAmJiBpc1VuZGVmKHRoaXMuX3VuaXRzKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCB1bml0cyBpbiB0aGlzLl9leHByZXNzaW9ucykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9leHByZXNzaW9uc1t1bml0c10ucmVnZXhwLnRlc3QodGhpcy5fdmFsLnRyaW0oKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHR5cGVOYW1lIGluIHRoaXMuX3ZhbCkge1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fdmFsW3R5cGVOYW1lXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSB0aGlzLl92YWxbdHlwZU5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWUgPSAobmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5jb250ZXh0LCB0eXBlTmFtZSkpLnZhbHVlT2YoKSAqIHF1YW50aXR5O1xuICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX3VuaXRzKSkge1xuICAgICAgICAgICAgY29uc3QgZXhwciA9IHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuX3VuaXRzXTtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoaW5nID0gdGhpcy5fdmFsLnRvU3RyaW5nKCkudHJpbSgpLm1hdGNoKGV4cHIucmVnZXhwKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBleHByLm1ldGhvZC5hcHBseSh0aGlzLCBtYXRjaGluZy5zbGljZSgxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwci5tZXRob2QuY2FsbCh0aGlzLCB0aGlzLl92YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHRoaXMuX3ZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VU5JVCBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gMSAvIGZyZXE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gKDYwIC8gdGhpcy5fZ2V0QnBtKCkpICogYmVhdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIHNlY29uZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gKHRpY2tzICogKHRoaXMuX2JlYXRzVG9Vbml0cygxKSkgLyB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdpdGggbm8gYXJndW1lbnRzLCByZXR1cm4gJ25vdydcbiAgICAgKi9cbiAgICBfbm9BcmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ub3coKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRURU1QTyBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgYnBtXG4gICAgICovXG4gICAgX2dldEJwbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuYnBtLnZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWVTaWduYXR1cmVcbiAgICAgKi9cbiAgICBfZ2V0VGltZVNpZ25hdHVyZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQudGltZVNpZ25hdHVyZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBQUFEgb3IgMTkyIGlmIFRyYW5zcG9ydCBpcyBub3QgYXZhaWxhYmxlXG4gICAgICovXG4gICAgX2dldFBQUSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuUFBRO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdENPTlZFUlNJT04gSU5URVJGQUNFXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQ29lcmNlIGEgdGltZSB0eXBlIGludG8gdGhpcyB1bml0cyB0eXBlLlxuICAgICAqIEBwYXJhbSB0eXBlIEFueSB0aW1lIHR5cGUgdW5pdHNcbiAgICAgKi9cbiAgICBmcm9tVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3VuaXRzID0gdW5kZWZpbmVkO1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZGVmYXVsdFVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlIFwic1wiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiaVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9UaWNrcygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImh6XCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b0ZyZXF1ZW5jeSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm1pZGlcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvTWlkaSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIGluIGhlcnR6XG4gICAgICovXG4gICAgdG9GcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiAxIC8gdGhpcy50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNhbXBsZXNcbiAgICAgKi9cbiAgICB0b1NhbXBsZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMuXG4gICAgICovXG4gICAgdG9NaWxsaXNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogMTAwMDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lQmFzZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgZnRvbSB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBUaW1lQmFzZUNsYXNzIH0gZnJvbSBcIi4vVGltZUJhc2VcIjtcbi8qKlxuICogVGltZUNsYXNzIGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIFRpbWVDbGFzcyBjYW4gYmUgcGFzc2VkIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAcGFyYW0gIHZhbCAgICBUaGUgdGltZSB2YWx1ZS5cbiAqIEBwYXJhbSAgdW5pdHMgIFRoZSB1bml0cyBvZiB0aGUgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdGltZSA9IFRvbmUuVGltZShcIjRuXCIpOyAvLyBhIHF1YXJ0ZXIgbm90ZVxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVDbGFzcyBleHRlbmRzIFRpbWVCYXNlQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVDbGFzc1wiO1xuICAgIH1cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHN1cGVyLl9nZXRFeHByZXNzaW9ucygpLCB7XG4gICAgICAgICAgICBub3c6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6IChjYXB0dXJlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub3coKSArIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgY2FwdHVyZSkudmFsdWVPZigpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXlxcKyguKykvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHF1YW50aXplOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAoY2FwdHVyZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudFRvID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGNhcHR1cmUpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NlY29uZHNUb1VuaXRzKHRoaXMuY29udGV4dC50cmFuc3BvcnQubmV4dFN1YmRpdmlzaW9uKHF1YW50VG8pKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL15AKC4rKS8sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUXVhbnRpemUgdGhlIHRpbWUgYnkgdGhlIGdpdmVuIHN1YmRpdmlzaW9uLiBPcHRpb25hbGx5IGFkZCBhXG4gICAgICogcGVyY2VudGFnZSB3aGljaCB3aWxsIG1vdmUgdGhlIHRpbWUgdmFsdWUgdG93YXJkcyB0aGUgaWRlYWxcbiAgICAgKiBxdWFudGl6ZWQgdmFsdWUgYnkgdGhhdCBwZXJjZW50YWdlLlxuICAgICAqIEBwYXJhbSAgc3ViZGl2ICAgIFRoZSBzdWJkaXZpc2lvbiB0byBxdWFudGl6ZSB0b1xuICAgICAqIEBwYXJhbSAgcGVyY2VudCAgTW92ZSB0aGUgdGltZSB2YWx1ZSB0b3dhcmRzIHRoZSBxdWFudGl6ZWQgdmFsdWUgYnkgYSBwZXJjZW50YWdlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UaW1lKDIxKS5xdWFudGl6ZSgyKTsgLy8gcmV0dXJucyAyMlxuICAgICAqIFRvbmUuVGltZSgwLjYpLnF1YW50aXplKFwiNG5cIiwgMC41KTsgLy8gcmV0dXJucyAwLjU1XG4gICAgICovXG4gICAgcXVhbnRpemUoc3ViZGl2LCBwZXJjZW50ID0gMSkge1xuICAgICAgICBjb25zdCBzdWJkaXZpc2lvbiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgc3ViZGl2KS52YWx1ZU9mKCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWx1ZU9mKCk7XG4gICAgICAgIGNvbnN0IG11bHRpcGxlID0gTWF0aC5yb3VuZCh2YWx1ZSAvIHN1YmRpdmlzaW9uKTtcbiAgICAgICAgY29uc3QgaWRlYWwgPSBtdWx0aXBsZSAqIHN1YmRpdmlzaW9uO1xuICAgICAgICBjb25zdCBkaWZmID0gaWRlYWwgLSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgZGlmZiAqIHBlcmNlbnQ7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIFRpbWUgdG8gTm90YXRpb24uIFRoZSBub3RhdGlvbiB2YWx1ZXMgYXJlIHdpbGwgYmUgdGhlXG4gICAgICogY2xvc2VzdCByZXByZXNlbnRhdGlvbiBiZXR3ZWVuIDFtIHRvIDEyOHRoIG5vdGUuXG4gICAgICogQHJldHVybiB7Tm90YXRpb259XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBpZiB0aGUgVHJhbnNwb3J0IGlzIGF0IDEyMGJwbTpcbiAgICAgKiBUb25lLlRpbWUoMikudG9Ob3RhdGlvbigpOyAvLyByZXR1cm5zIFwiMW1cIlxuICAgICAqL1xuICAgIHRvTm90YXRpb24oKSB7XG4gICAgICAgIGNvbnN0IHRpbWUgPSB0aGlzLnRvU2Vjb25kcygpO1xuICAgICAgICBjb25zdCB0ZXN0Tm90YXRpb25zID0gW1wiMW1cIl07XG4gICAgICAgIGZvciAobGV0IHBvd2VyID0gMTsgcG93ZXIgPCA5OyBwb3dlcisrKSB7XG4gICAgICAgICAgICBjb25zdCBzdWJkaXYgPSBNYXRoLnBvdygyLCBwb3dlcik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJuLlwiKTtcbiAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyBcIm5cIik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJ0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChcIjBcIik7XG4gICAgICAgIC8vIGZpbmQgdGhlIGNsb3NldHMgbm90YXRpb24gcmVwcmVzZW50YXRpb25cbiAgICAgICAgbGV0IGNsb3Nlc3QgPSB0ZXN0Tm90YXRpb25zWzBdO1xuICAgICAgICBsZXQgY2xvc2VzdFNlY29uZHMgPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGVzdE5vdGF0aW9uc1swXSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHRlc3ROb3RhdGlvbnMuZm9yRWFjaChub3RhdGlvbiA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3RhdGlvblNlY29uZHMgPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgbm90YXRpb24pLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKG5vdGF0aW9uU2Vjb25kcyAtIHRpbWUpIDwgTWF0aC5hYnMoY2xvc2VzdFNlY29uZHMgLSB0aW1lKSkge1xuICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBub3RhdGlvbjtcbiAgICAgICAgICAgICAgICBjbG9zZXN0U2Vjb25kcyA9IG5vdGF0aW9uU2Vjb25kcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbG9zZXN0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgZW5jb2RlZCBhcyBCYXJzOkJlYXRzOlNpeHRlZW50aHMuXG4gICAgICovXG4gICAgdG9CYXJzQmVhdHNTaXh0ZWVudGhzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgbGV0IHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcbiAgICAgICAgcXVhcnRlcnMgPSBwYXJzZUZsb2F0KHF1YXJ0ZXJzLnRvRml4ZWQoNCkpO1xuICAgICAgICBjb25zdCBtZWFzdXJlcyA9IE1hdGguZmxvb3IocXVhcnRlcnMgLyB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpO1xuICAgICAgICBsZXQgc2l4dGVlbnRocyA9IChxdWFydGVycyAlIDEpICogNDtcbiAgICAgICAgcXVhcnRlcnMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzKSAlIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKTtcbiAgICAgICAgY29uc3Qgc2l4dGVlbnRoU3RyaW5nID0gc2l4dGVlbnRocy50b1N0cmluZygpO1xuICAgICAgICBpZiAoc2l4dGVlbnRoU3RyaW5nLmxlbmd0aCA+IDMpIHtcbiAgICAgICAgICAgIC8vIHRoZSBhZGRpdGlvbmFsIHBhcnNlRmxvYXQgcmVtb3ZlcyBpbnNpZ25pZmljYW50IHRyYWlsaW5nIHplcm9lc1xuICAgICAgICAgICAgc2l4dGVlbnRocyA9IHBhcnNlRmxvYXQocGFyc2VGbG9hdChzaXh0ZWVudGhTdHJpbmcpLnRvRml4ZWQoMykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb2dyZXNzID0gW21lYXN1cmVzLCBxdWFydGVycywgc2l4dGVlbnRoc107XG4gICAgICAgIHJldHVybiBwcm9ncmVzcy5qb2luKFwiOlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHRpY2tzLlxuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBjb25zdCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHF1YXJ0ZXJzICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBhcyBhIG1pZGkgbm90ZS5cbiAgICAgKi9cbiAgICB0b01pZGkoKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHRoaXMudG9GcmVxdWVuY3koKSk7XG4gICAgfVxuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQubm93KCk7XG4gICAgfVxufVxuLyoqXG4gKiBDcmVhdGUgYSBUaW1lQ2xhc3MgZnJvbSBhIHRpbWUgc3RyaW5nIG9yIG51bWJlci4gVGhlIHRpbWUgaXMgY29tcHV0ZWQgYWdhaW5zdCB0aGVcbiAqIGdsb2JhbCBUb25lLkNvbnRleHQuIFRvIHVzZSBhIHNwZWNpZmljIGNvbnRleHQsIHVzZSBbW1RpbWVDbGFzc11dXG4gKiBAcGFyYW0gdmFsdWUgQSB2YWx1ZSB3aGljaCByZXByZXNlbnRzIHRpbWVcbiAqIEBwYXJhbSB1bml0cyBUaGUgdmFsdWUncyB1bml0cyBpZiB0aGV5IGNhbid0IGJlIGluZmVycmVkIGJ5IHRoZSB2YWx1ZS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKiBAZXhhbXBsZVxuICogY29uc3QgdGltZSA9IFRvbmUuVGltZShcIjRuXCIpLnRvU2Vjb25kcygpO1xuICogY29uc29sZS5sb2codGltZSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3Qgbm90ZSA9IFRvbmUuVGltZSgxKS50b05vdGF0aW9uKCk7XG4gKiBjb25zb2xlLmxvZyhub3RlKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmcmVxID0gVG9uZS5UaW1lKDAuNSkudG9GcmVxdWVuY3koKTtcbiAqIGNvbnNvbGUubG9nKGZyZXEpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gVGltZSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8sIG10b2YgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgZnRvbSwgZ2V0QTQsIHNldEE0IH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuL1RpbWVcIjtcbi8qKlxuICogRnJlcXVlbmN5IGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIEZyZXF1ZW5jeSB2YWx1ZXMuXG4gKiBFdmVudHVhbGx5IGFsbCB0aW1lIHZhbHVlcyBhcmUgZXZhbHVhdGVkIHRvIGhlcnR6IHVzaW5nIHRoZSBgdmFsdWVPZmAgbWV0aG9kLlxuICogQGV4YW1wbGVcbiAqIFRvbmUuRnJlcXVlbmN5KFwiQzNcIik7IC8vIDI2MVxuICogVG9uZS5GcmVxdWVuY3koMzgsIFwibWlkaVwiKTtcbiAqIFRvbmUuRnJlcXVlbmN5KFwiQzNcIikudHJhbnNwb3NlKDQpO1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZXF1ZW5jeUNsYXNzIGV4dGVuZHMgVGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcImh6XCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBbY29uY2VydCB0dW5pbmcgcGl0Y2hdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbmNlcnRfcGl0Y2gpIHdoaWNoIGlzIHVzZWRcbiAgICAgKiB0byBnZW5lcmF0ZSBhbGwgdGhlIG90aGVyIHBpdGNoIHZhbHVlcyBmcm9tIG5vdGVzLiBBNCdzIHZhbHVlcyBpbiBIZXJ0ei5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEE0KCkge1xuICAgICAgICByZXR1cm4gZ2V0QTQoKTtcbiAgICB9XG4gICAgc3RhdGljIHNldCBBNChmcmVxKSB7XG4gICAgICAgIHNldEE0KGZyZXEpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdEFVR01FTlQgQkFTRSBFWFBSRVNTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9nZXRFeHByZXNzaW9ucygpLCB7XG4gICAgICAgICAgICBtaWRpOiB7XG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/bWlkaSkvLFxuICAgICAgICAgICAgICAgIG1ldGhvZCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VW5pdHMgPT09IFwibWlkaVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnJlcXVlbmN5Q2xhc3MubXRvZih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5vdGU6IHtcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFthLWddezF9KD86YnwjfHh8YmIpPykoLT9bMC05XSspL2ksXG4gICAgICAgICAgICAgICAgbWV0aG9kKHBpdGNoLCBvY3RhdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBub3RlVG9TY2FsZUluZGV4W3BpdGNoLnRvTG93ZXJDYXNlKCldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBub3RlTnVtYmVyID0gaW5kZXggKyAocGFyc2VJbnQob2N0YXZlLCAxMCkgKyAxKSAqIDEyO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VW5pdHMgPT09IFwibWlkaVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm90ZU51bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGcmVxdWVuY3lDbGFzcy5tdG9mKG5vdGVOdW1iZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cjoge1xuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyk6KFxcZCsoPzpcXC5cXGQrKT8pOj8oXFxkKyg/OlxcLlxcZCspPyk/LyxcbiAgICAgICAgICAgICAgICBtZXRob2QobSwgcSwgcykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChxICYmIHEgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCAqPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICo9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHMpIC8gNCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRFWFBSRVNTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRyYW5zcG9zZXMgdGhlIGZyZXF1ZW5jeSBieSB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHNlbWl0b25lcy5cbiAgICAgKiBAcmV0dXJuICBBIG5ldyB0cmFuc3Bvc2VkIGZyZXF1ZW5jeVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS50cmFuc3Bvc2UoMyk7IC8vIFwiQzVcIlxuICAgICAqL1xuICAgIHRyYW5zcG9zZShpbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy52YWx1ZU9mKCkgKiBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGFrZXMgYW4gYXJyYXkgb2Ygc2VtaXRvbmUgaW50ZXJ2YWxzIGFuZCByZXR1cm5zXG4gICAgICogYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMgdHJhbnNwb3NlZCBieSB0aG9zZSBpbnRlcnZhbHMuXG4gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBhcnJheSBvZiBGcmVxdWVuY2llc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS5oYXJtb25pemUoWzAsIDMsIDddKTsgLy8gW1wiQTRcIiwgXCJDNVwiLCBcIkU1XCJdXG4gICAgICovXG4gICAgaGFybW9uaXplKGludGVydmFscykge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWxzLm1hcChpbnRlcnZhbCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc3Bvc2UoaW50ZXJ2YWwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRVTklUIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGFzIGEgTUlESSBub3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLkZyZXF1ZW5jeShcIkM0XCIpLnRvTWlkaSgpOyAvLyA2MFxuICAgICAqL1xuICAgIHRvTWlkaSgpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20odGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgaW4gU2NpZW50aWZpYyBQaXRjaCBOb3RhdGlvblxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koNjksIFwibWlkaVwiKS50b05vdGUoKTsgLy8gXCJBNFwiXG4gICAgICovXG4gICAgdG9Ob3RlKCkge1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeSgpO1xuICAgICAgICBjb25zdCBsb2cgPSBNYXRoLmxvZzIoZnJlcSAvIEZyZXF1ZW5jeUNsYXNzLkE0KTtcbiAgICAgICAgbGV0IG5vdGVOdW1iZXIgPSBNYXRoLnJvdW5kKDEyICogbG9nKSArIDU3O1xuICAgICAgICBjb25zdCBvY3RhdmUgPSBNYXRoLmZsb29yKG5vdGVOdW1iZXIgLyAxMik7XG4gICAgICAgIGlmIChvY3RhdmUgPCAwKSB7XG4gICAgICAgICAgICBub3RlTnVtYmVyICs9IC0xMiAqIG9jdGF2ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBub3RlTmFtZSA9IHNjYWxlSW5kZXhUb05vdGVbbm90ZU51bWJlciAlIDEyXTtcbiAgICAgICAgcmV0dXJuIG5vdGVOYW1lICsgb2N0YXZlLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZHVyYXRpb24gb2Ygb25lIGN5Y2xlIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gMSAvIHN1cGVyLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiB0aWNrc1xuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBjb25zdCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHF1YXJ0ZXJzICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFVOSVQgQ09OVkVSU0lPTlMgSEVMUEVSU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFdpdGggbm8gYXJndW1lbnRzLCByZXR1cm4gMFxuICAgICAqL1xuICAgIF9ub0FyZygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gZnJlcTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiAxIC8gKCh0aWNrcyAqIDYwKSAvICh0aGlzLl9nZXRCcG0oKSAqIHRoaXMuX2dldFBQUSgpKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gMSAvIHN1cGVyLl9iZWF0c1RvVW5pdHMoYmVhdHMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiAxIC8gc2Vjb25kcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIE1JREkgbm90ZSB0byBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICogQHBhcmFtICBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm4gVGhlIGNvcnJlc3BvbmRpbmcgZnJlcXVlbmN5IHZhbHVlXG4gICAgICovXG4gICAgc3RhdGljIG10b2YobWlkaSkge1xuICAgICAgICByZXR1cm4gbXRvZihtaWRpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIGZyZXF1ZW5jeSB2YWx1ZSB0byBhIE1JREkgbm90ZS5cbiAgICAgKiBAcGFyYW0gZnJlcXVlbmN5IFRoZSB2YWx1ZSB0byBmcmVxdWVuY3kgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKi9cbiAgICBzdGF0aWMgZnRvbShmcmVxdWVuY3kpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oZnJlcXVlbmN5KTtcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0RlJFUVVFTkNZIENPTlZFUlNJT05TXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogTm90ZSB0byBzY2FsZSBpbmRleC5cbiAqIEBoaWRkZW5cbiAqL1xuY29uc3Qgbm90ZVRvU2NhbGVJbmRleCA9IHtcbiAgICBjYmI6IC0yLCBjYjogLTEsIGM6IDAsIFwiYyNcIjogMSwgY3g6IDIsXG4gICAgZGJiOiAwLCBkYjogMSwgZDogMiwgXCJkI1wiOiAzLCBkeDogNCxcbiAgICBlYmI6IDIsIGViOiAzLCBlOiA0LCBcImUjXCI6IDUsIGV4OiA2LFxuICAgIGZiYjogMywgZmI6IDQsIGY6IDUsIFwiZiNcIjogNiwgZng6IDcsXG4gICAgZ2JiOiA1LCBnYjogNiwgZzogNywgXCJnI1wiOiA4LCBneDogOSxcbiAgICBhYmI6IDcsIGFiOiA4LCBhOiA5LCBcImEjXCI6IDEwLCBheDogMTEsXG4gICAgYmJiOiA5LCBiYjogMTAsIGI6IDExLCBcImIjXCI6IDEyLCBieDogMTMsXG59O1xuLyoqXG4gKiBzY2FsZSBpbmRleCB0byBub3RlIChzaGFycHMpXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHNjYWxlSW5kZXhUb05vdGUgPSBbXCJDXCIsIFwiQyNcIiwgXCJEXCIsIFwiRCNcIiwgXCJFXCIsIFwiRlwiLCBcIkYjXCIsIFwiR1wiLCBcIkcjXCIsIFwiQVwiLCBcIkEjXCIsIFwiQlwiXTtcbi8qKlxuICogQ29udmVydCBhIHZhbHVlIGludG8gYSBGcmVxdWVuY3lDbGFzcyBvYmplY3QuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1pZGkgPSBUb25lLkZyZXF1ZW5jeShcIkMzXCIpLnRvTWlkaSgpO1xuICogY29uc29sZS5sb2cobWlkaSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3QgaGVydHogPSBUb25lLkZyZXF1ZW5jeSgzOCwgXCJtaWRpXCIpLnRvRnJlcXVlbmN5KCk7XG4gKiBjb25zb2xlLmxvZyhoZXJ0eik7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBGcmVxdWVuY3kodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBGcmVxdWVuY3lDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3kuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuL1RpbWVcIjtcbi8qKlxuICogVHJhbnNwb3J0VGltZSBpcyBhIHRoZSB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQnc1xuICogdGltZWxpbmUuIEl0IGlzIHNpbWlsYXIgdG8gVG9uZS5UaW1lLCBidXQgaW5zdGVhZCBvZiBldmFsdWF0aW5nXG4gKiBhZ2FpbnN0IHRoZSBBdWRpb0NvbnRleHQncyBjbG9jaywgaXQgaXMgZXZhbHVhdGVkIGFnYWluc3RcbiAqIHRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbi4gU2VlIFtUcmFuc3BvcnRUaW1lIHdpa2ldKGh0dHBzOi8vZ2l0aHViLmNvbS9Ub25lanMvVG9uZS5qcy93aWtpL1RyYW5zcG9ydFRpbWUpLlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zcG9ydFRpbWVDbGFzcyBleHRlbmRzIFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJhbnNwb3J0VGltZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBpbiB3aGljaGV2ZXIgY29udGV4dCBpcyByZWxldmFudFxuICAgICAqL1xuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHM7XG4gICAgfVxufVxuLyoqXG4gKiBUcmFuc3BvcnRUaW1lIGlzIGEgdGhlIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzXG4gKiB0aW1lbGluZS4gSXQgaXMgc2ltaWxhciB0byBbW1RpbWVdXSwgYnV0IGluc3RlYWQgb2YgZXZhbHVhdGluZ1xuICogYWdhaW5zdCB0aGUgQXVkaW9Db250ZXh0J3MgY2xvY2ssIGl0IGlzIGV2YWx1YXRlZCBhZ2FpbnN0XG4gKiB0aGUgVHJhbnNwb3J0J3MgcG9zaXRpb24uIFNlZSBbVHJhbnNwb3J0VGltZSB3aWtpXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUcmFuc3BvcnRUaW1lKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydFRpbWUuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9GcmVxdWVuY3lcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpbWVcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IGdldERlZmF1bHRzRnJvbUluc3RhbmNlLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Jvb2xlYW4sIGlzRGVmaW5lZCwgaXNOdW1iZXIsIGlzU3RyaW5nLCBpc1VuZGVmIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRoZSBCYXNlIGNsYXNzIGZvciBhbGwgbm9kZXMgdGhhdCBoYXZlIGFuIEF1ZGlvQ29udGV4dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVXaXRoQ29udGV4dCBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY29udGV4dFwiXSk7XG4gICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmRlZmF1bHRDb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldENvbnRleHQoKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIENvbnRleHQgY2xvY2sgcGx1cyB0aGUgbG9va0FoZWFkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2coVG9uZS5ub3coKSk7XG4gICAgICogfSwgMTAwKTtcbiAgICAgKi9cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgKyB0aGlzLmNvbnRleHQubG9va0FoZWFkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBvZiB0aGUgQ29udGV4dCBjbG9jayB3aXRob3V0IGFueSBsb29rQWhlYWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICogXHRjb25zb2xlLmxvZyhUb25lLmltbWVkaWF0ZSgpKTtcbiAgICAgKiB9LCAxMDApO1xuICAgICAqL1xuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgb2Ygb25lIHNhbXBsZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuVHJhbnNwb3J0LnNhbXBsZVRpbWUpO1xuICAgICAqL1xuICAgIGdldCBzYW1wbGVUaW1lKCkge1xuICAgICAgICByZXR1cm4gMSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNlY29uZHMgb2YgMSBwcm9jZXNzaW5nIGJsb2NrICgxMjggc2FtcGxlcylcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuRGVzdGluYXRpb24uYmxvY2tUaW1lKTtcbiAgICAgKi9cbiAgICBnZXQgYmxvY2tUaW1lKCkge1xuICAgICAgICByZXR1cm4gMTI4IC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGluY29taW5nIHRpbWUgdG8gc2Vjb25kcy5cbiAgICAgKiBUaGlzIGlzIGNhbGN1bGF0ZWQgYWdhaW5zdCB0aGUgY3VycmVudCBbW1RvbmUuVHJhbnNwb3J0XV0gYnBtXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKGdhaW4udG9TZWNvbmRzKFwiNG5cIikpLCAxMDApO1xuICAgICAqIC8vIHJhbXAgdGhlIHRlbXBvIHRvIDYwIGJwbSBvdmVyIDMwIHNlY29uZHNcbiAgICAgKiBUb25lLmdldFRyYW5zcG9ydCgpLmJwbS5yYW1wVG8oNjAsIDMwKTtcbiAgICAgKi9cbiAgICB0b1NlY29uZHModGltZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbnB1dCB0byBhIGZyZXF1ZW5jeSBudW1iZXJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2coZ2Fpbi50b0ZyZXF1ZW5jeShcIjRuXCIpKTtcbiAgICAgKi9cbiAgICB0b0ZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHJldHVybiBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBmcmVxKS50b0ZyZXF1ZW5jeSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbnB1dCB0aW1lIGludG8gdGlja3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2coZ2Fpbi50b1RpY2tzKFwiNG5cIikpO1xuICAgICAqL1xuICAgIHRvVGlja3ModGltZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRHRVQvU0VUXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3Vic2V0IG9mIHRoZSBwcm9wZXJ0aWVzIHdoaWNoIGFyZSBpbiB0aGUgcGFydGlhbCBwcm9wc1xuICAgICAqL1xuICAgIF9nZXRQYXJ0aWFsUHJvcGVydGllcyhwcm9wcykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5nZXQoKTtcbiAgICAgICAgLy8gcmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgcHJvcCB0aGF0IGFyZSBub3QgaW4gdGhlIHBhcnRpYWxcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHByb3BzW25hbWVdKSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zW25hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb2JqZWN0J3MgYXR0cmlidXRlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvc2MuZ2V0KCkpO1xuICAgICAqL1xuICAgIGdldCgpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZSh0aGlzKTtcbiAgICAgICAgT2JqZWN0LmtleXMoZGVmYXVsdHMpLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0Lmhhcyh0aGlzLCBhdHRyaWJ1dGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyID0gdGhpc1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQobWVtYmVyKSAmJiBpc0RlZmluZWQobWVtYmVyLnZhbHVlKSAmJiBpc0RlZmluZWQobWVtYmVyLnNldFZhbHVlQXRUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0c1thdHRyaWJ1dGVdID0gbWVtYmVyLnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChtZW1iZXIgaW5zdGFuY2VvZiBUb25lV2l0aENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlci5fZ2V0UGFydGlhbFByb3BlcnRpZXMoZGVmYXVsdHNbYXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBtYWtlIHN1cmUgaXQncyBhIHNlcmlhbGl6YWJsZSB0eXBlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXkobWVtYmVyKSB8fCBpc051bWJlcihtZW1iZXIpIHx8IGlzU3RyaW5nKG1lbWJlcikgfHwgaXNCb29sZWFuKG1lbWJlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgdW5kZWZpbmVkIGFuZCB1bnNlcmlhbGl6YWJsZSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBkZWZhdWx0c1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IG11bHRpcGxlIHByb3BlcnRpZXMgYXQgb25jZSB3aXRoIGFuIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzZXQgdmFsdWVzIHVzaW5nIGFuIG9iamVjdFxuICAgICAqIGZpbHRlci5zZXQoe1xuICAgICAqIFx0ZnJlcXVlbmN5OiBcIkM2XCIsXG4gICAgICogXHR0eXBlOiBcImhpZ2hwYXNzXCJcbiAgICAgKiB9KTtcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9BbmFsb2dzeW50aF9vY3RhdmVzX2hpZ2htaWQubXAzXCIpLmNvbm5lY3QoZmlsdGVyKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXQocHJvcHMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMocHJvcHMpLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0Lmhhcyh0aGlzLCBhdHRyaWJ1dGUpICYmIGlzRGVmaW5lZCh0aGlzW2F0dHJpYnV0ZV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdLnZhbHVlKSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdLnNldFZhbHVlQXRUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBzbWFsbCBvcHRpbWl6YXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXS52YWx1ZSAhPT0gcHJvcHNbYXR0cmlidXRlXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdLnZhbHVlID0gcHJvcHNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzW2F0dHJpYnV0ZV0gaW5zdGFuY2VvZiBUb25lV2l0aENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdLnNldChwcm9wc1thdHRyaWJ1dGVdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXSA9IHByb3BzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZVdpdGhDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogQSBUaW1lbGluZSBTdGF0ZS4gUHJvdmlkZXMgdGhlIG1ldGhvZHM6IGBzZXRTdGF0ZUF0VGltZShcInN0YXRlXCIsIHRpbWUpYCBhbmQgYGdldFZhbHVlQXRUaW1lKHRpbWUpYFxuICogQHBhcmFtIGluaXRpYWwgVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIFN0YXRlVGltZWxpbmUuICBEZWZhdWx0cyB0byBgdW5kZWZpbmVkYFxuICovXG5leHBvcnQgY2xhc3MgU3RhdGVUaW1lbGluZSBleHRlbmRzIFRpbWVsaW5lIHtcbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsID0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGF0ZVRpbWVsaW5lXCI7XG4gICAgICAgIHRoaXMuX2luaXRpYWwgPSBpbml0aWFsO1xuICAgICAgICB0aGlzLnNldFN0YXRlQXRUaW1lKHRoaXMuX2luaXRpYWwsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgc2NoZWR1bGVkIGJlZm9yZSBvciBhdFxuICAgICAqIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuICAgICAqL1xuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKGV2ZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBzdGF0ZSB0byB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgbmFtZSBvZiB0aGUgc3RhdGUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgQW55IGFkZGl0aW9uYWwgb3B0aW9ucyB0aGF0IGFyZSBuZWVkZWQgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIHNldFN0YXRlQXRUaW1lKHN0YXRlLCB0aW1lLCBvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDApO1xuICAgICAgICB0aGlzLmFkZChPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICAgIHRpbWUsXG4gICAgICAgIH0pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZXZlbnQgYmVmb3JlIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgc3RhdGUgdG8gbG9vayBmb3JcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gY2hlY2sgYmVmb3JlXG4gICAgICogQHJldHVybiAgVGhlIGV2ZW50IHdpdGggdGhlIGdpdmVuIHN0YXRlIGJlZm9yZSB0aGUgdGltZVxuICAgICAqL1xuICAgIGdldExhc3RTdGF0ZShzdGF0ZSwgdGltZSkge1xuICAgICAgICAvLyB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGV2ZW50IGFmdGVyIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgc3RhdGUgdG8gbG9vayBmb3JcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gY2hlY2sgZnJvbVxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aXRoIHRoZSBnaXZlbiBzdGF0ZSBhZnRlciB0aGUgdGltZVxuICAgICAqL1xuICAgIGdldE5leHRTdGF0ZShzdGF0ZSwgdGltZSkge1xuICAgICAgICAvLyB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPCB0aGlzLl90aW1lbGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RhdGVUaW1lbGluZS5qcy5tYXAiLCJpbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4vVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBFUSB9IGZyb20gXCIuLi91dGlsL01hdGhcIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQYXJhbSB3cmFwcyB0aGUgbmF0aXZlIFdlYiBBdWRpbydzIEF1ZGlvUGFyYW0gdG8gcHJvdmlkZVxuICogYWRkaXRpb25hbCB1bml0IGNvbnZlcnNpb24gZnVuY3Rpb25hbGl0eS4gSXQgYWxzb1xuICogc2VydmVzIGFzIGEgYmFzZS1jbGFzcyBmb3IgY2xhc3NlcyB3aGljaCBoYXZlIGEgc2luZ2xlLFxuICogYXV0b21hdGFibGUgcGFyYW1ldGVyLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFBhcmFtIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYXJhbVwiLCBcInVuaXRzXCIsIFwiY29udmVydFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhcmFtXCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGRlbiA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9taW5PdXRwdXQgPSAxZS03O1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYXJhbVwiLCBcInVuaXRzXCIsIFwiY29udmVydFwiXSk7XG4gICAgICAgIGFzc2VydChpc0RlZmluZWQob3B0aW9ucy5wYXJhbSkgJiZcbiAgICAgICAgICAgIChpc0F1ZGlvUGFyYW0ob3B0aW9ucy5wYXJhbSkgfHwgb3B0aW9ucy5wYXJhbSBpbnN0YW5jZW9mIFBhcmFtKSwgXCJwYXJhbSBtdXN0IGJlIGFuIEF1ZGlvUGFyYW1cIik7XG4gICAgICAgIHdoaWxlICghaXNBdWRpb1BhcmFtKG9wdGlvbnMucGFyYW0pKSB7XG4gICAgICAgICAgICBvcHRpb25zLnBhcmFtID0gb3B0aW9ucy5wYXJhbS5fcGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3dhcHBhYmxlID0gaXNEZWZpbmVkKG9wdGlvbnMuc3dhcHBhYmxlKSA/IG9wdGlvbnMuc3dhcHBhYmxlIDogZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9zd2FwcGFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZVxuICAgICAgICAgICAgdGhpcy5fcGFyYW0gPSBvcHRpb25zLnBhcmFtO1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtID0gdGhpcy5pbnB1dCA9IG9wdGlvbnMucGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRpbWVsaW5lKDEwMDApO1xuICAgICAgICB0aGlzLl9pbml0aWFsVmFsdWUgPSB0aGlzLl9wYXJhbS5kZWZhdWx0VmFsdWU7XG4gICAgICAgIHRoaXMudW5pdHMgPSBvcHRpb25zLnVuaXRzO1xuICAgICAgICB0aGlzLmNvbnZlcnQgPSBvcHRpb25zLmNvbnZlcnQ7XG4gICAgICAgIHRoaXMuX21pblZhbHVlID0gb3B0aW9ucy5taW5WYWx1ZTtcbiAgICAgICAgdGhpcy5fbWF4VmFsdWUgPSBvcHRpb25zLm1heFZhbHVlO1xuICAgICAgICAvLyBpZiB0aGUgdmFsdWUgaXMgZGVmaW5lZCwgc2V0IGl0IGltbWVkaWF0ZWx5XG4gICAgICAgIGlmIChpc0RlZmluZWQob3B0aW9ucy52YWx1ZSkgJiYgb3B0aW9ucy52YWx1ZSAhPT0gdGhpcy5fdG9UeXBlKHRoaXMuX2luaXRpYWxWYWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZUF0VGltZShub3cpO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGhpcy5ub3coKSk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIC8vIGlmIGl0J3Mgbm90IHRoZSBkZWZhdWx0IG1pblZhbHVlLCByZXR1cm4gaXRcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl9taW5WYWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9taW5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcInRpbWVcIiB8fCB0aGlzLnVuaXRzID09PSBcImZyZXF1ZW5jeVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcIm5vcm1hbFJhbmdlXCIgfHwgdGhpcy51bml0cyA9PT0gXCJwb3NpdGl2ZVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcInRyYW5zcG9ydFRpbWVcIiB8fCB0aGlzLnVuaXRzID09PSBcInRpY2tzXCIgfHxcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPT09IFwiYnBtXCIgfHwgdGhpcy51bml0cyA9PT0gXCJoZXJ0elwiIHx8IHRoaXMudW5pdHMgPT09IFwic2FtcGxlc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcImF1ZGlvUmFuZ2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwiZGVjaWJlbHNcIikge1xuICAgICAgICAgICAgcmV0dXJuIC1JbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5taW5WYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fbWF4VmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWF4VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJub3JtYWxSYW5nZVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcImF1ZGlvUmFuZ2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWF4VmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHlwZSBndWFyZCBiYXNlZCBvbiB0aGUgdW5pdCBuYW1lXG4gICAgICovXG4gICAgX2lzKGFyZywgdHlwZSkge1xuICAgICAgICByZXR1cm4gdGhpcy51bml0cyA9PT0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFrZSBzdXJlIHRoZSB2YWx1ZSBpcyBhbHdheXMgaW4gdGhlIGRlZmluZWQgcmFuZ2VcbiAgICAgKi9cbiAgICBfYXNzZXJ0UmFuZ2UodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm1heFZhbHVlKSAmJiBpc0RlZmluZWQodGhpcy5taW5WYWx1ZSkpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHZhbHVlLCB0aGlzLl9mcm9tVHlwZSh0aGlzLm1pblZhbHVlKSwgdGhpcy5fZnJvbVR5cGUodGhpcy5tYXhWYWx1ZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgZ2l2ZW4gdmFsdWUgZnJvbSB0aGUgdHlwZSBzcGVjaWZpZWQgYnkgUGFyYW0udW5pdHNcbiAgICAgKiBpbnRvIHRoZSBkZXN0aW5hdGlvbiB2YWx1ZSAoc3VjaCBhcyBHYWluIG9yIEZyZXF1ZW5jeSkuXG4gICAgICovXG4gICAgX2Zyb21UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy5jb252ZXJ0ICYmICF0aGlzLm92ZXJyaWRkZW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pcyh2YWwsIFwidGltZVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcyh2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXModmFsLCBcImRlY2liZWxzXCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRiVG9HYWluKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9pcyh2YWwsIFwiZnJlcXVlbmN5XCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9GcmVxdWVuY3kodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5vdmVycmlkZGVuKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIG92ZXJyaWRkZW4sIHNob3VsZCBvbmx5IHNjaGVkdWxlIDBzXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgcGFyYW1ldGVycyB2YWx1ZSBpbnRvIHRoZSB1bml0cyBzcGVjaWZpZWQgYnkgUGFyYW0udW5pdHMuXG4gICAgICovXG4gICAgX3RvVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udmVydCAmJiB0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBnYWluVG9EYih2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBQlNUUkFDVCBQQVJBTSBJTlRFUkZBQ0VcbiAgICAvLyBhbGwgZG9jcyBhcmUgZ2VuZXJhdGVkIGZyb20gUGFyYW1JbnRlcmZhY2UudHNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBzZXRWYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KHRpbWUpfWApO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcInNldFZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IE1hdGgubWF4KHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwKTtcbiAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIC8vIGlmIGl0IHdhcyBzZXQgYnlcbiAgICAgICAgaWYgKGJlZm9yZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIgJiYgKGFmdGVyID09PSBudWxsIHx8IGFmdGVyLnR5cGUgPT09IFwic2V0VmFsdWVBdFRpbWVcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5fZXZlbnRzLmdldEJlZm9yZShiZWZvcmUudGltZSk7XG4gICAgICAgICAgICBsZXQgcHJldmlvdXNWYWw7XG4gICAgICAgICAgICBpZiAocHJldmlvdXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbCA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzVmFsID0gcHJldmlvdXMudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsQXBwcm9hY2goYmVmb3JlLnRpbWUsIHByZXZpb3VzVmFsLCBiZWZvcmUudmFsdWUsIGJlZm9yZS5jb25zdGFudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhZnRlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiIHx8IGFmdGVyLnR5cGUgPT09IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICBsZXQgYmVmb3JlVmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2V2ZW50cy5nZXRCZWZvcmUoYmVmb3JlLnRpbWUpO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBiZWZvcmVWYWx1ZSA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVZhbHVlID0gcHJldmlvdXMudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fbGluZWFySW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZVZhbHVlLCBhZnRlci50aW1lLCBhZnRlci52YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fZXhwb25lbnRpYWxJbnRlcnBvbGF0ZShiZWZvcmUudGltZSwgYmVmb3JlVmFsdWUsIGFmdGVyLnRpbWUsIGFmdGVyLnZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh2YWx1ZSk7XG4gICAgfVxuICAgIHNldFJhbXBQb2ludCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWYWwgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9mcm9tVHlwZShjdXJyZW50VmFsKSA9PT0gMCkge1xuICAgICAgICAgICAgY3VycmVudFZhbCA9IHRoaXMuX3RvVHlwZSh0aGlzLl9taW5PdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUoY3VycmVudFZhbCwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKGVuZFRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KGVuZFRpbWUpfWApO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgIGxldCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIHRoZSB2YWx1ZSBjYW4ndCBiZSAwXG4gICAgICAgIG51bWVyaWNWYWx1ZSA9IEVRKG51bWVyaWNWYWx1ZSwgMCkgPyB0aGlzLl9taW5PdXRwdXQgOiBudW1lcmljVmFsdWU7XG4gICAgICAgIHRoaXMuX2Fzc2VydFJhbmdlKG51bWVyaWNWYWx1ZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKGVuZFRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkoZW5kVGltZSl9YCk7XG4gICAgICAgIC8vIHN0b3JlIHRoZSBldmVudFxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSArIHRoaXMudG9TZWNvbmRzKHJhbXBUaW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lICsgdGhpcy50b1NlY29uZHMocmFtcFRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUsIHJhbXBUaW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmFtcFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSk7XG4gICAgICAgIGNvbnN0IHRpbWVDb25zdGFudCA9IE1hdGgubG9nKHJhbXBUaW1lICsgMSkgLyBNYXRoLmxvZygyMDApO1xuICAgICAgICB0aGlzLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgdGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgLy8gYXQgOTAlIHN0YXJ0IGEgbGluZWFyIHJhbXAgdG8gdGhlIGZpbmFsIHZhbHVlXG4gICAgICAgIHRoaXMuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lICsgcmFtcFRpbWUgKiAwLjkpO1xuICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lICsgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIFRoZSB2YWx1ZSB3aWxsIG5ldmVyIGJlIGFibGUgdG8gYXBwcm9hY2ggd2l0aG91dCB0aW1lQ29uc3RhbnQgPiAwLlxuICAgICAgICBhc3NlcnQoaXNGaW5pdGUodGltZUNvbnN0YW50KSAmJiB0aW1lQ29uc3RhbnQgPiAwLCBcInRpbWVDb25zdGFudCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwXCIpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBzZXRUYXJnZXRBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeShzdGFydFRpbWUpfWApO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIGNvbnN0YW50OiB0aW1lQ29uc3RhbnQsXG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcInNldFRhcmdldEF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwic2V0VGFyZ2V0QXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFRhcmdldEF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nID0gMSkge1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc3RhcnRpbmdWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlc1swXSkgKiBzY2FsaW5nO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShzdGFydGluZ1ZhbHVlKSwgc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc2VnVGltZSA9IGR1cmF0aW9uIC8gKHZhbHVlcy5sZW5ndGggLSAxKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlc1tpXSkgKiBzY2FsaW5nO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUobnVtZXJpY1ZhbHVlKSwgc3RhcnRUaW1lICsgaSAqIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50IHRvIGNhbmNlbFNjaGVkdWxlZFZhbHVlczogJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJjYW5jZWxTY2hlZHVsZWRWYWx1ZXNcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgdmFsdWVBdFRpbWUgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkpO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHNjaGVkdWxlIGV2ZW50c1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQgdG8gY2FuY2VsQW5kSG9sZEF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJjYW5jZWxBbmRIb2xkQXRUaW1lXCIsIGNvbXB1dGVkVGltZSwgXCJ2YWx1ZT1cIiArIHZhbHVlQXRUaW1lKTtcbiAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gZXZlbnQgYXQgdGhlIGdpdmVuIGNvbXB1dGVkVGltZVxuICAgICAgICAvLyBhbmQgdGhhdCBldmVuIGlzIG5vdCBhIFwic2V0XCJcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcihjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAoYmVmb3JlICYmIEVRKGJlZm9yZS50aW1lLCBjb21wdXRlZFRpbWUpKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgZXZlcnl0aGluZyBhZnRlclxuICAgICAgICAgICAgaWYgKGFmdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChjb21wdXRlZFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGFmdGVyKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICAvLyBjYW5jZWwgdGhlIG5leHQgZXZlbnQocylcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUodmFsdWVBdFRpbWUpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHZhbHVlQXRUaW1lKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlQXRUaW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWVBdFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByYW1wVG8odmFsdWUsIHJhbXBUaW1lID0gMC4xLCBzdGFydFRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiZnJlcXVlbmN5XCIgfHwgdGhpcy51bml0cyA9PT0gXCJicG1cIiB8fCB0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcHBseSBhbGwgb2YgdGhlIHByZXZpb3VzbHkgc2NoZWR1bGVkIGV2ZW50cyB0byB0aGUgcGFzc2VkIGluIFBhcmFtIG9yIEF1ZGlvUGFyYW0uXG4gICAgICogVGhlIGFwcGxpZWQgdmFsdWVzIHdpbGwgc3RhcnQgYXQgdGhlIGNvbnRleHQncyBjdXJyZW50IHRpbWUgYW5kIHNjaGVkdWxlXG4gICAgICogYWxsIG9mIHRoZSBldmVudHMgd2hpY2ggYXJlIHNjaGVkdWxlZCBvbiB0aGlzIFBhcmFtIG9udG8gdGhlIHBhc3NlZCBpbiBwYXJhbS5cbiAgICAgKi9cbiAgICBhcHBseShwYXJhbSkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIC8vIHNldCB0aGUgcGFyYW0ncyB2YWx1ZSBhdCB0aGUgY3VycmVudCB0aW1lIGFuZCBzY2hlZHVsZSBldmVyeXRoaW5nIGVsc2VcbiAgICAgICAgcGFyYW0uc2V0VmFsdWVBdFRpbWUodGhpcy5nZXRWYWx1ZUF0VGltZShub3cpLCBub3cpO1xuICAgICAgICAvLyBpZiB0aGUgcHJldmlvdXMgZXZlbnQgd2FzIGEgY3VydmUsIHRoZW4gc2V0IHRoZSByZXN0IG9mIGl0XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KG5vdyk7XG4gICAgICAgIGlmIChwcmV2aW91c0V2ZW50ICYmIHByZXZpb3VzRXZlbnQudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIikge1xuICAgICAgICAgICAgLy8gYXBwcm94IGl0IHVudGlsIHRoZSBuZXh0IGV2ZW50IHdpdGggbGluZWFyIHJhbXBzXG4gICAgICAgICAgICBjb25zdCBuZXh0RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIocHJldmlvdXNFdmVudC50aW1lKTtcbiAgICAgICAgICAgIC8vIG9yIGZvciAyIHNlY29uZHMgaWYgdGhlcmUgaXMgbm8gZXZlbnRcbiAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBuZXh0RXZlbnQgPyBuZXh0RXZlbnQudGltZSA6IG5vdyArIDI7XG4gICAgICAgICAgICBjb25zdCBzdWJkaXZpc2lvbnMgPSAoZW5kVGltZSAtIG5vdykgLyAxMDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBub3c7IGkgPCBlbmRUaW1lOyBpICs9IHN1YmRpdmlzaW9ucykge1xuICAgICAgICAgICAgICAgIHBhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuZ2V0VmFsdWVBdFRpbWUoaSksIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoQWZ0ZXIodGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJjYW5jZWxTY2hlZHVsZWRWYWx1ZXNcIikge1xuICAgICAgICAgICAgICAgIHBhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5zZXRUYXJnZXRBdFRpbWUoZXZlbnQudmFsdWUsIGV2ZW50LnRpbWUsIGV2ZW50LmNvbnN0YW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtW2V2ZW50LnR5cGVdKGV2ZW50LnZhbHVlLCBldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlIHRoZSBQYXJhbSdzIGludGVybmFsIEF1ZGlvUGFyYW0uIFdpbGwgYXBwbHkgc2NoZWR1bGVkIGN1cnZlc1xuICAgICAqIG9udG8gdGhlIHBhcmFtZXRlciBhbmQgcmVwbGFjZSB0aGUgY29ubmVjdGlvbnMuXG4gICAgICovXG4gICAgc2V0UGFyYW0ocGFyYW0pIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N3YXBwYWJsZSwgXCJUaGUgUGFyYW0gbXVzdCBiZSBhc3NpZ25lZCBhcyAnc3dhcHBhYmxlJyBpbiB0aGUgY29uc3RydWN0b3JcIik7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdGhpcy5pbnB1dDtcbiAgICAgICAgaW5wdXQuZGlzY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIHRoaXMuYXBwbHkocGFyYW0pO1xuICAgICAgICB0aGlzLl9wYXJhbSA9IHBhcmFtO1xuICAgICAgICBpbnB1dC5jb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCBkZWZhdWx0VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fcGFyYW0uZGVmYXVsdFZhbHVlKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRBVVRPTUFUSU9OIENVUlZFIENBTENVTEFUSU9OU1xuICAgIC8vIFx0TUlUIExpY2Vuc2UsIGNvcHlyaWdodCAoYykgMjAxNCBKb3JkYW4gU2FudGVsbFxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgc2V0VGFyZ2V0QXRUaW1lXG4gICAgX2V4cG9uZW50aWFsQXBwcm9hY2godDAsIHYwLCB2MSwgdGltZUNvbnN0YW50LCB0KSB7XG4gICAgICAgIHJldHVybiB2MSArICh2MCAtIHYxKSAqIE1hdGguZXhwKC0odCAtIHQwKSAvIHRpbWVDb25zdGFudCk7XG4gICAgfVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcbiAgICBfbGluZWFySW50ZXJwb2xhdGUodDAsIHYwLCB0MSwgdjEsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYwICsgKHYxIC0gdjApICogKCh0IC0gdDApIC8gKHQxIC0gdDApKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlcyB0aGUgdGhlIHZhbHVlIGFsb25nIHRoZSBjdXJ2ZSBwcm9kdWNlZCBieSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXG4gICAgX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUodDAsIHYwLCB0MSwgdjEsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYwICogTWF0aC5wb3codjEgLyB2MCwgKHQgLSB0MCkgLyAodDEgLSB0MCkpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlLCBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuL1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCwgd2FybiB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFRvbmVBdWRpb05vZGUgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGNsYXNzZXMgd2hpY2ggcHJvY2VzcyBhdWRpby5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb05vZGUgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGNsYXNzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb05vZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIExpc3QgYWxsIG9mIHRoZSBub2RlIHRoYXQgbXVzdCBiZSBzZXQgdG8gbWF0Y2ggdGhlIENoYW5uZWxQcm9wZXJ0aWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW5wdXRzIGZlZWRpbmcgaW50byB0aGUgQXVkaW9Ob2RlLlxuICAgICAqIEZvciBzb3VyY2Ugbm9kZXMsIHRoaXMgd2lsbCBiZSAwLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhub2RlLm51bWJlck9mSW5wdXRzKTtcbiAgICAgKi9cbiAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgIGlmIChpc0F1ZGlvUGFyYW0odGhpcy5pbnB1dCkgfHwgdGhpcy5pbnB1dCBpbnN0YW5jZW9mIFBhcmFtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb3V0cHV0cyBvZiB0aGUgQXVkaW9Ob2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhub2RlLm51bWJlck9mT3V0cHV0cyk7XG4gICAgICovXG4gICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBVURJTyBQUk9QRVJUSUVTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVXNlZCB0byBkZWNpZGUgd2hpY2ggbm9kZXMgdG8gZ2V0L3NldCBwcm9wZXJ0aWVzIG9uXG4gICAgICovXG4gICAgX2lzQXVkaW9Ob2RlKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIGlzRGVmaW5lZChub2RlKSAmJiAobm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgaXNBdWRpb05vZGUobm9kZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdWRpbyBub2RlcyAoZWl0aGVyIGludGVybmFsIG9yIGlucHV0L291dHB1dCkgd2hpY2ggdG9nZXRoZXJcbiAgICAgKiBtYWtlIHVwIGhvdyB0aGUgY2xhc3Mgbm9kZSByZXNwb25kcyB0byBjaGFubmVsIGlucHV0L291dHB1dFxuICAgICAqL1xuICAgIF9nZXRJbnRlcm5hbE5vZGVzKCkge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2ludGVybmFsQ2hhbm5lbHMuc2xpY2UoMCk7XG4gICAgICAgIGlmICh0aGlzLl9pc0F1ZGlvTm9kZSh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgbm9kZUxpc3QucHVzaCh0aGlzLmlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5faXNBdWRpb05vZGUodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dCAhPT0gdGhpcy5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICBub2RlTGlzdC5wdXNoKHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9kZUxpc3Q7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXVkaW8gb3B0aW9ucyBmb3IgdGhpcyBub2RlIHN1Y2ggYXMgY2hhbm5lbEludGVycHJldGF0aW9uXG4gICAgICogY2hhbm5lbENvdW50LCBldGMuXG4gICAgICogQHBhcmFtIG9wdGlvbnNcbiAgICAgKi9cbiAgICBfc2V0Q2hhbm5lbFByb3BlcnRpZXMob3B0aW9ucykge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2dldEludGVybmFsTm9kZXMoKTtcbiAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5vZGUuY2hhbm5lbENvdW50ID0gb3B0aW9ucy5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxDb3VudE1vZGUgPSBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IGF1ZGlvIG9wdGlvbnMgZm9yIHRoaXMgbm9kZSBzdWNoIGFzIGNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAqIGNoYW5uZWxDb3VudCwgZXRjLlxuICAgICAqL1xuICAgIF9nZXRDaGFubmVsUHJvcGVydGllcygpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9nZXRJbnRlcm5hbE5vZGVzKCk7XG4gICAgICAgIGFzc2VydChub2RlTGlzdC5sZW5ndGggPiAwLCBcIlRvbmVBdWRpb05vZGUgZG9lcyBub3QgaGF2ZSBhbnkgaW50ZXJuYWwgbm9kZXNcIik7XG4gICAgICAgIC8vIHVzZSB0aGUgZmlyc3Qgbm9kZSB0byBnZXQgcHJvcGVydGllc1xuICAgICAgICAvLyB0aGV5IHNob3VsZCBhbGwgYmUgdGhlIHNhbWVcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVMaXN0WzBdO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBub2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYW5uZWxDb3VudCBpcyB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHVzZWQgd2hlbiB1cC1taXhpbmcgYW5kIGRvd24tbWl4aW5nXG4gICAgICogY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMiBleGNlcHQgZm9yXG4gICAgICogc3BlY2lmaWMgbm9kZXMgd2hlcmUgaXRzIHZhbHVlIGlzIHNwZWNpYWxseSBkZXRlcm1pbmVkLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpLmNoYW5uZWxDb3VudDtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxDb3VudChjaGFubmVsQ291bnQpIHtcbiAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpO1xuICAgICAgICAvLyBtZXJnZSBpdCB3aXRoIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuX3NldENoYW5uZWxQcm9wZXJ0aWVzKE9iamVjdC5hc3NpZ24ocHJvcHMsIHsgY2hhbm5lbENvdW50IH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhbm5lbENvdW50TW9kZSBkZXRlcm1pbmVzIGhvdyBjaGFubmVscyB3aWxsIGJlIGNvdW50ZWQgd2hlbiB1cC1taXhpbmcgYW5kXG4gICAgICogZG93bi1taXhpbmcgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcIm1heFwiLiBUaGlzIGF0dHJpYnV0ZSBoYXMgbm8gZWZmZWN0IGZvciBub2RlcyB3aXRoIG5vIGlucHV0cy5cbiAgICAgKiAqIFwibWF4XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgdGhlIG1heGltdW0gb2YgdGhlIG51bWJlciBvZiBjaGFubmVscyBvZiBhbGwgY29ubmVjdGlvbnMgdG8gYW4gaW5wdXQuIEluIHRoaXMgbW9kZSBjaGFubmVsQ291bnQgaXMgaWdub3JlZC5cbiAgICAgKiAqIFwiY2xhbXBlZC1tYXhcIiAtIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyBkZXRlcm1pbmVkIGFzIGZvciBcIm1heFwiIGFuZCB0aGVuIGNsYW1wZWQgdG8gYSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBnaXZlbiBjaGFubmVsQ291bnQuXG4gICAgICogKiBcImV4cGxpY2l0XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgdGhlIGV4YWN0IHZhbHVlIGFzIHNwZWNpZmllZCBieSB0aGUgY2hhbm5lbENvdW50LlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKS5jaGFubmVsQ291bnRNb2RlO1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbENvdW50TW9kZShjaGFubmVsQ291bnRNb2RlKSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKTtcbiAgICAgICAgLy8gbWVyZ2UgaXQgd2l0aCB0aGUgb3RoZXIgcHJvcGVydGllc1xuICAgICAgICB0aGlzLl9zZXRDaGFubmVsUHJvcGVydGllcyhPYmplY3QuYXNzaWduKHByb3BzLCB7IGNoYW5uZWxDb3VudE1vZGUgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFubmVsSW50ZXJwcmV0YXRpb24gZGV0ZXJtaW5lcyBob3cgaW5kaXZpZHVhbCBjaGFubmVscyB3aWxsIGJlIHRyZWF0ZWRcbiAgICAgKiB3aGVuIHVwLW1peGluZyBhbmQgZG93bi1taXhpbmcgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcInNwZWFrZXJzXCIuXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKGNoYW5uZWxJbnRlcnByZXRhdGlvbikge1xuICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCk7XG4gICAgICAgIC8vIG1lcmdlIGl0IHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5fc2V0Q2hhbm5lbFByb3BlcnRpZXMoT2JqZWN0LmFzc2lnbihwcm9wcywgeyBjaGFubmVsSW50ZXJwcmV0YXRpb24gfSkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDT05ORUNUSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiBhIFRvbmVBdWRpb05vZGUgdG8gYW4gQXVkaW9QYXJhbSwgQXVkaW9Ob2RlLCBvciBUb25lQXVkaW9Ob2RlXG4gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBvdXRwdXQgdG8gY29ubmVjdCB0b1xuICAgICAqIEBwYXJhbSBvdXRwdXROdW0gVGhlIG91dHB1dCB0byBjb25uZWN0IGZyb21cbiAgICAgKiBAcGFyYW0gaW5wdXROdW0gVGhlIGlucHV0IHRvIGNvbm5lY3QgdG9cbiAgICAgKi9cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgY29ubmVjdCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBvdXRwdXQgdG8gdGhlIGNvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcihcIkMyXCIpLnN0YXJ0KCk7XG4gICAgICogb3NjLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICB0b0Rlc3RpbmF0aW9uKCkge1xuICAgICAgICB0aGlzLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG91dHB1dCB0byB0aGUgY29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICogU2VlIFtbdG9EZXN0aW5hdGlvbl1dXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICB0b01hc3RlcigpIHtcbiAgICAgICAgd2FybihcInRvTWFzdGVyKCkgaGFzIGJlZW4gcmVuYW1lZCB0b0Rlc3RpbmF0aW9uKClcIik7XG4gICAgICAgIHJldHVybiB0aGlzLnRvRGVzdGluYXRpb24oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZGlzY29ubmVjdCB0aGUgb3V0cHV0XG4gICAgICovXG4gICAgZGlzY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGRpc2Nvbm5lY3QodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gc2VyaWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9oYW5kZHJ1bS1sb29wLm1wM1wiKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKDQpLnN0YXJ0KCk7XG4gICAgICogY29uc3QgZGlzdG9ydGlvbiA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC41KTtcbiAgICAgKiAvLyBjb25uZWN0IHRoZSBwbGF5ZXIgdG8gdGhlIGZpbHRlciwgZGlzdG9ydGlvbiBhbmQgdGhlbiB0byB0aGUgbWFzdGVyIG91dHB1dFxuICAgICAqIHBsYXllci5jaGFpbihmaWx0ZXIsIGRpc3RvcnRpb24sIFRvbmUuRGVzdGluYXRpb24pO1xuICAgICAqL1xuICAgIGNoYWluKC4uLm5vZGVzKSB7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcywgLi4ubm9kZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gcGFyYWxsZWwuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vZHJ1bS1zYW1wbGVzL2NvbmdhLXJoeXRobS5tcDNcIik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogY29uc3QgcGl0Y2hTaGlmdCA9IG5ldyBUb25lLlBpdGNoU2hpZnQoNCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcihcIkc1XCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBjb25uZWN0IGEgbm9kZSB0byB0aGUgcGl0Y2ggc2hpZnQgYW5kIGZpbHRlciBpbiBwYXJhbGxlbFxuICAgICAqIHBsYXllci5mYW4ocGl0Y2hTaGlmdCwgZmlsdGVyKTtcbiAgICAgKi9cbiAgICBmYW4oLi4ubm9kZXMpIHtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHRoaXMuY29ubmVjdChub2RlKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEaXNwb3NlIGFuZCBkaXNjb25uZWN0XG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dCBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm91dHB1dCBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZSh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENPTk5FQ1RJT05TXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogY29ubmVjdCB0b2dldGhlciBhbGwgb2YgdGhlIGFyZ3VtZW50cyBpbiBzZXJpZXNcbiAqIEBwYXJhbSBub2Rlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdFNlcmllcyguLi5ub2Rlcykge1xuICAgIGNvbnN0IGZpcnN0ID0gbm9kZXMuc2hpZnQoKTtcbiAgICBub2Rlcy5yZWR1Y2UoKHByZXYsIGN1cnJlbnQpID0+IHtcbiAgICAgICAgaWYgKHByZXYgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICBwcmV2LmNvbm5lY3QoY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNBdWRpb05vZGUocHJldikpIHtcbiAgICAgICAgICAgIGNvbm5lY3QocHJldiwgY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGN1cnJlbnQ7XG4gICAgfSwgZmlyc3QpO1xufVxuLyoqXG4gKiBDb25uZWN0IHR3byBub2RlcyB0b2dldGhlciBzbyB0aGF0IHNpZ25hbCBmbG93cyBmcm9tIHRoZVxuICogZmlyc3Qgbm9kZSB0byB0aGUgc2Vjb25kLiBPcHRpb25hbGx5IHNwZWNpZnkgdGhlIGlucHV0IGFuZCBvdXRwdXQgY2hhbm5lbHMuXG4gKiBAcGFyYW0gc3JjTm9kZSBUaGUgc291cmNlIG5vZGVcbiAqIEBwYXJhbSBkc3ROb2RlIFRoZSBkZXN0aW5hdGlvbiBub2RlXG4gKiBAcGFyYW0gb3V0cHV0TnVtYmVyIFRoZSBvdXRwdXQgY2hhbm5lbCBvZiB0aGUgc3JjTm9kZVxuICogQHBhcmFtIGlucHV0TnVtYmVyIFRoZSBpbnB1dCBjaGFubmVsIG9mIHRoZSBkc3ROb2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0KHNyY05vZGUsIGRzdE5vZGUsIG91dHB1dE51bWJlciA9IDAsIGlucHV0TnVtYmVyID0gMCkge1xuICAgIGFzc2VydChpc0RlZmluZWQoc3JjTm9kZSksIFwiQ2Fubm90IGNvbm5lY3QgZnJvbSB1bmRlZmluZWQgbm9kZVwiKTtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKGRzdE5vZGUpLCBcIkNhbm5vdCBjb25uZWN0IHRvIHVuZGVmaW5lZCBub2RlXCIpO1xuICAgIGlmIChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBpc0F1ZGlvTm9kZShkc3ROb2RlKSkge1xuICAgICAgICBhc3NlcnQoZHN0Tm9kZS5udW1iZXJPZklucHV0cyA+IDAsIFwiQ2Fubm90IGNvbm5lY3QgdG8gbm9kZSB3aXRoIG5vIGlucHV0c1wiKTtcbiAgICB9XG4gICAgYXNzZXJ0KHNyY05vZGUubnVtYmVyT2ZPdXRwdXRzID4gMCwgXCJDYW5ub3QgY29ubmVjdCBmcm9tIG5vZGUgd2l0aCBubyBvdXRwdXRzXCIpO1xuICAgIC8vIHJlc29sdmUgdGhlIGlucHV0IG9mIHRoZSBkc3ROb2RlXG4gICAgd2hpbGUgKChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBkc3ROb2RlIGluc3RhbmNlb2YgUGFyYW0pKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoZHN0Tm9kZS5pbnB1dCkpIHtcbiAgICAgICAgICAgIGRzdE5vZGUgPSBkc3ROb2RlLmlucHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHdoaWxlIChzcmNOb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHNyY05vZGUub3V0cHV0KSkge1xuICAgICAgICAgICAgc3JjTm9kZSA9IHNyY05vZGUub3V0cHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIG1ha2UgdGhlIGNvbm5lY3Rpb25cbiAgICBpZiAoaXNBdWRpb1BhcmFtKGRzdE5vZGUpKSB7XG4gICAgICAgIHNyY05vZGUuY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3JjTm9kZS5jb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgIH1cbn1cbi8qKlxuICogRGlzY29ubmVjdCBhIG5vZGUgZnJvbSBhbGwgbm9kZXMgb3Igb3B0aW9uYWxseSBpbmNsdWRlIGEgZGVzdGluYXRpb24gbm9kZSBhbmQgaW5wdXQvb3V0cHV0IGNoYW5uZWxzLlxuICogQHBhcmFtIHNyY05vZGUgVGhlIHNvdXJjZSBub2RlXG4gKiBAcGFyYW0gZHN0Tm9kZSBUaGUgZGVzdGluYXRpb24gbm9kZVxuICogQHBhcmFtIG91dHB1dE51bWJlciBUaGUgb3V0cHV0IGNoYW5uZWwgb2YgdGhlIHNyY05vZGVcbiAqIEBwYXJhbSBpbnB1dE51bWJlciBUaGUgaW5wdXQgY2hhbm5lbCBvZiB0aGUgZHN0Tm9kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzY29ubmVjdChzcmNOb2RlLCBkc3ROb2RlLCBvdXRwdXROdW1iZXIgPSAwLCBpbnB1dE51bWJlciA9IDApIHtcbiAgICAvLyByZXNvbHZlIHRoZSBkZXN0aW5hdGlvbiBub2RlXG4gICAgaWYgKGlzRGVmaW5lZChkc3ROb2RlKSkge1xuICAgICAgICB3aGlsZSAoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgIGRzdE5vZGUgPSBkc3ROb2RlLmlucHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHJlc29sdmUgdGhlIHNyYyBub2RlXG4gICAgd2hpbGUgKCEoaXNBdWRpb05vZGUoc3JjTm9kZSkpKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoc3JjTm9kZS5vdXRwdXQpKSB7XG4gICAgICAgICAgICBzcmNOb2RlID0gc3JjTm9kZS5vdXRwdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQXVkaW9QYXJhbShkc3ROb2RlKSkge1xuICAgICAgICBzcmNOb2RlLmRpc2Nvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNBdWRpb05vZGUoZHN0Tm9kZSkpIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvTm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogQSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBOYXRpdmUgV2ViIEF1ZGlvIEdhaW5Ob2RlLlxuICogVGhlIEdhaW5Ob2RlIGlzIGEgYmFzaWMgYnVpbGRpbmcgYmxvY2sgb2YgdGhlIFdlYiBBdWRpb1xuICogQVBJIGFuZCBpcyB1c2VmdWwgZm9yIHJvdXRpbmcgYXVkaW8gYW5kIGFkanVzdGluZyBnYWlucy5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGdhaW5Ob2RlID0gbmV3IFRvbmUuR2FpbigwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMzApLmNvbm5lY3QoZ2Fpbk5vZGUpLnN0YXJ0KCk7XG4gKiBcdGdhaW5Ob2RlLmdhaW4ucmFtcFRvKDEsIDAuMSk7XG4gKiBcdGdhaW5Ob2RlLmdhaW4ucmFtcFRvKDAsIDAuNCwgMC4yKTtcbiAqIH0sIDAuNywgMSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBHYWluIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhaW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJnYWluXCIsIFwidW5pdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYWluXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgd3JhcHBlZCBHYWluTm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgLy8gaW5wdXQgPSBvdXRwdXRcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR2Fpbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImdhaW5cIiwgXCJ1bml0c1wiXSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZ2Fpbk5vZGUuZ2FpbixcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImdhaW5cIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgZ2FpbjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImdhaW5cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYWluLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUsIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZmlyZS1hbmQtZm9yZ2V0IG5vZGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBPbmVTaG90U291cmNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlXG4gICAgICAgICAqIHNvdXJjZSBpcyBkb25lIHBsYXlpbmcuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uZW5kZWQgPSBub09wO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0YXJ0IHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0b3AgdGltZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpZCBvZiB0aGUgdGltZW91dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHB1YmxpYyBvdXRwdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgZ2FpbiBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUgPSB0aGlzLm91dHB1dDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0U3RhdGVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhcnRUaW1lICE9PSAtMSAmJlxuICAgICAgICAgICAgICAgIGNvbXB1dGVkVGltZSA+PSB0aGlzLl9zdGFydFRpbWUgJiZcbiAgICAgICAgICAgICAgICAodGhpcy5fc3RvcFRpbWUgPT09IC0xIHx8IGNvbXB1dGVkVGltZSA8PSB0aGlzLl9zdG9wVGltZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdGFydGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgICAgICB0aGlzLl9jdXJ2ZSA9IG9wdGlvbnMuY3VydmU7XG4gICAgICAgIHRoaXMub25lbmRlZCA9IG9wdGlvbnMub25lbmRlZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGN1cnZlOiBcImxpbmVhclwiLFxuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIG9uZW5kZWQ6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIF9zdGFydEdhaW4odGltZSwgZ2FpbiA9IDEpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSA9PT0gLTEsIFwiU291cmNlIGNhbm5vdCBiZSBzdGFydGVkIG1vcmUgdGhhbiBvbmNlXCIpO1xuICAgICAgICAvLyBhcHBseSBhIGZhZGUgaW4gZW52ZWxvcGVcbiAgICAgICAgY29uc3QgZmFkZUluVGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuX2ZhZGVJbik7XG4gICAgICAgIC8vIHJlY29yZCB0aGUgc3RhcnQgdGltZVxuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSB0aW1lICsgZmFkZUluVGltZTtcbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gTWF0aC5tYXgodGhpcy5fc3RhcnRUaW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgZW52ZWxvcGVcbiAgICAgICAgaWYgKGZhZGVJblRpbWUgPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShnYWluLCB0aW1lICsgZmFkZUluVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZShnYWluLCB0aW1lLCBmYWRlSW5UaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoZ2FpbiwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBub2RlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgc291cmNlXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcEdhaW4odGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgc291cmNlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgc291cmNlXG4gICAgICovXG4gICAgX3N0b3BHYWluKHRpbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSAhPT0gLTEsIFwiJ3N0YXJ0JyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgJ3N0b3AnXCIpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgdGhpcy5jYW5jZWxTdG9wKCk7XG4gICAgICAgIC8vIHRoZSBmYWRlT3V0IHRpbWVcbiAgICAgICAgY29uc3QgZmFkZU91dFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLl9mYWRlT3V0KTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIHN0b3AgY2FsbGJhY2tcbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKSArIGZhZGVPdXRUaW1lO1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IE1hdGgubWF4KHRoaXMuX3N0b3BUaW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICBpZiAoZmFkZU91dFRpbWUgPiAwKSB7XG4gICAgICAgICAgICAvLyBzdGFydCB0aGUgZmFkZSBvdXQgY3VydmUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvKDAsIGZhZGVPdXRUaW1lLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4udGFyZ2V0UmFtcFRvKDAsIGZhZGVPdXRUaW1lLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHN0b3AgYW55IG9uZ29pbmcgcmFtcHMsIGFuZCBzZXQgdGhlIHZhbHVlIHRvIDBcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vIGFsbG93IGFkZGl0aW9uYWwgdGltZSBmb3IgdGhlIGV4cG9uZW50aWFsIGN1cnZlIHRvIGZ1bGx5IGRlY2F5XG4gICAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGFpbCA9IHRoaXMuX2N1cnZlID09PSBcImV4cG9uZW50aWFsXCIgPyBmYWRlT3V0VGltZSAqIDIgOiAwO1xuICAgICAgICAgICAgdGhpcy5fc3RvcFNvdXJjZSh0aGlzLm5vdygpICsgYWRkaXRpb25hbFRhaWwpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCgpO1xuICAgICAgICB9LCB0aGlzLl9zdG9wVGltZSAtIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIG9uZW5kZWQgY2FsbGJhY2tcbiAgICAgKi9cbiAgICBfb25lbmRlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMub25lbmRlZCAhPT0gbm9PcCkge1xuICAgICAgICAgICAgdGhpcy5vbmVuZGVkKHRoaXMpO1xuICAgICAgICAgICAgLy8gb3ZlcndyaXRlIG9uZW5kZWQgdG8gbWFrZSBzdXJlIGl0IG9ubHkgaXMgY2FsbGVkIG9uY2VcbiAgICAgICAgICAgIHRoaXMub25lbmRlZCA9IG5vT3A7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIHdoZW4gaXQncyBlbmRlZCB0byBmcmVlIHVwIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24gb25seSBpbiB0aGUgb25saW5lIGNvbnRleHRcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3Bvc2VDYWxsYmFjayA9ICgpID0+IHRoaXMuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5yZXF1ZXN0SWRsZUNhbGxiYWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnJlcXVlc3RJZGxlQ2FsbGJhY2soZGlzcG9zZUNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZGlzcG9zZUNhbGxiYWNrLCAxMDAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGEgc2NoZWR1bGVkIHN0b3AgZXZlbnRcbiAgICAgKi9cbiAgICBjYW5jZWxTdG9wKCkge1xuICAgICAgICB0aGlzLmxvZyhcImNhbmNlbFN0b3BcIik7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgIT09IC0xLCBcIlNvdXJjZSBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBzdG9wIGVudmVsb3BlXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMuX3N0YXJ0VGltZSArIHRoaXMuc2FtcGxlVGltZSk7XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gLTE7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T25lU2hvdFNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lU2hvdFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvT25lU2hvdFNvdXJjZVwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIGZpcmUtYW5kLWZvcmdldCBDb25zdGFudFNvdXJjZS5cbiAqIEFkZHMgdGhlIGFiaWxpdHkgdG8gcmVzY2hlZHVsZSB0aGUgc3RvcCBtZXRob2QuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQ29uc3RhbnRTb3VyY2UgZXh0ZW5kcyBPbmVTaG90U291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUNvbnN0YW50U291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib2Zmc2V0XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUNvbnN0YW50U291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2lnbmFsIGdlbmVyYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQ29uc3RhbnRTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvZmZzZXRcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NvdXJjZSwgdGhpcy5fZ2Fpbk5vZGUpO1xuICAgICAgICB0aGlzLm9mZnNldCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fc291cmNlLm9mZnNldCxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgb2Zmc2V0OiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgc291cmNlXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydEdhaW4oY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5vZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQ29uc3RhbnRTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vY29yZS91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRvbmVDb25zdGFudFNvdXJjZSB9IGZyb20gXCIuL1RvbmVDb25zdGFudFNvdXJjZVwiO1xuLyoqXG4gKiBBIHNpZ25hbCBpcyBhbiBhdWRpby1yYXRlIHZhbHVlLiBUb25lLlNpZ25hbCBpcyBhIGNvcmUgY29tcG9uZW50IG9mIHRoZSBsaWJyYXJ5LlxuICogVW5saWtlIGEgbnVtYmVyLCBTaWduYWxzIGNhbiBiZSBzY2hlZHVsZWQgd2l0aCBzYW1wbGUtbGV2ZWwgYWNjdXJhY3kuIFRvbmUuU2lnbmFsXG4gKiBoYXMgYWxsIG9mIHRoZSBtZXRob2RzIGF2YWlsYWJsZSB0byBuYXRpdmUgV2ViIEF1ZGlvXG4gKiBbQXVkaW9QYXJhbV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtYXVkaW9wYXJhbS1pbnRlcmZhY2UpXG4gKiBhcyB3ZWxsIGFzIGFkZGl0aW9uYWwgY29udmVuaWVuY2VzLiBSZWFkIG1vcmUgYWJvdXQgd29ya2luZyB3aXRoIHNpZ25hbHNcbiAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9TaWduYWxzKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gYSBzY2hlZHVsZWFibGUgc2lnbmFsIHdoaWNoIGNhbiBiZSBjb25uZWN0ZWQgdG8gY29udHJvbCBhbiBBdWRpb1BhcmFtIG9yIGFub3RoZXIgU2lnbmFsXG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoe1xuICogXHR2YWx1ZTogXCJDNFwiLFxuICogXHR1bml0czogXCJmcmVxdWVuY3lcIlxuICogfSkuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAqIC8vIHRoZSBzY2hlZHVsZWQgcmFtcCBjb250cm9scyB0aGUgY29ubmVjdGVkIHNpZ25hbFxuICogc2lnbmFsLnJhbXBUbyhcIkMyXCIsIDQsIFwiKzAuNVwiKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25hbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2lnbmFsXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBvdmVycmlkZGVuIG9uIGNvbm5lY3Rpb24uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCIsIFwidW5pdHNcIl0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2NvbnN0YW50U291cmNlID0gbmV3IFRvbmVDb25zdGFudFNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5zdGFydCgwKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3BhcmFtID0gdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgLy8gc3RhcnQgaXQgb25seSB3aGVuIGNvbm5lY3RlZCB0byBzb21ldGhpbmdcbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQUJTVFJBQ1QgUEFSQU0gSU5URVJGQUNFXG4gICAgLy8ganVzdCBhIHByb3h5IGZvciB0aGUgQ29uc3RhbnRTb3VyY2VOb2RlJ3Mgb2Zmc2V0IEF1ZGlvUGFyYW1cbiAgICAvLyBhbGwgZG9jcyBhcmUgZ2VuZXJhdGVkIGZyb20gQWJzdHJhY3RQYXJhbS50c1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBzZXRSYW1wUG9pbnQodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRSYW1wUG9pbnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0udGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSwgcmFtcFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lLCByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ucmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0udmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgZ2V0IGNvbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5jb252ZXJ0O1xuICAgIH1cbiAgICBzZXQgY29udmVydChjb252ZXJ0KSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNvbnZlcnQgPSBjb252ZXJ0O1xuICAgIH1cbiAgICBnZXQgdW5pdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS51bml0cztcbiAgICB9XG4gICAgZ2V0IG92ZXJyaWRkZW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5vdmVycmlkZGVuO1xuICAgIH1cbiAgICBzZXQgb3ZlcnJpZGRlbihvdmVycmlkZGVuKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLm92ZXJyaWRkZW4gPSBvdmVycmlkZGVuO1xuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tYXhWYWx1ZTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWluVmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlZSBbW1BhcmFtLmFwcGx5XV0uXG4gICAgICovXG4gICAgYXBwbHkocGFyYW0pIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uYXBwbHkocGFyYW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIFdoZW4gY29ubmVjdGluZyBmcm9tIGEgc2lnbmFsLCBpdCdzIG5lY2Vzc2FyeSB0byB6ZXJvIG91dCB0aGUgbm9kZSBkZXN0aW5hdGlvblxuICogbm9kZSBpZiB0aGF0IG5vZGUgaXMgYWxzbyBhIHNpZ25hbC4gSWYgdGhlIGRlc3RpbmF0aW9uIGlzIG5vdCAwLCB0aGVuIHRoZSB2YWx1ZXNcbiAqIHdpbGwgYmUgc3VtbWVkLiBUaGlzIG1ldGhvZCBpbnN1cmVzIHRoYXQgdGhlIG91dHB1dCBvZiB0aGUgZGVzdGluYXRpb24gc2lnbmFsIHdpbGxcbiAqIGJlIHRoZSBzYW1lIGFzIHRoZSBzb3VyY2Ugc2lnbmFsLCBtYWtpbmcgdGhlIGRlc3RpbmF0aW9uIHNpZ25hbCBhIHBhc3MgdGhyb3VnaCBub2RlLlxuICogQHBhcmFtIHNpZ25hbCBUaGUgb3V0cHV0IHNpZ25hbCB0byBjb25uZWN0IGZyb21cbiAqIEBwYXJhbSBkZXN0aW5hdGlvbiB0aGUgZGVzdGluYXRpb24gdG8gY29ubmVjdCB0b1xuICogQHBhcmFtIG91dHB1dE51bSB0aGUgb3B0aW9uYWwgb3V0cHV0IG51bWJlclxuICogQHBhcmFtIGlucHV0TnVtIHRoZSBpbnB1dCBudW1iZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RTaWduYWwoc2lnbmFsLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSkge1xuICAgIGlmIChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIFBhcmFtIHx8IGlzQXVkaW9QYXJhbShkZXN0aW5hdGlvbikgfHxcbiAgICAgICAgKGRlc3RpbmF0aW9uIGluc3RhbmNlb2YgU2lnbmFsICYmIGRlc3RpbmF0aW9uLm92ZXJyaWRlKSkge1xuICAgICAgICAvLyBjYW5jZWwgY2hhbmdlc1xuICAgICAgICBkZXN0aW5hdGlvbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoMCk7XG4gICAgICAgIC8vIHJlc2V0IHRoZSB2YWx1ZVxuICAgICAgICBkZXN0aW5hdGlvbi5zZXRWYWx1ZUF0VGltZSgwLCAwKTtcbiAgICAgICAgLy8gbWFyayB0aGUgdmFsdWUgYXMgb3ZlcnJpZGRlblxuICAgICAgICBpZiAoZGVzdGluYXRpb24gaW5zdGFuY2VvZiBTaWduYWwpIHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uLm92ZXJyaWRkZW4gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbm5lY3Qoc2lnbmFsLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaWduYWwuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBBIFBhcmFtIGNsYXNzIGp1c3QgZm9yIGNvbXB1dGluZyB0aWNrcy4gU2ltaWxhciB0byB0aGUgW1tQYXJhbV1dIGNsYXNzLFxuICogYnV0IG9mZmVycyBjb252ZXJzaW9uIHRvIEJQTSB2YWx1ZXMgYXMgd2VsbCBhcyBhYmlsaXR5IHRvIGNvbXB1dGUgdGlja1xuICogZHVyYXRpb24gYW5kIGVsYXBzZWQgdGlja3NcbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tQYXJhbSBleHRlbmRzIFBhcmFtIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1BhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrUGFyYW1cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lbGluZSB3aGljaCB0cmFja3MgYWxsIG9mIHRoZSBhdXRvbWF0aW9ucy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBUaW1lbGluZShJbmZpbml0eSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW50ZXJuYWwgaG9sZGVyIGZvciB0aGUgbXVsdGlwbGllciB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbXVsdGlwbGllciA9IDE7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIC8vIHNldCB0aGUgbXVsdGlwbGllclxuICAgICAgICB0aGlzLl9tdWx0aXBsaWVyID0gb3B0aW9ucy5tdWx0aXBsaWVyO1xuICAgICAgICAvLyBjbGVhciB0aGUgdGlja3MgZnJvbSB0aGUgYmVnaW5uaW5nXG4gICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoMCk7XG4gICAgICAgIC8vIHNldCBhbiBpbml0aWFsIGV2ZW50XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGlja3M6IDAsXG4gICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuX2Zyb21UeXBlKG9wdGlvbnMudmFsdWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihQYXJhbS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdWx0aXBsaWVyOiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiaGVydHpcIixcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCB0aW1lLCBjb25zdGFudCkge1xuICAgICAgICAvLyBhcHByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBzdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG4gICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgxIC8gY29uc3RhbnQsIDEpKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gc2VnbWVudHM7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc2VnVGltZSA9IGNvbnN0YW50ICogaSArIHRpbWU7XG4gICAgICAgICAgICBjb25zdCByYW1wVmFsID0gdGhpcy5fZXhwb25lbnRpYWxBcHByb2FjaChwcmV2RXZlbnQudGltZSwgcHJldkV2ZW50LnZhbHVlLCBjb21wdXRlZFZhbHVlLCBjb25zdGFudCwgc2VnVGltZSk7XG4gICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShyYW1wVmFsKSwgc2VnVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBzdXBlci5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICBjb25zdCB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBldmVudC50aWNrcyA9IE1hdGgubWF4KHRpY2tzVW50aWxUaW1lLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICBjb25zdCB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBldmVudC50aWNrcyA9IE1hdGgubWF4KHRpY2tzVW50aWxUaW1lLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgLy8gYXByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVmFsID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBzdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG4gICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIC8vIGFwcHJveCAxMCBzZWdtZW50cyBwZXIgc2Vjb25kXG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgodGltZSAtIHByZXZFdmVudC50aW1lKSAqIDEwLCAxKSk7XG4gICAgICAgIGNvbnN0IHNlZ21lbnREdXIgPSAoKHRpbWUgLSBwcmV2RXZlbnQudGltZSkgLyBzZWdtZW50cyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBzZWdtZW50RHVyICogaSArIHByZXZFdmVudC50aW1lO1xuICAgICAgICAgICAgY29uc3QgcmFtcFZhbCA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUocHJldkV2ZW50LnRpbWUsIHByZXZFdmVudC52YWx1ZSwgdGltZSwgY29tcHV0ZWRWYWwsIHNlZ1RpbWUpO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUocmFtcFZhbCksIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcbiAgICAgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG4gICAgICogQHBhcmFtICBldmVudCBUaGUgdGltZSB0byBnZXQgdGhlIHRpY2sgY291bnQgYXRcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3Mgd2hpY2ggaGF2ZSBlbGFwc2VkIGF0IHRoZSB0aW1lIGdpdmVuIGFueSBhdXRvbWF0aW9ucy5cbiAgICAgKi9cbiAgICBfZ2V0VGlja3NVbnRpbEV2ZW50KGV2ZW50LCB0aW1lKSB7XG4gICAgICAgIGlmIChldmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgdGlja3M6IDAsXG4gICAgICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzVW5kZWYoZXZlbnQudGlja3MpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgZXZlbnQudGlja3MgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgZXZlbnQudGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsMCA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoZXZlbnQudGltZSkpO1xuICAgICAgICBsZXQgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSkpO1xuICAgICAgICAvLyBpZiBpdCdzIHJpZ2h0IG9uIHRoZSBsaW5lLCB0YWtlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgICBjb25zdCBvblRoZUxpbmVFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIGlmIChvblRoZUxpbmVFdmVudCAmJiBvblRoZUxpbmVFdmVudC50aW1lID09PSB0aW1lICYmIG9uVGhlTGluZUV2ZW50LnR5cGUgPT09IFwic2V0VmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSAtIHRoaXMuc2FtcGxlVGltZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwLjUgKiAodGltZSAtIGV2ZW50LnRpbWUpICogKHZhbDAgKyB2YWwxKSArIGV2ZW50LnRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcbiAgICAgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgdGljayBjb3VudCBhdFxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrcyB3aGljaCBoYXZlIGVsYXBzZWQgYXQgdGhlIHRpbWUgZ2l2ZW4gYW55IGF1dG9tYXRpb25zLlxuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgodGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KGV2ZW50LCBjb21wdXRlZFRpbWUpLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHRpbWUgb2YgdGhlIG51bWJlciBvZiB0aWNrcyBmcm9tIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtIHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY2FsY3VsYXRlXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgbmV4dCB0aWNrIGZyb21cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBvZiB0aGUgbnVtYmVyIG9mIHRpY2tzIGZyb20gdGhlIGdpdmVuIHRpbWUgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIGdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY3VycmVudFRpY2sgPSB0aGlzLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUaW1lT2ZUaWNrKGN1cnJlbnRUaWNrICsgdGlja3MpIC0gY29tcHV0ZWRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIHRpY2ssIHJldHVybnMgdGhlIHRpbWUgdGhhdCB0aWNrIG9jY3VycyBhdC5cbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIHRoYXQgdGhlIHRpY2sgb2NjdXJzLlxuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaykge1xuICAgICAgICBjb25zdCBiZWZvcmUgPSB0aGlzLl9ldmVudHMuZ2V0KHRpY2ssIFwidGlja3NcIik7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKHRpY2ssIFwidGlja3NcIik7XG4gICAgICAgIGlmIChiZWZvcmUgJiYgYmVmb3JlLnRpY2tzID09PSB0aWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gYmVmb3JlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlICYmIGFmdGVyICYmXG4gICAgICAgICAgICBhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIgJiZcbiAgICAgICAgICAgIGJlZm9yZS52YWx1ZSAhPT0gYWZ0ZXIudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbDAgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGJlZm9yZS50aW1lKSk7XG4gICAgICAgICAgICBjb25zdCB2YWwxID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShhZnRlci50aW1lKSk7XG4gICAgICAgICAgICBjb25zdCBkZWx0YSA9ICh2YWwxIC0gdmFsMCkgLyAoYWZ0ZXIudGltZSAtIGJlZm9yZS50aW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGsgPSBNYXRoLnNxcnQoTWF0aC5wb3codmFsMCwgMikgLSAyICogZGVsdGEgKiAoYmVmb3JlLnRpY2tzIC0gdGljaykpO1xuICAgICAgICAgICAgY29uc3Qgc29sMSA9ICgtdmFsMCArIGspIC8gZGVsdGE7XG4gICAgICAgICAgICBjb25zdCBzb2wyID0gKC12YWwwIC0gaykgLyBkZWx0YTtcbiAgICAgICAgICAgIHJldHVybiAoc29sMSA+IDAgPyBzb2wxIDogc29sMikgKyBiZWZvcmUudGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiZWZvcmUpIHtcbiAgICAgICAgICAgIGlmIChiZWZvcmUudmFsdWUgPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmVmb3JlLnRpbWUgKyAodGljayAtIGJlZm9yZS50aWNrcykgLyBiZWZvcmUudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGljayAvIHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHNvbWUgbnVtYmVyIG9mIHRpY2tzIHRoZWlyIHRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFjY291bnRpbmdcbiAgICAgKiBmb3IgYW55IGF1dG9tYXRpb24gY3VydmVzIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIG51bWJlciBvZiB0aWNrcyB0byBjb252ZXJ0IHRvIHNlY29uZHMuXG4gICAgICogQHBhcmFtICB3aGVuICBXaGVuIGFsb25nIHRoZSBhdXRvbWF0aW9uIHRpbWVsaW5lIHRvIGNvbnZlcnQgdGhlIHRpY2tzLlxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgb2YgdGhlIHRpY2tzLlxuICAgICAqL1xuICAgIHRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgd2hlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbnZlcnNlIG9mIFtbdGlja3NUb1RpbWVdXS4gQ29udmVydCBhIGR1cmF0aW9uIGluXG4gICAgICogc2Vjb25kcyB0byB0aGUgY29ycmVzcG9uZGluZyBudW1iZXIgb2YgdGlja3MgYWNjb3VudGluZyBmb3IgYW55XG4gICAgICogYXV0b21hdGlvbiBjdXJ2ZXMgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBUaGUgdGltZSBpbnRlcnZhbCB0byBjb252ZXJ0IHRvIHRpY2tzLlxuICAgICAqIEBwYXJhbSAgd2hlbiBXaGVuIGFsb25nIHRoZSBhdXRvbWF0aW9uIHRpbWVsaW5lIHRvIGNvbnZlcnQgdGhlIHRpY2tzLlxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIGluIHRpY2tzLlxuICAgICAqL1xuICAgIHRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBjb25zdCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICBjb25zdCBzdGFydFRpY2tzID0gdGhpcy5nZXRUaWNrc0F0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBlbmRUaWNrcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgIHJldHVybiBlbmRUaWNrcyAtIHN0YXJ0VGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgZnJvbSB0aGUgdHlwZSB3aGVuIHRoZSB1bml0IHZhbHVlIGlzIEJQTVxuICAgICAqL1xuICAgIF9mcm9tVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiYnBtXCIgJiYgdGhpcy5tdWx0aXBsaWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gMSAvICg2MCAvIHZhbCAvIHRoaXMubXVsdGlwbGllcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuX2Zyb21UeXBlKHZhbCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lhbCBjYXNlIG9mIHR5cGUgY29udmVyc2lvbiB3aGVyZSB0aGUgdW5pdHMgPT09IFwiYnBtXCJcbiAgICAgKi9cbiAgICBfdG9UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gXCJicG1cIiAmJiB0aGlzLm11bHRpcGxpZXIpIHtcbiAgICAgICAgICAgIHJldHVybiAodmFsIC8gdGhpcy5tdWx0aXBsaWVyKSAqIDYwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLl90b1R5cGUodmFsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIG11bHRpcGxpZXIgb24gdGhlIGJwbSB2YWx1ZS4gVXNlZnVsIGZvciBzZXR0aW5nIGEgUFBRIHJlbGF0aXZlIHRvIHRoZSBiYXNlIGZyZXF1ZW5jeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgbXVsdGlwbGllcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX211bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBtdWx0aXBsaWVyKG0pIHtcbiAgICAgICAgLy8gZ2V0IGFuZCByZXNldCB0aGUgY3VycmVudCB2YWx1ZSB3aXRoIHRoZSBuZXcgbXVsdGlwbGllclxuICAgICAgICAvLyBtaWdodCBiZSBuZWNlc3NhcnkgdG8gY2xlYXIgYWxsIHRoZSBwcmV2aW91cyB2YWx1ZXNcbiAgICAgICAgY29uc3QgY3VycmVudFZhbCA9IHRoaXMudmFsdWU7XG4gICAgICAgIHRoaXMuX211bHRpcGxpZXIgPSBtO1xuICAgICAgICB0aGlzLmNhbmNlbFNjaGVkdWxlZFZhbHVlcygwKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShjdXJyZW50VmFsLCAwKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrUGFyYW0uanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpY2tQYXJhbSB9IGZyb20gXCIuL1RpY2tQYXJhbVwiO1xuLyoqXG4gKiBUaWNrU2lnbmFsIGV4dGVuZHMgVG9uZS5TaWduYWwsIGJ1dCBhZGRzIHRoZSBjYXBhYmlsaXR5XG4gKiB0byBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBlbGFwc2VkIHRpY2tzLiBleHBvbmVudGlhbCBhbmQgdGFyZ2V0IGN1cnZlc1xuICogYXJlIGFwcHJveGltYXRlZCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wcy5cbiAqXG4gKiBUaGFuayB5b3UgQnJ1bm8gRGlhcywgSC4gU29maWEgUGludG8sIGFuZCBEYXZpZCBNLiBNYXRvcyxcbiAqIGZvciB5b3VyIFtXQUMgcGFwZXJdKGh0dHBzOi8vc21hcnRlY2guZ2F0ZWNoLmVkdS9iaXRzdHJlYW0vaGFuZGxlLzE4NTMvNTQ1ODgvV0FDMjAxNi00OS5wZGYpXG4gKiBkZXNjcmliaW5nIGludGVncmF0aW5nIHRpbWluZyBmdW5jdGlvbnMgZm9yIHRlbXBvIGNhbGN1bGF0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tTaWduYWwgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrU2lnbmFsXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fcGFyYW0gPSBuZXcgVGlja1BhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IG9wdGlvbnMuY29udmVydCxcbiAgICAgICAgICAgIG11bHRpcGxpZXI6IG9wdGlvbnMubXVsdGlwbGllcixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXVsdGlwbGllcjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS50aWNrc1RvVGltZSh0aWNrcywgd2hlbik7XG4gICAgfVxuICAgIHRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS50aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbik7XG4gICAgfVxuICAgIGdldFRpbWVPZlRpY2sodGljaykge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0VGltZU9mVGljayh0aWNrKTtcbiAgICB9XG4gICAgZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpO1xuICAgIH1cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtdWx0aXBsaWVyIG9uIHRoZSBicG0gdmFsdWUuIFVzZWZ1bCBmb3Igc2V0dGluZyBhIFBQUSByZWxhdGl2ZSB0byB0aGUgYmFzZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IG11bHRpcGxpZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgbXVsdGlwbGllcihtKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLm11bHRpcGxpZXIgPSBtO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja1NpZ25hbC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUaWNrU2lnbmFsIH0gZnJvbSBcIi4vVGlja1NpZ25hbFwiO1xuaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi4vdXRpbC9NYXRoXCI7XG4vKipcbiAqIFVzZXMgW1RpY2tTaWduYWxdKFRpY2tTaWduYWwpIHRvIHRyYWNrIGVsYXBzZWQgdGlja3Mgd2l0aCBjb21wbGV4IGF1dG9tYXRpb24gY3VydmVzLlxuICovXG5leHBvcnQgY2xhc3MgVGlja1NvdXJjZSBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrU291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3RhdGUgdGltZWxpbmVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvZmZzZXQgdmFsdWVzIG9mIHRoZSB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGlja09mZnNldCA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRpY2tTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHN0YXRlXG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCAwKTtcbiAgICAgICAgLy8gYWRkIHRoZSBmaXJzdCBldmVudFxuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKDAsIDApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgIH0sIFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBjbG9jayBhdCB0aGUgZ2l2ZW4gdGltZS4gT3B0aW9uYWxseSBwYXNzIGluIGFuIG9mZnNldFxuICAgICAqIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG51bWJlciBvZiB0aWNrcyB0byBzdGFydCB0aGUgc291cmNlIGF0XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChvZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZShvZmZzZXQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGNsb2NrLiBTdG9wcGluZyB0aGUgY2xvY2sgcmVzZXRzIHRoZSB0aWNrIGNvdW50ZXIgdG8gMC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQudGltZSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbChldmVudC50aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKDAsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwicGF1c2VkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBzdGFydC9zdG9wL3BhdXNlIGFuZCBzZXRUaWNrQXRUaW1lIGV2ZW50cyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0byBjbGVhciB0aGUgZXZlbnRzIGFmdGVyXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBlbGFwc2VkIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrc1xuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgLy8gdGhpcyBldmVudCBhbGxvd3MgZm9yRWFjaEJldHdlZW4gdG8gaXRlcmF0ZSB1bnRpbCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgIGNvbnN0IHRtcEV2ZW50ID0geyBzdGF0ZTogXCJwYXVzZWRcIiwgdGltZTogY29tcHV0ZWRUaW1lIH07XG4gICAgICAgIHRoaXMuX3N0YXRlLmFkZCh0bXBFdmVudCk7XG4gICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIHByZXZpb3VzIG9mZnNldCBldmVudFxuICAgICAgICBsZXQgbGFzdFN0YXRlID0gc3RvcEV2ZW50O1xuICAgICAgICBsZXQgZWxhcHNlZFRpY2tzID0gMDtcbiAgICAgICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGFsbCB0aGUgZXZlbnRzIHNpbmNlIHRoZSBsYXN0IHN0b3BcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RvcEV2ZW50LnRpbWUsIGNvbXB1dGVkVGltZSArIHRoaXMuc2FtcGxlVGltZSwgZSA9PiB7XG4gICAgICAgICAgICBsZXQgcGVyaW9kU3RhcnRUaW1lID0gbGFzdFN0YXRlLnRpbWU7XG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBvZmZzZXQgZXZlbnQgaW4gdGhpcyBwZXJpb2QgdXNlIHRoYXRcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEV2ZW50ID0gdGhpcy5fdGlja09mZnNldC5nZXQoZS50aW1lKTtcbiAgICAgICAgICAgIGlmIChvZmZzZXRFdmVudCAmJiBvZmZzZXRFdmVudC50aW1lID49IGxhc3RTdGF0ZS50aW1lKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzID0gb2Zmc2V0RXZlbnQudGlja3M7XG4gICAgICAgICAgICAgICAgcGVyaW9kU3RhcnRUaW1lID0gb2Zmc2V0RXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGUuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzICs9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKGUudGltZSkgLSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShwZXJpb2RTdGFydFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlID0gZTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG4gICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgdGlja3NcbiAgICAgICAgcmV0dXJuIGVsYXBzZWRUaWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiB0aW1lcyB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuIFN0YXJ0cyBjb3VudGluZyBhdCAwXG4gICAgICogYW5kIGluY3JlbWVudHMgYWZ0ZXIgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBSZXR1cm5zIC0xIHdoZW4gc3RvcHBlZC5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRpY2tzQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHQsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaW5jZSB0aWNrcz0wIHRoYXQgdGhlIFRpY2tTb3VyY2UgaGFzIGJlZW4gcnVubmluZy4gQWNjb3VudHNcbiAgICAgKiBmb3IgdGVtcG8gY3VydmVzXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNlY29uZHNBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmZyZXF1ZW5jeS50aW1lVG9UaWNrcyhzLCBub3cpO1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHRpY2tzLCBub3cpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShcInN0b3BwZWRcIiwgdGltZSk7XG4gICAgICAgIC8vIHRoaXMgZXZlbnQgYWxsb3dzIGZvckVhY2hCZXR3ZWVuIHRvIGl0ZXJhdGUgdW50aWwgdGhlIGN1cnJlbnQgdGltZVxuICAgICAgICBjb25zdCB0bXBFdmVudCA9IHsgc3RhdGU6IFwicGF1c2VkXCIsIHRpbWUgfTtcbiAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHRtcEV2ZW50KTtcbiAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGUgcHJldmlvdXMgb2Zmc2V0IGV2ZW50XG4gICAgICAgIGxldCBsYXN0U3RhdGUgPSBzdG9wRXZlbnQ7XG4gICAgICAgIGxldCBlbGFwc2VkU2Vjb25kcyA9IDA7XG4gICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCBzdG9wXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0b3BFdmVudC50aW1lLCB0aW1lICsgdGhpcy5zYW1wbGVUaW1lLCBlID0+IHtcbiAgICAgICAgICAgIGxldCBwZXJpb2RTdGFydFRpbWUgPSBsYXN0U3RhdGUudGltZTtcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIG9mZnNldCBldmVudCBpbiB0aGlzIHBlcmlvZCB1c2UgdGhhdFxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0RXZlbnQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChlLnRpbWUpO1xuICAgICAgICAgICAgaWYgKG9mZnNldEV2ZW50ICYmIG9mZnNldEV2ZW50LnRpbWUgPj0gbGFzdFN0YXRlLnRpbWUpIHtcbiAgICAgICAgICAgICAgICBlbGFwc2VkU2Vjb25kcyA9IG9mZnNldEV2ZW50LnNlY29uZHM7XG4gICAgICAgICAgICAgICAgcGVyaW9kU3RhcnRUaW1lID0gb2Zmc2V0RXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGUuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFNlY29uZHMgKz0gZS50aW1lIC0gcGVyaW9kU3RhcnRUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlID0gZTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG4gICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgdGlja3NcbiAgICAgICAgcmV0dXJuIGVsYXBzZWRTZWNvbmRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICovXG4gICAgc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbCh0aW1lKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5hZGQoe1xuICAgICAgICAgICAgc2Vjb25kczogdGhpcy5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSxcbiAgICAgICAgICAgIHRpY2tzLFxuICAgICAgICAgICAgdGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRTdGF0ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcbiAgICAgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuICAgICAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLlxuICAgICAqIEBwYXJhbSAgdGljayBUaGUgdGljayBudW1iZXIuXG4gICAgICogQHBhcmFtICBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGUgdGlja1xuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlID0gdGhpcy5ub3coKSkge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChiZWZvcmUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXRlLmdldChiZWZvcmUpO1xuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBNYXRoLm1heChvZmZzZXQudGltZSwgZXZlbnQudGltZSk7XG4gICAgICAgIGNvbnN0IGFic29sdXRlVGlja3MgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShzdGFydFRpbWUpICsgdGljayAtIG9mZnNldC50aWNrcztcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soYWJzb2x1dGVUaWNrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2sgZXZlbnQgYXQgYWxsIHNjaGVkdWxlZCB0aWNrcyBiZXR3ZWVuIHRoZVxuICAgICAqIHN0YXJ0IHRpbWUgYW5kIHRoZSBlbmQgdGltZVxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lICBUaGUgYmVnaW5uaW5nIG9mIHRoZSBzZWFyY2ggcmFuZ2VcbiAgICAgKiBAcGFyYW0gIGVuZFRpbWUgICAgVGhlIGVuZCBvZiB0aGUgc2VhcmNoIHJhbmdlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBlYWNoIHRpY2tcbiAgICAgKi9cbiAgICBmb3JFYWNoVGlja0JldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBvbmx5IGl0ZXJhdGUgdGhyb3VnaCB0aGUgc2VjdGlvbnMgd2hlcmUgaXQgaXMgXCJzdGFydGVkXCJcbiAgICAgICAgbGV0IGxhc3RTdGF0ZUV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50ICYmIGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBldmVudC5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvckVhY2hUaWNrQmV0d2VlbihNYXRoLm1heChsYXN0U3RhdGVFdmVudC50aW1lLCBzdGFydFRpbWUpLCBldmVudC50aW1lIC0gdGhpcy5zYW1wbGVUaW1lLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U3RhdGVFdmVudCA9IGV2ZW50O1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGVycm9yID0gbnVsbDtcbiAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50ICYmIGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgY29uc3QgbWF4U3RhcnRUaW1lID0gTWF0aC5tYXgobGFzdFN0YXRlRXZlbnQudGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgIC8vIGZpZ3VyZSBvdXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZnJlcXVlbmN5IHRpY2tzIGFuZCB0aGVcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGlja3MgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShtYXhTdGFydFRpbWUpO1xuICAgICAgICAgICAgY29uc3QgdGlja3NBdFN0YXJ0ID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUobGFzdFN0YXRlRXZlbnQudGltZSk7XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gc3RhcnRUaWNrcyAtIHRpY2tzQXRTdGFydDtcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSBNYXRoLmNlaWwoZGlmZikgLSBkaWZmO1xuICAgICAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCBmbG9hdGluZyBwb2ludCBpc3N1ZXNcbiAgICAgICAgICAgIG9mZnNldCA9IEVRKG9mZnNldCwgMSkgPyAwIDogb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IG5leHRUaWNrVGltZSA9IHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soc3RhcnRUaWNrcyArIG9mZnNldCk7XG4gICAgICAgICAgICB3aGlsZSAobmV4dFRpY2tUaW1lIDwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5leHRUaWNrVGltZSwgTWF0aC5yb3VuZCh0aGlzLmdldFRpY2tzQXRUaW1lKG5leHRUaWNrVGltZSkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV4dFRpY2tUaW1lICs9IHRoaXMuZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcygxLCBuZXh0VGlja1RpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBUaWNrU291cmNlIH0gZnJvbSBcIi4vVGlja1NvdXJjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0Q29udGV4dFJ1bm5pbmcgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBBIHNhbXBsZSBhY2N1cmF0ZSBjbG9jayB3aGljaCBwcm92aWRlcyBhIGNhbGxiYWNrIGF0IHRoZSBnaXZlbiByYXRlLlxuICogV2hpbGUgdGhlIGNhbGxiYWNrIGlzIG5vdCBzYW1wbGUtYWNjdXJhdGUgKGl0IGlzIHN0aWxsIHN1c2NlcHRpYmxlIHRvXG4gKiBsb29zZSBKUyB0aW1pbmcpLCB0aGUgdGltZSBwYXNzZWQgaW4gYXMgdGhlIGFyZ3VtZW50IHRvIHRoZSBjYWxsYmFja1xuICogaXMgcHJlY2lzZS4gRm9yIG1vc3QgYXBwbGljYXRpb25zLCBpdCBpcyBiZXR0ZXIgdG8gdXNlIFRvbmUuVHJhbnNwb3J0XG4gKiBpbnN0ZWFkIG9mIHRoZSBDbG9jayBieSBpdHNlbGYgc2luY2UgeW91IGNhbiBzeW5jaHJvbml6ZSBtdWx0aXBsZSBjYWxsYmFja3MuXG4gKiBAZXhhbXBsZVxuICogLy8gdGhlIGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZCBhcHByb3hpbWF0ZWx5IG9uY2UgYSBzZWNvbmRcbiAqIC8vIGFuZCB3aWxsIHByaW50IHRoZSB0aW1lIGV4YWN0bHkgb25jZSBhIHNlY29uZCBhcGFydC5cbiAqIGNvbnN0IGNsb2NrID0gbmV3IFRvbmUuQ2xvY2sodGltZSA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogfSwgMSk7XG4gKiBjbG9jay5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIENsb2NrIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2xvY2suZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNsb2NrXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIGF0IHRoZSBzY2hlZHVsZWQgdGljay5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBub09wO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxhc3QgdGltZSB0aGUgbG9vcCBjYWxsYmFjayB3YXMgaW52b2tlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBwbGF5YmFjayBzdGF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb250ZXh0IGJvdW5kIHJlZmVyZW5jZSB0byB0aGUgX2xvb3AgbWV0aG9kXG4gICAgICAgICAqIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIHJlbW92ZSB0aGUgZXZlbnQgaW4gdGhlIGVuZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kTG9vcCA9IHRoaXMuX2xvb3AuYmluZCh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENsb2NrLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZSA9IG5ldyBUaWNrU291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSAwO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX3RpY2tTb3VyY2UuZnJlcXVlbmN5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgLy8gYWRkIGFuIGluaXRpYWwgc3RhdGVcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIDApO1xuICAgICAgICAvLyBiaW5kIGEgY2FsbGJhY2sgdG8gdGhlIHdvcmtlciB0aHJlYWRcbiAgICAgICAgdGhpcy5jb250ZXh0Lm9uKFwidGlja1wiLCB0aGlzLl9ib3VuZExvb3ApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiIG9yIFwicGF1c2VkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBjbG9jayBhdCB0aGUgZ2l2ZW4gdGltZS4gT3B0aW9uYWxseSBwYXNzIGluIGFuIG9mZnNldFxuICAgICAqIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSBvZmZzZXQgIFdoZXJlIHRoZSB0aWNrIGNvdW50ZXIgc3RhcnRzIGNvdW50aW5nIGZyb20uXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgY29udGV4dCBpcyBydW5uaW5nXG4gICAgICAgIGFzc2VydENvbnRleHRSdW5uaW5nKHRoaXMuY29udGV4dCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBsb29wXG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChjb21wdXRlZFRpbWUgPCB0aGlzLl9sYXN0VXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lLCBvZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBjbG9jay4gU3RvcHBpbmcgdGhlIGNsb2NrIHJlc2V0cyB0aGUgdGljayBjb3VudGVyIHRvIDAuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjbG9jayA9IG5ldyBUb25lLkNsb2NrKHRpbWUgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gICAgICogfSwgMSk7XG4gICAgICogY2xvY2suc3RhcnQoKTtcbiAgICAgKiAvLyBzdG9wIHRoZSBjbG9jayBhZnRlciAxMCBzZWNvbmRzXG4gICAgICogY2xvY2suc3RvcChcIisxMFwiKTtcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwicGF1c2VkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLnBhdXNlKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInBhdXNlXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBTdGFydHMgY291bnRpbmcgYXQgMFxuICAgICAqIGFuZCBpbmNyZW1lbnRzIGFmdGVyIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy5nZXRUaWNrc0F0VGltZSh0aGlzLm5vdygpKSk7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UudGlja3MgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaW5jZSB0aWNrcz0wIHRoYXQgdGhlIENsb2NrIGhhcyBiZWVuIHJ1bm5pbmcuIEFjY291bnRzIGZvciB0ZW1wbyBjdXJ2ZXNcbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2Uuc2Vjb25kcztcbiAgICB9XG4gICAgc2V0IHNlY29uZHMocykge1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnNlY29uZHMgPSBzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRTZWNvbmRzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICovXG4gICAgc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zZXRUaWNrc0F0VGltZSh0aWNrcywgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcbiAgICAgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuICAgICAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLlxuICAgICAqIEBwYXJhbSAgdGljayBUaGUgdGljayBudW1iZXIuXG4gICAgICogQHBhcmFtICBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGUgdGlja1xuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlID0gdGhpcy5ub3coKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgdGljayB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIG5leHQgdGlja1xuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSB0aWNrIG51bWJlci5cbiAgICAgKi9cbiAgICBuZXh0VGlja1RpbWUob2Zmc2V0LCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBjb25zdCBjdXJyZW50VGljayA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGltZU9mVGljayhjdXJyZW50VGljayArIG9mZnNldCwgY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNjaGVkdWxpbmcgbG9vcC5cbiAgICAgKi9cbiAgICBfbG9vcCgpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gdGhpcy5fbGFzdFVwZGF0ZTtcbiAgICAgICAgY29uc3QgZW5kVGltZSA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSBlbmRUaW1lO1xuICAgICAgICB0aGlzLmxvZyhcImxvb3BcIiwgc3RhcnRUaW1lLCBlbmRUaW1lKTtcbiAgICAgICAgaWYgKHN0YXJ0VGltZSAhPT0gZW5kVGltZSkge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXRlIGNoYW5nZSBldmVudHNcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZSA9PiB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlLnN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzdGFydGVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLl90aWNrU291cmNlLmdldFRpY2tzQXRUaW1lKGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCBlLnRpbWUsIG9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0b3BwZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLnRpbWUgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdXNlZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwicGF1c2VcIiwgZS50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gdGhlIHRpY2sgY2FsbGJhY2tzXG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLmZvckVhY2hUaWNrQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsICh0aW1lLCB0aWNrcykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGlja3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygpO1xuICAgICAqIGNsb2NrLnN0YXJ0KFwiKzAuMVwiKTtcbiAgICAgKiBjbG9jay5nZXRTdGF0ZUF0VGltZShcIiswLjFcIik7IC8vIHJldHVybnMgXCJzdGFydGVkXCJcbiAgICAgKi9cbiAgICBnZXRTdGF0ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC5vZmYoXCJ0aWNrXCIsIHRoaXMuX2JvdW5kTG9vcCk7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbkVtaXR0ZXIubWl4aW4oQ2xvY2spO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2xvY2suanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIFdlYiBBdWRpbydzIG5hdGl2ZSBbRGVsYXlOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1kZWxheW5vZGUtaW50ZXJmYWNlKS5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGRlbGF5ID0gbmV3IFRvbmUuRGVsYXkoMC4xKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIGNvbm5lY3QgdGhlIHNpZ25hbCB0byBib3RoIHRoZSBkZWxheSBhbmQgdGhlIGRlc3RpbmF0aW9uXG4gKiBcdGNvbnN0IHB1bHNlID0gbmV3IFRvbmUuUHVsc2VPc2NpbGxhdG9yKCkuY29ubmVjdChkZWxheSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBzdGFydCBhbmQgc3RvcCB0aGUgcHVsc2VcbiAqIFx0cHVsc2Uuc3RhcnQoMCkuc3RvcCgwLjAxKTtcbiAqIH0sIDAuNSwgMSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBEZWxheSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcIm1heERlbGF5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGVsYXlcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwibWF4RGVsYXlcIl0pO1xuICAgICAgICBjb25zdCBtYXhEZWxheUluU2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKG9wdGlvbnMubWF4RGVsYXkpO1xuICAgICAgICB0aGlzLl9tYXhEZWxheSA9IE1hdGgubWF4KG1heERlbGF5SW5TZWNvbmRzLCB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLmRlbGF5VGltZSkpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlRGVsYXkobWF4RGVsYXlJblNlY29uZHMpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIG1pblZhbHVlOiAwLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gZGVsYXkgdGltZS4gVGhpcyBjYW5ub3QgYmUgY2hhbmdlZCBhZnRlclxuICAgICAqIHRoZSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IuXG4gICAgICovXG4gICAgZ2V0IG1heERlbGF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWF4RGVsYXk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGdldENvbnRleHQsIHNldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuL09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbi8qKlxuICogR2VuZXJhdGUgYSBidWZmZXIgYnkgcmVuZGVyaW5nIGFsbCBvZiB0aGUgVG9uZS5qcyBjb2RlIHdpdGhpbiB0aGUgY2FsbGJhY2sgdXNpbmcgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gKiBUaGUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpcyBjYXBhYmxlIG9mIHJlbmRlcmluZyBtdWNoIGZhc3RlciB0aGFuIHJlYWwgdGltZSBpbiBtYW55IGNhc2VzLlxuICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGFsc28gcGFzc2VzIGluIGFuIG9mZmxpbmUgaW5zdGFuY2Ugb2YgW1tDb250ZXh0XV0gd2hpY2ggY2FuIGJlIHVzZWRcbiAqIHRvIHNjaGVkdWxlIGV2ZW50cyBhbG9uZyB0aGUgVHJhbnNwb3J0LlxuICogQHBhcmFtICBjYWxsYmFjayAgQWxsIFRvbmUuanMgbm9kZXMgd2hpY2ggYXJlIGNyZWF0ZWQgYW5kIHNjaGVkdWxlZCB3aXRoaW4gdGhpcyBjYWxsYmFjayBhcmUgcmVjb3JkZWQgaW50byB0aGUgb3V0cHV0IEJ1ZmZlci5cbiAqIEBwYXJhbSAgZHVyYXRpb24gICAgIHRoZSBhbW91bnQgb2YgdGltZSB0byByZWNvcmQgZm9yLlxuICogQHJldHVybiAgVGhlIHByb21pc2Ugd2hpY2ggaXMgaW52b2tlZCB3aXRoIHRoZSBUb25lQXVkaW9CdWZmZXIgb2YgdGhlIHJlY29yZGVkIG91dHB1dC5cbiAqIEBleGFtcGxlXG4gKiAvLyByZW5kZXIgMiBzZWNvbmRzIG9mIHRoZSBvc2NpbGxhdG9yXG4gKiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHQvLyBvbmx5IG5vZGVzIGNyZWF0ZWQgaW4gdGhpcyBjYWxsYmFjayB3aWxsIGJlIHJlY29yZGVkXG4gKiBcdGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KDApO1xuICogfSwgMikudGhlbigoYnVmZmVyKSA9PiB7XG4gKiBcdC8vIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlcik7XG4gKiB9KTtcbiAqIEBleGFtcGxlXG4gKiAvLyBjYW4gYWxzbyBzY2hlZHVsZSBldmVudHMgYWxvbmcgdGhlIFRyYW5zcG9ydFxuICogLy8gdXNpbmcgdGhlIHBhc3NlZCBpbiBPZmZsaW5lIFRyYW5zcG9ydFxuICogVG9uZS5PZmZsaW5lKCh7IHRyYW5zcG9ydCB9KSA9PiB7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdHRyYW5zcG9ydC5zY2hlZHVsZSh0aW1lID0+IHtcbiAqIFx0XHRvc2Muc3RhcnQodGltZSkuc3RvcCh0aW1lICsgMC4xKTtcbiAqIFx0fSwgMSk7XG4gKiBcdC8vIG1ha2Ugc3VyZSB0byBzdGFydCB0aGUgdHJhbnNwb3J0XG4gKiBcdHRyYW5zcG9ydC5zdGFydCgwLjIpO1xuICogfSwgNCkudGhlbigoYnVmZmVyKSA9PiB7XG4gKiBcdC8vIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlcik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPZmZsaW5lKGNhbGxiYWNrLCBkdXJhdGlvbiwgY2hhbm5lbHMgPSAyLCBzYW1wbGVSYXRlID0gZ2V0Q29udGV4dCgpLnNhbXBsZVJhdGUpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAvLyBzZXQgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHQgYmFzZWQgb24gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgICAgICBjb25zdCBvcmlnaW5hbENvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoY2hhbm5lbHMsIGR1cmF0aW9uLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFjay9zY2hlZHVsaW5nXG4gICAgICAgIHlpZWxkIGNhbGxiYWNrKGNvbnRleHQpO1xuICAgICAgICAvLyB0aGVuIHJlbmRlciB0aGUgYXVkaW9cbiAgICAgICAgY29uc3QgYnVmZmVyUHJvbWlzZSA9IGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgb3JpZ2luYWwgQXVkaW9Db250ZXh0XG4gICAgICAgIHNldENvbnRleHQob3JpZ2luYWxDb250ZXh0KTtcbiAgICAgICAgLy8gYXdhaXQgdGhlIHJlbmRlcmluZ1xuICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBidWZmZXJQcm9taXNlO1xuICAgICAgICAvLyByZXR1cm4gdGhlIGF1ZGlvXG4gICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKGJ1ZmZlcik7XG4gICAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PZmZsaW5lLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQSBkYXRhIHN0cnVjdHVyZSBmb3IgaG9sZGluZyBtdWx0aXBsZSBidWZmZXJzIGluIGEgTWFwLWxpa2UgZGF0YXN0cnVjdHVyZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGlhbm9TYW1wbGVzID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVycyh7XG4gKiBcdEExOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMS5tcDNcIixcbiAqIFx0QTI6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0EyLm1wM1wiLFxuICogfSwgKCkgPT4ge1xuICogXHRjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIHBsYXkgb25lIG9mIHRoZSBzYW1wbGVzIHdoZW4gdGhleSBhbGwgbG9hZFxuICogXHRwbGF5ZXIuYnVmZmVyID0gcGlhbm9TYW1wbGVzLmdldChcIkEyXCIpO1xuICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAqIH0pO1xuICogQGV4YW1wbGVcbiAqIC8vIFRvIHBhc3MgaW4gYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGluIHRoZSBzZWNvbmQgcGFyYW1ldGVyXG4gKiBjb25zdCBidWZmZXJzID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVycyh7XG4gKiBcdCB1cmxzOiB7XG4gKiBcdFx0IEExOiBcIkExLm1wM1wiLFxuICogXHRcdCBBMjogXCJBMi5tcDNcIixcbiAqIFx0IH0sXG4gKiBcdCBvbmxvYWQ6ICgpID0+IGNvbnNvbGUubG9nKFwibG9hZGVkXCIpLFxuICogXHQgYmFzZVVybDogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vXCJcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb0J1ZmZlcnMgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9CdWZmZXJzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGJ1ZmZlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgbG9hZGVkIGJ1ZmZlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudCA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQXVkaW9CdWZmZXJzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgdGhpcy5iYXNlVXJsID0gb3B0aW9ucy5iYXNlVXJsO1xuICAgICAgICAvLyBhZGQgZWFjaCBvbmVcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucy51cmxzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50Kys7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBvcHRpb25zLnVybHNbbmFtZV07XG4gICAgICAgICAgICB0aGlzLmFkZChuYW1lLCB1cmwsIHRoaXMuX2J1ZmZlckxvYWRlZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSwgb3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRydWUgaWYgdGhlIGJ1ZmZlcnMgb2JqZWN0IGhhcyBhIGJ1ZmZlciBieSB0aGF0IG5hbWUuXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUga2V5IG9yIGluZGV4IG9mIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuaGFzKG5hbWUudG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIGJ1ZmZlciBieSBuYW1lLiBJZiBhbiBhcnJheSB3YXMgbG9hZGVkLFxuICAgICAqIHRoZW4gdXNlIHRoZSBhcnJheSBpbmRleC5cbiAgICAgKiBAcGFyYW0gIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBnZXQobmFtZSkge1xuICAgICAgICBhc3NlcnQodGhpcy5oYXMobmFtZSksIGBUb25lQXVkaW9CdWZmZXJzIGhhcyBubyBidWZmZXIgbmFtZWQ6ICR7bmFtZX1gKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuZ2V0KG5hbWUudG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgYnVmZmVyIHdhcyBsb2FkZWQuIGRlY3JlbWVudCB0aGUgY291bnRlci5cbiAgICAgKi9cbiAgICBfYnVmZmVyTG9hZGVkKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudC0tO1xuICAgICAgICBpZiAodGhpcy5fbG9hZGluZ0NvdW50ID09PSAwICYmIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXJzIGFyZSBsb2FkZWQgb3Igbm90XG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5fYnVmZmVycykuZXZlcnkoKFtfLCBidWZmZXJdKSA9PiBidWZmZXIubG9hZGVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYnVmZmVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgQnVmZmVyc1xuICAgICAqIEBwYXJhbSAgbmFtZSAgICAgIEEgdW5pcXVlIG5hbWUgdG8gZ2l2ZSB0aGUgYnVmZmVyXG4gICAgICogQHBhcmFtICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZlciwgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKiBAcGFyYW0gIG9uZXJyb3IgIEludm9rZWQgaWYgdGhlIGJ1ZmZlciBjYW4ndCBiZSBsb2FkZWRcbiAgICAgKi9cbiAgICBhZGQobmFtZSwgdXJsLCBjYWxsYmFjayA9IG5vT3AsIG9uZXJyb3IgPSBub09wKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh1cmwpKSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLnNldChuYW1lLnRvU3RyaW5nKCksIG5ldyBUb25lQXVkaW9CdWZmZXIodGhpcy5iYXNlVXJsICsgdXJsLCBjYWxsYmFjaywgb25lcnJvcikpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5zZXQobmFtZS50b1N0cmluZygpLCBuZXcgVG9uZUF1ZGlvQnVmZmVyKHVybCwgY2FsbGJhY2ssIG9uZXJyb3IpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmZvckVhY2goYnVmZmVyID0+IGJ1ZmZlci5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb0J1ZmZlcnMuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGZ0b20sIG10b2YgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi9GcmVxdWVuY3lcIjtcbi8qKlxuICogTWlkaSBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIE1pZGkgY2FuIGJlIGNvbnN0cnVjdGVkIHdpdGggb3Igd2l0aG91dCB0aGUgYG5ld2Aga2V5d29yZC4gTWlkaSBjYW4gYmUgcGFzc2VkXG4gKiBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZGlDbGFzcyBleHRlbmRzIEZyZXF1ZW5jeUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRpQ2xhc3NcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcIm1pZGlcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBmcmVxdWVuY3kgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl90aWNrc1RvVW5pdHModGlja3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9iZWF0c1RvVW5pdHMoYmVhdHMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaSg2MCkudG9NaWRpKCk7IC8vIDYwXG4gICAgICovXG4gICAgdG9NaWRpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5NaWRpKDYwKS50b0ZyZXF1ZW5jeSgpOyAvLyAyNjEuNjI1NTY1MzAwNTk4NlxuICAgICAqL1xuICAgIHRvRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gbXRvZih0aGlzLnRvTWlkaSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJhbnNwb3NlcyB0aGUgZnJlcXVlbmN5IGJ5IHRoZSBnaXZlbiBudW1iZXIgb2Ygc2VtaXRvbmVzLlxuICAgICAqIEByZXR1cm4gQSBuZXcgdHJhbnNwb3NlZCBNaWRpQ2xhc3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaShcIkE0XCIpLnRyYW5zcG9zZSgzKTsgLy8gXCJDNVwiXG4gICAgICovXG4gICAgdHJhbnNwb3NlKGludGVydmFsKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy50b01pZGkoKSArIGludGVydmFsKTtcbiAgICB9XG59XG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIGEgRnJlcXVlbmN5Q2xhc3Mgb2JqZWN0LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE1pZGkodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBNaWRpQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkaS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4vVHJhbnNwb3J0VGltZVwiO1xuLyoqXG4gKiBUaWNrcyBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIFRpY2tzIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIG9yIHdpdGhvdXQgdGhlIGBuZXdgIGtleXdvcmQuIFRpY2tzIGNhbiBiZSBwYXNzZWRcbiAqIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdCA9IFRvbmUuVGlja3MoXCI0blwiKTsgLy8gYSBxdWFydGVyIG5vdGUgYXMgdGlja3NcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrc0NsYXNzIGV4dGVuZHMgVHJhbnNwb3J0VGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrc1wiO1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwiaVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZSBpbiB0aGUgZ2l2ZW4gdW5pdHNcbiAgICAgKi9cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRQUFEoKSAqIGJlYXRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHNlY29uZHMgLyAoNjAgLyB0aGlzLl9nZXRCcG0oKSkgKiB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiB0aWNrc1xuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNlY29uZHNcbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy52YWx1ZU9mKCkgLyB0aGlzLl9nZXRQUFEoKSkgKiAoNjAgLyB0aGlzLl9nZXRCcG0oKSk7XG4gICAgfVxufVxuLyoqXG4gKiBDb252ZXJ0IGEgdGltZSByZXByZXNlbnRhdGlvbiB0byB0aWNrc1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFRpY2tzKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrcy5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG4vKipcbiAqIERyYXcgaXMgdXNlZnVsIGZvciBzeW5jaHJvbml6aW5nIHZpc3VhbHMgYW5kIGF1ZGlvIGV2ZW50cy5cbiAqIENhbGxiYWNrcyBmcm9tIFRvbmUuVHJhbnNwb3J0IG9yIGFueSBvZiB0aGUgVG9uZS5FdmVudCBjbGFzc2VzXG4gKiBhbHdheXMgaGFwcGVuIF9iZWZvcmVfIHRoZSBzY2hlZHVsZWQgdGltZSBhbmQgYXJlIG5vdCBzeW5jaHJvbml6ZWRcbiAqIHRvIHRoZSBhbmltYXRpb24gZnJhbWUgc28gdGhleSBhcmUgbm90IGdvb2QgZm9yIHRyaWdnZXJpbmcgdGlnaHRseVxuICogc3luY2hyb25pemVkIHZpc3VhbHMgYW5kIHNvdW5kLiBEcmF3IG1ha2VzIGl0IGVhc3kgdG8gc2NoZWR1bGVcbiAqIGNhbGxiYWNrcyB1c2luZyB0aGUgQXVkaW9Db250ZXh0IHRpbWUgYW5kIHVzZXMgcmVxdWVzdEFuaW1hdGlvbkZyYW1lLlxuICogQGV4YW1wbGVcbiAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKCh0aW1lKSA9PiB7XG4gKiBcdC8vIHVzZSB0aGUgdGltZSBhcmd1bWVudCB0byBzY2hlZHVsZSBhIGNhbGxiYWNrIHdpdGggRHJhd1xuICogXHRUb25lLkRyYXcuc2NoZWR1bGUoKCkgPT4ge1xuICogXHRcdC8vIGRvIGRyYXdpbmcgb3IgRE9NIG1hbmlwdWxhdGlvbiBoZXJlXG4gKiBcdFx0Y29uc29sZS5sb2codGltZSk7XG4gKiBcdH0sIHRpbWUpO1xuICogfSwgXCIrMC41XCIpO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBEcmF3IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEcmF3XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZHVyYXRpb24gYWZ0ZXIgd2hpY2ggZXZlbnRzIGFyZSBub3QgaW52b2tlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXhwaXJhdGlvbiA9IDAuMjU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSBzY2hlZHVsZWQgdGltZVxuICAgICAgICAgKiB0aGF0IHRoZSBjYWxsYmFjayBjYW4gYmUgaW52b2tlZC4gRGVmYXVsdCBpc1xuICAgICAgICAgKiBoYWxmIHRoZSB0aW1lIG9mIGFuIGFuaW1hdGlvbiBmcmFtZSAoMC4wMDggc2Vjb25kcykuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFudGljaXBhdGlvbiA9IDAuMDA4O1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkcmF3IGxvb3BcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kRHJhd0xvb3AgPSB0aGlzLl9kcmF3TG9vcC5iaW5kKHRoaXMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFuaW1hdGlvbiBmcmFtZSBpZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSAtMTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYSBmdW5jdGlvbiBhdCB0aGUgZ2l2ZW4gdGltZSB0byBiZSBpbnZva2VkXG4gICAgICogb24gdGhlIG5lYXJlc3QgYW5pbWF0aW9uIGZyYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIENhbGxiYWNrIGlzIGludm9rZWQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgICAgVGhlIHRpbWUgcmVsYXRpdmUgdG8gdGhlIEF1ZGlvQ29udGV4dCB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2suXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aW1lID0+IHtcbiAgICAgKiBcdFRvbmUuRHJhdy5zY2hlZHVsZSgoKSA9PiBjb25zb2xlLmxvZyh0aW1lKSwgdGltZSk7XG4gICAgICogfSwgMSk7XG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgdGltZTogdGhpcy50b1NlY29uZHModGltZSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB0aGUgZHJhdyBsb29wIG9uIHRoZSBmaXJzdCBldmVudFxuICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGltZSBhZnRlciB3aGljaCBzY2hlZHVsZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBzY2hlZHVsaW5nIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHJhdyBsb29wXG4gICAgICovXG4gICAgX2RyYXdMb29wKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIHdoaWxlICh0aGlzLl9ldmVudHMubGVuZ3RoICYmIHRoaXMuX2V2ZW50cy5wZWVrKCkudGltZSAtIHRoaXMuYW50aWNpcGF0aW9uIDw9IG5vdykge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9ldmVudHMuc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChldmVudCAmJiBub3cgLSBldmVudC50aW1lIDw9IHRoaXMuZXhwaXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGV2ZW50LmNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmltYXRpb25GcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLl9ib3VuZERyYXdMb29wKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuX2FuaW1hdGlvbkZyYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kcmF3ID0gbmV3IERyYXcoeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRyYXcuZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EcmF3LmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi9EZWJ1Z1wiO1xuLyoqXG4gKiBTaW1pbGFyIHRvIFRvbmUuVGltZWxpbmUsIGJ1dCBhbGwgZXZlbnRzIHJlcHJlc2VudFxuICogaW50ZXJ2YWxzIHdpdGggYm90aCBcInRpbWVcIiBhbmQgXCJkdXJhdGlvblwiIHRpbWVzLiBUaGVcbiAqIGV2ZW50cyBhcmUgcGxhY2VkIGluIGEgdHJlZSBzdHJ1Y3R1cmUgb3B0aW1pemVkXG4gKiBmb3IgcXVlcnlpbmcgYW4gaW50ZXJzZWN0aW9uIHBvaW50IHdpdGggdGhlIHRpbWVsaW5lXG4gKiBldmVudHMuIEludGVybmFsbHkgdXNlcyBhbiBbSW50ZXJ2YWwgVHJlZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW50ZXJ2YWxfdHJlZSlcbiAqIHRvIHJlcHJlc2VudCB0aGUgZGF0YS5cbiAqL1xuZXhwb3J0IGNsYXNzIEludGVydmFsVGltZWxpbmUgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnRlcnZhbFRpbWVsaW5lXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcm9vdCBub2RlIG9mIHRoZSBpbnRldmFsIHRyZWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgbGVuZ3RoIG9mIHRoZSB0aW1lbGluZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xlbmd0aCA9IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCB0byBhZGQgdG8gdGhlIHRpbWVsaW5lLiBBbGwgZXZlbnRzIG11c3RcbiAgICAgKiBoYXZlIGEgdGltZSBhbmQgZHVyYXRpb24gdmFsdWVcbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgZXZlbnQgdG8gYWRkIHRvIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIGFkZChldmVudCkge1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKGV2ZW50LnRpbWUpLCBcIkV2ZW50cyBtdXN0IGhhdmUgYSB0aW1lIHByb3BlcnR5XCIpO1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKGV2ZW50LmR1cmF0aW9uKSwgXCJFdmVudHMgbXVzdCBoYXZlIGEgZHVyYXRpb24gcGFyYW1ldGVyXCIpO1xuICAgICAgICBldmVudC50aW1lID0gZXZlbnQudGltZS52YWx1ZU9mKCk7XG4gICAgICAgIGxldCBub2RlID0gbmV3IEludGVydmFsTm9kZShldmVudC50aW1lLCBldmVudC50aW1lICsgZXZlbnQuZHVyYXRpb24sIGV2ZW50KTtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5pbnNlcnQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbGVuZ3RoKys7XG4gICAgICAgIC8vIFJlc3RydWN0dXJlIHRyZWUgdG8gYmUgYmFsYW5jZWRcbiAgICAgICAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUudXBkYXRlSGVpZ2h0KCk7XG4gICAgICAgICAgICBub2RlLnVwZGF0ZU1heCgpO1xuICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKG5vZGUpO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYW4gZXZlbnQgZnJvbSB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIHJlbW92ZSBmcm9tIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIHJlbW92ZShldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2goZXZlbnQudGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50ID09PSBldmVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVOb2RlKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sZW5ndGgtLTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcmVhZE9ubHlcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgZXZlbnRzIHdob3NlIHRpbWUgdGltZSBpcyBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLmZvckVhY2hGcm9tKGFmdGVyLCBldmVudCA9PiB0aGlzLnJlbW92ZShldmVudCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSByb290IG5vZGUgYXMgdGhlIGdpdmVuIG5vZGVcbiAgICAgKi9cbiAgICBfc2V0Um9vdChub2RlKSB7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5wYXJlbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2UgdGhlIHJlZmVyZW5jZXMgdG8gdGhlIG5vZGUgaW4gdGhlIG5vZGUncyBwYXJlbnRcbiAgICAgKiB3aXRoIHRoZSByZXBsYWNlbWVudCBub2RlLlxuICAgICAqL1xuICAgIF9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIHJlcGxhY2VtZW50KSB7XG4gICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LnJpZ2h0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2Uobm9kZS5wYXJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChyZXBsYWNlbWVudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBub2RlIGZyb20gdGhlIHRyZWUgYW5kIHJlcGxhY2UgaXQgd2l0aFxuICAgICAqIGEgc3VjY2Vzc29yIHdoaWNoIGZvbGxvd3MgdGhlIHNjaGVtYS5cbiAgICAgKi9cbiAgICBfcmVtb3ZlTm9kZShub2RlKSB7XG4gICAgICAgIGlmIChub2RlLmxlZnQgPT09IG51bGwgJiYgbm9kZS5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUubGVmdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5sZWZ0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUucmlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYmFsYW5jZSA9IG5vZGUuZ2V0QmFsYW5jZSgpO1xuICAgICAgICAgICAgbGV0IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgbGV0IHRlbXAgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGJhbGFuY2UgPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUubGVmdC5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUubGVmdC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlcGxhY2VtZW50LnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXBsYWNlbWVudC5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50LmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQucGFyZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUucmlnaHQubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodC5sZWZ0O1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZXBsYWNlbWVudC5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQubGVmdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlcGxhY2VtZW50LnBhcmVudCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5wYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQucGFyZW50O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5yaWdodCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vZGUucGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocmVwbGFjZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRlbXApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2UodGVtcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5kaXNwb3NlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgbGVmdFxuICAgICAqL1xuICAgIF9yb3RhdGVMZWZ0KG5vZGUpIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIGNvbnN0IGlzTGVmdENoaWxkID0gbm9kZS5pc0xlZnRDaGlsZCgpO1xuICAgICAgICAvLyBNYWtlIG5vZGUucmlnaHQgdGhlIG5ldyByb290IG9mIHRoaXMgc3ViIHRyZWUgKGluc3RlYWQgb2Ygbm9kZSlcbiAgICAgICAgY29uc3QgcGl2b3ROb2RlID0gbm9kZS5yaWdodDtcbiAgICAgICAgaWYgKHBpdm90Tm9kZSkge1xuICAgICAgICAgICAgbm9kZS5yaWdodCA9IHBpdm90Tm9kZS5sZWZ0O1xuICAgICAgICAgICAgcGl2b3ROb2RlLmxlZnQgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0xlZnRDaGlsZCkge1xuICAgICAgICAgICAgICAgIHBhcmVudC5sZWZ0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LnJpZ2h0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChwaXZvdE5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBfcm90YXRlUmlnaHQobm9kZSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcbiAgICAgICAgY29uc3QgaXNMZWZ0Q2hpbGQgPSBub2RlLmlzTGVmdENoaWxkKCk7XG4gICAgICAgIC8vIE1ha2Ugbm9kZS5sZWZ0IHRoZSBuZXcgcm9vdCBvZiB0aGlzIHN1YiB0cmVlIChpbnN0ZWFkIG9mIG5vZGUpXG4gICAgICAgIGNvbnN0IHBpdm90Tm9kZSA9IG5vZGUubGVmdDtcbiAgICAgICAgaWYgKHBpdm90Tm9kZSkge1xuICAgICAgICAgICAgbm9kZS5sZWZ0ID0gcGl2b3ROb2RlLnJpZ2h0O1xuICAgICAgICAgICAgcGl2b3ROb2RlLnJpZ2h0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBCYWxhbmNlIHRoZSBCU1RcbiAgICAgKi9cbiAgICBfcmViYWxhbmNlKG5vZGUpIHtcbiAgICAgICAgY29uc3QgYmFsYW5jZSA9IG5vZGUuZ2V0QmFsYW5jZSgpO1xuICAgICAgICBpZiAoYmFsYW5jZSA+IDEgJiYgbm9kZS5sZWZ0KSB7XG4gICAgICAgICAgICBpZiAobm9kZS5sZWZ0LmdldEJhbGFuY2UoKSA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVMZWZ0KG5vZGUubGVmdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVSaWdodChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiYWxhbmNlIDwgLTEgJiYgbm9kZS5yaWdodCkge1xuICAgICAgICAgICAgaWYgKG5vZGUucmlnaHQuZ2V0QmFsYW5jZSgpID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZVJpZ2h0KG5vZGUucmlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlTGVmdChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYW4gZXZlbnQgd2hvc2UgdGltZSBhbmQgZHVyYXRpb24gc3BhbiB0aGUgZ2l2ZSB0aW1lLiBXaWxsXG4gICAgICogcmV0dXJuIHRoZSBtYXRjaCB3aG9zZSBcInRpbWVcIiB2YWx1ZSBpcyBjbG9zZXN0IHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aGljaCBzcGFucyB0aGUgZGVzaXJlZCB0aW1lXG4gICAgICovXG4gICAgZ2V0KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKHRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCBtYXggPSByZXN1bHRzWzBdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0c1tpXS5sb3cgPiBtYXgubG93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXggPSByZXN1bHRzW2ldO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtYXguZXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgYWxsTm9kZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QudHJhdmVyc2Uobm9kZSA9PiBhbGxOb2Rlcy5wdXNoKG5vZGUpKTtcbiAgICAgICAgICAgIGFsbE5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBpbiB3aGljaCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIG92ZXJsYXBzIHdpdGggdGhlIHRpbWUgYW5kIGR1cmF0aW9uIHRpbWUgb2YgdGhlIGV2ZW50LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgb3ZlcmxhcHBpbmdcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEF0VGltZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2godGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICByZXN1bHRzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBpbiB3aGljaCB0aGUgdGltZSBpcyBncmVhdGVyXG4gICAgICogdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoRnJvbSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2hBZnRlcih0aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIHJlc3VsdHMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhub2RlLmV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yb290LnRyYXZlcnNlKG5vZGUgPT4gbm9kZS5kaXNwb3NlKCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5URVJWQUwgTk9ERSBIRUxQRVJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBSZXByZXNlbnRzIGEgbm9kZSBpbiB0aGUgYmluYXJ5IHNlYXJjaCB0cmVlLCB3aXRoIHRoZSBhZGRpdGlvblxuICogb2YgYSBcImhpZ2hcIiB2YWx1ZSB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgaGlnaGVzdCB2YWx1ZSBvZlxuICogaXRzIGNoaWxkcmVuLlxuICogUmVmZXJlbmNlczpcbiAqIGh0dHBzOi8vYnJvb2tub3Zhay53b3JkcHJlc3MuY29tLzIwMTMvMTIvMDcvYXVnbWVudGVkLWludGVydmFsLXRyZWUtaW4tYy9cbiAqIGh0dHA6Ly93d3cubWlmLnZ1Lmx0L352YWxkYXMvQUxHT1JJVE1BSS9MSVRFUkFUVVJBL0Nvcm1lbi9Db3JtZW4ucGRmXG4gKiBAcGFyYW0gbG93XG4gKiBAcGFyYW0gaGlnaFxuICovXG5jbGFzcyBJbnRlcnZhbE5vZGUge1xuICAgIGNvbnN0cnVjdG9yKGxvdywgaGlnaCwgZXZlbnQpIHtcbiAgICAgICAgLy8gdGhlIG5vZGVzIHRvIHRoZSBsZWZ0XG4gICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgbm9kZXMgdG8gdGhlIHJpZ2h0XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIHBhcmVudCBub2RlXG4gICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIG51bWJlciBvZiBjaGlsZCBub2Rlc1xuICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICAgICAgLy8gdGhlIGxvdyB2YWx1ZVxuICAgICAgICB0aGlzLmxvdyA9IGxvdztcbiAgICAgICAgLy8gdGhlIGhpZ2ggdmFsdWVcbiAgICAgICAgdGhpcy5oaWdoID0gaGlnaDtcbiAgICAgICAgLy8gdGhlIGhpZ2ggdmFsdWUgZm9yIHRoaXMgYW5kIGFsbCBjaGlsZCBub2Rlc1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zZXJ0IGEgbm9kZSBpbnRvIHRoZSBjb3JyZWN0IHNwb3QgaW4gdGhlIHRyZWVcbiAgICAgKi9cbiAgICBpbnNlcnQobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5sb3cgPD0gdGhpcy5sb3cpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQgPSBub2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0Lmluc2VydChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQuaW5zZXJ0KG5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgdHJlZSBmb3Igbm9kZXMgd2hpY2ggb3ZlcmxhcFxuICAgICAqIHdpdGggdGhlIGdpdmVuIHBvaW50XG4gICAgICogQHBhcmFtICBwb2ludCAgVGhlIHBvaW50IHRvIHF1ZXJ5XG4gICAgICogQHBhcmFtICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG4gICAgICovXG4gICAgc2VhcmNoKHBvaW50LCByZXN1bHRzKSB7XG4gICAgICAgIC8vIElmIHAgaXMgdG8gdGhlIHJpZ2h0IG9mIHRoZSByaWdodG1vc3QgcG9pbnQgb2YgYW55IGludGVydmFsXG4gICAgICAgIC8vIGluIHRoaXMgbm9kZSBhbmQgYWxsIGNoaWxkcmVuLCB0aGVyZSB3b24ndCBiZSBhbnkgbWF0Y2hlcy5cbiAgICAgICAgaWYgKHBvaW50ID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTZWFyY2ggbGVmdCBjaGlsZHJlblxuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxlZnQuc2VhcmNoKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDaGVjayB0aGlzIG5vZGVcbiAgICAgICAgaWYgKHRoaXMubG93IDw9IHBvaW50ICYmIHRoaXMuaGlnaCA+IHBvaW50KSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgcCBpcyB0byB0aGUgbGVmdCBvZiB0aGUgdGltZSBvZiB0aGlzIGludGVydmFsLFxuICAgICAgICAvLyB0aGVuIGl0IGNhbid0IGJlIGluIGFueSBjaGlsZCB0byB0aGUgcmlnaHQuXG4gICAgICAgIGlmICh0aGlzLmxvdyA+IHBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VhcmNoIHJpZ2h0IGNoaWxkcmVuXG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VhcmNoIHRoZSB0cmVlIGZvciBub2RlcyB3aGljaCBhcmUgbGVzc1xuICAgICAqIHRoYW4gdGhlIGdpdmVuIHBvaW50XG4gICAgICogQHBhcmFtICBwb2ludCAgVGhlIHBvaW50IHRvIHF1ZXJ5XG4gICAgICogQHBhcmFtICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG4gICAgICovXG4gICAgc2VhcmNoQWZ0ZXIocG9pbnQsIHJlc3VsdHMpIHtcbiAgICAgICAgLy8gQ2hlY2sgdGhpcyBub2RlXG4gICAgICAgIGlmICh0aGlzLmxvdyA+PSBwb2ludCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVmdC5zZWFyY2hBZnRlcihwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2VhcmNoIHRoZSByaWdodCBzaWRlXG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrIG9uIHRoaXMgZWxlbWVudCBhbmQgYm90aCBpdCdzIGJyYW5jaGVzXG4gICAgICogQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFja1xuICAgICAqL1xuICAgIHRyYXZlcnNlKGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxlZnQudHJhdmVyc2UoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuICAgICAqL1xuICAgIHVwZGF0ZUhlaWdodCgpIHtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IE1hdGgubWF4KHRoaXMubGVmdC5oZWlnaHQsIHRoaXMucmlnaHQuaGVpZ2h0KSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnJpZ2h0LmhlaWdodCArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMubGVmdC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgaGVpZ2h0IG9mIHRoZSBub2RlXG4gICAgICovXG4gICAgdXBkYXRlTWF4KCkge1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSBNYXRoLm1heCh0aGlzLm1heCwgdGhpcy5sZWZ0Lm1heCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gTWF0aC5tYXgodGhpcy5tYXgsIHRoaXMucmlnaHQubWF4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFsYW5jZSBpcyBob3cgdGhlIGxlYWZzIGFyZSBkaXN0cmlidXRlZCBvbiB0aGUgbm9kZVxuICAgICAqIEByZXR1cm4gIE5lZ2F0aXZlIG51bWJlcnMgYXJlIGJhbGFuY2VkIHRvIHRoZSByaWdodFxuICAgICAqL1xuICAgIGdldEJhbGFuY2UoKSB7XG4gICAgICAgIGxldCBiYWxhbmNlID0gMDtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBiYWxhbmNlID0gdGhpcy5sZWZ0LmhlaWdodCAtIHRoaXMucmlnaHQuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgYmFsYW5jZSA9IHRoaXMubGVmdC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGJhbGFuY2UgPSAtKHRoaXMucmlnaHQuaGVpZ2h0ICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhbGFuY2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRydWUgaWYgdGhpcyBub2RlIGlzIHRoZSBsZWZ0IGNoaWxkIG9mIGl0cyBwYXJlbnRcbiAgICAgKi9cbiAgICBpc0xlZnRDaGlsZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50ICE9PSBudWxsICYmIHRoaXMucGFyZW50LmxlZnQgPT09IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGdldC9zZXQgdGhlIGxlZnQgbm9kZVxuICAgICAqL1xuICAgIGdldCBsZWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVmdDtcbiAgICB9XG4gICAgc2V0IGxlZnQobm9kZSkge1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQvc2V0IHRoZSByaWdodCBub2RlXG4gICAgICovXG4gICAgZ2V0IHJpZ2h0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmlnaHQ7XG4gICAgfVxuICAgIHNldCByaWdodChub2RlKSB7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBudWxsIG91dCByZWZlcmVuY2VzLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5ldmVudCA9IG51bGw7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW50ZXJ2YWxUaW1lbGluZS5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9jbG9jay9DbG9ja1wiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vY2xvY2svVHJhbnNwb3J0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0NvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvQmFzZUNvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvRGVsYXlcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvRGVzdGluYXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvR2FpblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9PZmZsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1BhcmFtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvRnJlcXVlbmN5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL01pZGlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVGltZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UaWNrc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgXCIuL3V0aWwvRHJhd1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9FbWl0dGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL0ludGVydmFsVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9UaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmV4cG9ydCB7IGRiVG9HYWluLCBnYWluVG9EYiwgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvLCBmdG9tLCBtdG9mIH0gZnJvbSBcIi4vdHlwZS9Db252ZXJzaW9uc1wiO1xuZXhwb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMsIGRlZmF1bHRBcmcgfSBmcm9tIFwiLi91dGlsL0RlZmF1bHRzXCI7XG4vLyBnZXQgdGhlIHVuaXRzIGFuZCBleHBvcnQgdGhlbSB1bmRlciB0aGUgXCJVbml0XCIgbmFtZXNwYWNlXG5pbXBvcnQgKiBhcyBVbml0IGZyb20gXCIuL3R5cGUvVW5pdHNcIjtcbmV4cG9ydCB7IFVuaXQgfTtcbi8vIGV4cG9ydCB0aGUgZGVidWcgc3R1ZmYgYXMgRGVidWdcbmltcG9ydCAqIGFzIGRlYnVnIGZyb20gXCIuL3V0aWwvRGVidWdcIjtcbmV4cG9ydCB7IGRlYnVnIH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogVm9sdW1lIGlzIGEgc2ltcGxlIHZvbHVtZSBub2RlLCB1c2VmdWwgZm9yIGNyZWF0aW5nIGEgdm9sdW1lIGZhZGVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCB2b2wgPSBuZXcgVG9uZS5Wb2x1bWUoLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdCh2b2wpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBWb2x1bWUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVm9sdW1lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVm9sdW1lXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhWb2x1bWUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMub3V0cHV0LmdhaW47XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLl91bm11dGVkVm9sdW1lID0gb3B0aW9ucy52b2x1bWU7XG4gICAgICAgIC8vIHNldCB0aGUgbXV0ZSBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCB2b2wgPSBuZXcgVG9uZS5Wb2x1bWUoLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3Qodm9sKS5zdGFydCgpO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIHZvbC5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9sdW1lLnZhbHVlID09PSAtSW5maW5pdHk7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgbXV0ZSkge1xuICAgICAgICAgICAgdGhpcy5fdW5tdXRlZFZvbHVtZSA9IHRoaXMudm9sdW1lLnZhbHVlO1xuICAgICAgICAgICAgLy8gbWF5YmUgaXQgc2hvdWxkIHJhbXAgaGVyZT9cbiAgICAgICAgICAgIHRoaXMudm9sdW1lLnZhbHVlID0gLUluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubXV0ZSAmJiAhbXV0ZSkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWUudmFsdWUgPSB0aGlzLl91bm11dGVkVm9sdW1lO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Wb2x1bWUuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBBIHNpbmdsZSBtYXN0ZXIgb3V0cHV0IHdoaWNoIGlzIGNvbm5lY3RlZCB0byB0aGVcbiAqIEF1ZGlvRGVzdGluYXRpb25Ob2RlIChha2EgeW91ciBzcGVha2VycykuXG4gKiBJdCBwcm92aWRlcyB1c2VmdWwgY29udmVuaWVuY2VzIHN1Y2ggYXMgdGhlIGFiaWxpdHlcbiAqIHRvIHNldCB0aGUgdm9sdW1lIGFuZCBtdXRlIHRoZSBlbnRpcmUgYXBwbGljYXRpb24uXG4gKiBJdCBhbHNvIGdpdmVzIHlvdSB0aGUgYWJpbGl0eSB0byBhcHBseSBtYXN0ZXIgZWZmZWN0cyB0byB5b3VyIGFwcGxpY2F0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnN0YXJ0KCk7XG4gKiAvLyB0aGUgYXVkaW8gd2lsbCBnbyBmcm9tIHRoZSBvc2NpbGxhdG9yIHRvIHRoZSBzcGVha2Vyc1xuICogb3NjaWxsYXRvci5jb25uZWN0KFRvbmUuZ2V0RGVzdGluYXRpb24oKSk7XG4gKiAvLyBhIGNvbnZlbmllbmNlIGZvciBjb25uZWN0aW5nIHRvIHRoZSBtYXN0ZXIgb3V0cHV0IGlzIGFsc28gcHJvdmlkZWQ6XG4gKiBvc2NpbGxhdG9yLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXN0aW5hdGlvbiBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEZXN0aW5hdGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEZXN0aW5hdGlvblwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IFZvbHVtZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2b2x1bWUgb2YgdGhlIG1hc3RlciBvdXRwdXQgaW4gZGVjaWJlbHMuIC1JbmZpbml0eSBpcyBzaWxlbnQsIGFuZCAwIGlzIG5vIGNoYW5nZS5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgICogb3NjLnN0YXJ0KCk7XG4gICAgICAgICAqIC8vIHJhbXAgdGhlIHZvbHVtZSBkb3duIHRvIHNpbGVudCBvdmVyIDEwIHNlY29uZHNcbiAgICAgICAgICogVG9uZS5nZXREZXN0aW5hdGlvbigpLnZvbHVtZS5yYW1wVG8oLUluZmluaXR5LCAxMCk7XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuaW5wdXQudm9sdW1lO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVzdGluYXRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCB0aGlzLm91dHB1dCwgdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5pbnB1dCwgdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24sIHRoaXMub3V0cHV0XTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgKiBcdC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIFx0VG9uZS5EZXN0aW5hdGlvbi5tdXRlID0gdHJ1ZTtcbiAgICAgKiB9LCAxMDAwKTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLmlucHV0Lm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBtYXN0ZXIgZWZmZWN0cyBjaGFpbi4gTk9URTogdGhpcyB3aWxsIGRpc2Nvbm5lY3QgYW55IG5vZGVzIHdoaWNoIHdlcmUgcHJldmlvdXNseVxuICAgICAqIGNoYWluZWQgaW4gdGhlIG1hc3RlciBlZmZlY3RzIGNoYWluLlxuICAgICAqIEBwYXJhbSBhcmdzIEFsbCBhcmd1bWVudHMgd2lsbCBiZSBjb25uZWN0ZWQgaW4gYSByb3cgYW5kIHRoZSBNYXN0ZXIgd2lsbCBiZSByb3V0ZWQgdGhyb3VnaCBpdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHJvdXRlIGFsbCBhdWRpbyB0aHJvdWdoIGEgZmlsdGVyIGFuZCBjb21wcmVzc29yXG4gICAgICogY29uc3QgbG93cGFzcyA9IG5ldyBUb25lLkZpbHRlcig4MDAsIFwibG93cGFzc1wiKTtcbiAgICAgKiBjb25zdCBjb21wcmVzc29yID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMTgpO1xuICAgICAqIFRvbmUuRGVzdGluYXRpb24uY2hhaW4obG93cGFzcywgY29tcHJlc3Nvcik7XG4gICAgICovXG4gICAgY2hhaW4oLi4uYXJncykge1xuICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgYXJncy51bnNoaWZ0KHRoaXMuaW5wdXQpO1xuICAgICAgICBhcmdzLnB1c2godGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLmFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYW5uZWxzIHRoZSBzeXN0ZW0gY2FuIG91dHB1dFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc29sZS5sb2coVG9uZS5EZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQpO1xuICAgICAqL1xuICAgIGdldCBtYXhDaGFubmVsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5kZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZGVzdGluYXRpb24gPSBuZXcgRGVzdGluYXRpb24oeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRlc3RpbmF0aW9uLmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVzdGluYXRpb24uanMubWFwIiwiaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi9UaW1lbGluZVwiO1xuaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG4vKipcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgdmFsdWUgd2hpY2ggaXMgZ2V0dGFibGUgYW5kIHNldHRhYmxlIGluIGEgdGltZWQgd2F5XG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lbGluZVZhbHVlIGV4dGVuZHMgVG9uZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGluaXRpYWxWYWx1ZSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIHRoZXJlIGlzIG5vIHNjaGVkdWxlZCB2YWx1ZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsVmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lbGluZVZhbHVlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZWxpbmUgd2hpY2ggc3RvcmVzIHRoZSB2YWx1ZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbmV3IFRpbWVsaW5lKHsgbWVtb3J5OiAxMCB9KTtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICovXG4gICAgc2V0KHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZSwgdGltZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKi9cbiAgICBnZXQodGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZWxpbmVWYWx1ZS5qcy5tYXAiLCJpbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFRyYW5zcG9ydEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgW1tUcmFuc3BvcnRdXVxuICogdG8gc2NoZWR1bGUgZXZlbnRzLiBEbyBubyBpbnZva2UgdGhpcyBjbGFzcyBkaXJlY3RseSwgaXQgaXNcbiAqIGhhbmRsZWQgZnJvbSB3aXRoaW4gVG9uZS5UcmFuc3BvcnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRFdmVudCB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHRyYW5zcG9ydCBUaGUgdHJhbnNwb3J0IG9iamVjdCB3aGljaCB0aGUgZXZlbnQgYmVsb25ncyB0b1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCwgb3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHVuaXF1ZSBpZCBvZiB0aGUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaWQgPSBUcmFuc3BvcnRFdmVudC5fZXZlbnRJZCsrO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gT2JqZWN0LmFzc2lnbihUcmFuc3BvcnRFdmVudC5nZXREZWZhdWx0cygpLCBvcHRzKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLl9vbmNlID0gb3B0aW9ucy5vbmNlO1xuICAgICAgICB0aGlzLnRpbWUgPSBvcHRpb25zLnRpbWU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgb25jZTogZmFsc2UsXG4gICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGV2ZW50IGNhbGxiYWNrLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIEF1ZGlvQ29udGV4dCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgaW52b2tlKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb25jZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBDdXJyZW50IElEIGNvdW50ZXJcbiAqL1xuVHJhbnNwb3J0RXZlbnQuX2V2ZW50SWQgPSAwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0RXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydEV2ZW50XCI7XG4vKipcbiAqIFRyYW5zcG9ydFJlcGVhdEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgVG9uZS5UcmFuc3BvcnRcbiAqIHRvIHNjaGVkdWxlIHJlcGVhdCBldmVudHMuIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRSZXBlYXRFdmVudCBleHRlbmRzIFRyYW5zcG9ydEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gdHJhbnNwb3J0IFRoZSB0cmFuc3BvcnQgb2JqZWN0IHdoaWNoIHRoZSBldmVudCBiZWxvbmdzIHRvXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHJhbnNwb3J0LCBvcHRzKSB7XG4gICAgICAgIHN1cGVyKHRyYW5zcG9ydCwgb3B0cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSUQgb2YgdGhlIGN1cnJlbnQgdGltZWxpbmUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIElEIG9mIHRoZSBuZXh0IHRpbWVsaW5lIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZXh0SWQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lIG9mIHRoZSBuZXh0IGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBib3VuZCBzdGFydCBtZXRob2RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kUmVzdGFydCA9IHRoaXMuX3Jlc3RhcnQuYmluZCh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oVHJhbnNwb3J0UmVwZWF0RXZlbnQuZ2V0RGVmYXVsdHMoKSwgb3B0cyk7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSBuZXcgVGlja3NDbGFzcyh0cmFuc3BvcnQuY29udGV4dCwgb3B0aW9ucy5kdXJhdGlvbikudmFsdWVPZigpO1xuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IG5ldyBUaWNrc0NsYXNzKHRyYW5zcG9ydC5jb250ZXh0LCBvcHRpb25zLmludGVydmFsKS52YWx1ZU9mKCk7XG4gICAgICAgIHRoaXMuX25leHRUaWNrID0gb3B0aW9ucy50aW1lO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9uKFwibG9vcFN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IHRoaXMudHJhbnNwb3J0LmNvbnRleHQ7XG4gICAgICAgIHRoaXMuX3Jlc3RhcnQoKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgVHJhbnNwb3J0RXZlbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZHVyYXRpb246IEluZmluaXR5LFxuICAgICAgICAgICAgaW50ZXJ2YWw6IDEsXG4gICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2suIFJldHVybnMgdGhlIHRpY2sgdGltZSB3aGljaFxuICAgICAqIHRoZSBuZXh0IGV2ZW50IHNob3VsZCBiZSBzY2hlZHVsZWQgYXQuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgQXVkaW9Db250ZXh0IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBpbnZva2UodGltZSkge1xuICAgICAgICAvLyBjcmVhdGUgbW9yZSBldmVudHMgaWYgbmVjZXNzYXJ5XG4gICAgICAgIHRoaXMuX2NyZWF0ZUV2ZW50cyh0aW1lKTtcbiAgICAgICAgLy8gY2FsbCB0aGUgc3VwZXIgY2xhc3NcbiAgICAgICAgc3VwZXIuaW52b2tlKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdXNoIG1vcmUgZXZlbnRzIG9udG8gdGhlIHRpbWVsaW5lIHRvIGtlZXAgdXAgd2l0aCB0aGUgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgX2NyZWF0ZUV2ZW50cyh0aW1lKSB7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBuZXh0IGV2ZW50XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50cmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aWNrcyA+PSB0aGlzLnRpbWUgJiYgdGlja3MgPj0gdGhpcy5fbmV4dFRpY2sgJiYgdGhpcy5fbmV4dFRpY2sgKyB0aGlzLl9pbnRlcnZhbCA8IHRoaXMudGltZSArIHRoaXMuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudElkID0gdGhpcy5fbmV4dElkO1xuICAgICAgICAgICAgdGhpcy5fbmV4dElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdXNoIG1vcmUgZXZlbnRzIG9udG8gdGhlIHRpbWVsaW5lIHRvIGtlZXAgdXAgd2l0aCB0aGUgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9jdXJyZW50SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9uZXh0SWQpO1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKHRpY2tzID4gdGhpcy50aW1lKSB7XG4gICAgICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZSArIE1hdGguY2VpbCgodGlja3MgLSB0aGlzLnRpbWUpIC8gdGhpcy5faW50ZXJ2YWwpICogdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY3VycmVudElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgKz0gdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9jdXJyZW50SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9uZXh0SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vZmYoXCJsb29wU3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0UmVwZWF0RXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9UaW1lXCI7XG5pbXBvcnQgeyBUaW1lbGluZVZhbHVlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UaW1lbGluZVZhbHVlXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBJbnRlcnZhbFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJ2YWxUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBDbG9jayB9IGZyb20gXCIuL0Nsb2NrXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydEV2ZW50XCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRSZXBlYXRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydFJlcGVhdEV2ZW50XCI7XG4vKipcbiAqIFRyYW5zcG9ydCBmb3IgdGltaW5nIG11c2ljYWwgZXZlbnRzLlxuICogU3VwcG9ydHMgdGVtcG8gY3VydmVzIGFuZCB0aW1lIGNoYW5nZXMuIFVubGlrZSBicm93c2VyLWJhc2VkIHRpbWluZyAoc2V0SW50ZXJ2YWwsIHJlcXVlc3RBbmltYXRpb25GcmFtZSlcbiAqIFRyYW5zcG9ydCB0aW1pbmcgZXZlbnRzIHBhc3MgaW4gdGhlIGV4YWN0IHRpbWUgb2YgdGhlIHNjaGVkdWxlZCBldmVudFxuICogaW4gdGhlIGFyZ3VtZW50IG9mIHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gUGFzcyB0aGF0IHRpbWUgdmFsdWUgdG8gdGhlIG9iamVjdFxuICogeW91J3JlIHNjaGVkdWxpbmcuIDxicj48YnI+XG4gKiBBIHNpbmdsZSB0cmFuc3BvcnQgaXMgY3JlYXRlZCBmb3IgeW91IHdoZW4gdGhlIGxpYnJhcnkgaXMgaW5pdGlhbGl6ZWQuXG4gKiA8YnI+PGJyPlxuICogVGhlIHRyYW5zcG9ydCBlbWl0cyB0aGUgZXZlbnRzOiBcInN0YXJ0XCIsIFwic3RvcFwiLCBcInBhdXNlXCIsIGFuZCBcImxvb3BcIiB3aGljaCBhcmVcbiAqIGNhbGxlZCB3aXRoIHRoZSB0aW1lIG9mIHRoYXQgZXZlbnQgYXMgdGhlIGFyZ3VtZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcmVwZWF0ZWQgZXZlbnQgZXZlcnkgOHRoIG5vdGVcbiAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KCh0aW1lKSA9PiB7XG4gKiBcdC8vIHVzZSB0aGUgY2FsbGJhY2sgdGltZSB0byBzY2hlZHVsZSBldmVudHNcbiAqIFx0b3NjLnN0YXJ0KHRpbWUpLnN0b3AodGltZSArIDAuMSk7XG4gKiB9LCBcIjhuXCIpO1xuICogLy8gdHJhbnNwb3J0IG11c3QgYmUgc3RhcnRlZCBiZWZvcmUgaXQgc3RhcnRzIGludm9raW5nIGV2ZW50c1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnQgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUcmFuc3BvcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJhbnNwb3J0XCI7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdExPT1BJTkdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgdHJhbnNwb3J0IGxvb3BzIG9yIG5vdC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3AgPSBuZXcgVGltZWxpbmVWYWx1ZShmYWxzZSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbG9vcCBzdGFydCBwb3NpdGlvbiBpbiB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb29wIGVuZCBwb3NpdGlvbiBpbiB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IDA7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdFRJTUVMSU5FIEVWRU5UU1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCB0aGUgZXZlbnRzIGluIGFuIG9iamVjdCB0byBrZWVwIHRyYWNrIGJ5IElEXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSB7fTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzY2hlZHVsZWQgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGVhdGVkIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMgPSBuZXcgSW50ZXJ2YWxUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBzeW5jZWQgU2lnbmFsc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN3aW5nIGFtb3VudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3dpbmdBbW91bnQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJhbnNwb3J0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIC8vIENMT0NLL1RFTVBPXG4gICAgICAgIHRoaXMuX3BwcSA9IG9wdGlvbnMucHBxO1xuICAgICAgICB0aGlzLl9jbG9jayA9IG5ldyBDbG9jayh7XG4gICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fcHJvY2Vzc1RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHVuaXRzOiBcImJwbVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmluZENsb2NrRXZlbnRzKCk7XG4gICAgICAgIHRoaXMuYnBtID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kubXVsdGlwbGllciA9IG9wdGlvbnMucHBxO1xuICAgICAgICB0aGlzLmJwbS5zZXRWYWx1ZUF0VGltZShvcHRpb25zLmJwbSwgMCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiYnBtXCIpO1xuICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gb3B0aW9ucy50aW1lU2lnbmF0dXJlO1xuICAgICAgICAvLyBTV0lOR1xuICAgICAgICB0aGlzLl9zd2luZ1RpY2tzID0gb3B0aW9ucy5wcHEgLyAyOyAvLyA4blxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBicG06IDEyMCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IFwiNG1cIixcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBwcTogMTkyLFxuICAgICAgICAgICAgc3dpbmc6IDAsXG4gICAgICAgICAgICBzd2luZ1N1YmRpdmlzaW9uOiBcIjhuXCIsXG4gICAgICAgICAgICB0aW1lU2lnbmF0dXJlOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRUSUNLU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIGNhbGxlZCBvbiBldmVyeSB0aWNrXG4gICAgICogQHBhcmFtICB0aWNrVGltZSBjbG9jayByZWxhdGl2ZSB0aWNrIHRpbWVcbiAgICAgKi9cbiAgICBfcHJvY2Vzc1RpY2sodGlja1RpbWUsIHRpY2tzKSB7XG4gICAgICAgIC8vIGRvIHRoZSBsb29wIHRlc3RcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AuZ2V0KHRpY2tUaW1lKSkge1xuICAgICAgICAgICAgaWYgKHRpY2tzID49IHRoaXMuX2xvb3BFbmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wRW5kXCIsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0aGlzLl9sb29wU3RhcnQsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgICAgICB0aWNrcyA9IHRoaXMuX2xvb3BTdGFydDtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wU3RhcnRcIiwgdGlja1RpbWUsIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGlja1RpbWUpKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wXCIsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoYW5kbGUgc3dpbmdcbiAgICAgICAgaWYgKHRoaXMuX3N3aW5nQW1vdW50ID4gMCAmJlxuICAgICAgICAgICAgdGlja3MgJSB0aGlzLl9wcHEgIT09IDAgJiYgLy8gbm90IG9uIGEgZG93bmJlYXRcbiAgICAgICAgICAgIHRpY2tzICUgKHRoaXMuX3N3aW5nVGlja3MgKiAyKSAhPT0gMCkge1xuICAgICAgICAgICAgLy8gYWRkIHNvbWUgc3dpbmdcbiAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gKHRpY2tzICUgKHRoaXMuX3N3aW5nVGlja3MgKiAyKSkgLyAodGhpcy5fc3dpbmdUaWNrcyAqIDIpO1xuICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gTWF0aC5zaW4oKHByb2dyZXNzKSAqIE1hdGguUEkpICogdGhpcy5fc3dpbmdBbW91bnQ7XG4gICAgICAgICAgICB0aWNrVGltZSArPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N3aW5nVGlja3MgKiAyIC8gMykudG9TZWNvbmRzKCkgKiBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW52b2tlIHRoZSB0aW1lbGluZSBldmVudHMgc2NoZWR1bGVkIG9uIHRoaXMgdGlja1xuICAgICAgICB0aGlzLl90aW1lbGluZS5mb3JFYWNoQXRUaW1lKHRpY2tzLCBldmVudCA9PiBldmVudC5pbnZva2UodGlja1RpbWUpKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTQ0hFRFVMQUJMRSBFVkVOVFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhbiBldmVudCBhbG9uZyB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBiZSBpbnZva2VkIGF0IHRoZSB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2sgYXQuXG4gICAgICogQHJldHVybiBUaGUgaWQgb2YgdGhlIGV2ZW50IHdoaWNoIGNhbiBiZSB1c2VkIGZvciBjYW5jZWxpbmcgdGhlIGV2ZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc2NoZWR1bGUgYW4gZXZlbnQgb24gdGhlIDE2dGggbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKCh0aW1lKSA9PiB7XG4gICAgICogXHQvLyBpbnZva2VkIG9uIG1lYXN1cmUgMTZcbiAgICAgKiBcdGNvbnNvbGUubG9nKFwibWVhc3VyZSAxNiFcIik7XG4gICAgICogfSwgXCIxNjowOjBcIik7XG4gICAgICovXG4gICAgc2NoZWR1bGUoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGEgcmVwZWF0ZWQgZXZlbnQgYWxvbmcgdGhlIHRpbWVsaW5lLiBUaGUgZXZlbnQgd2lsbCBmaXJlXG4gICAgICogYXQgdGhlIGBpbnRlcnZhbGAgc3RhcnRpbmcgYXQgdGhlIGBzdGFydFRpbWVgIGFuZCBmb3IgdGhlIHNwZWNpZmllZFxuICAgICAqIGBkdXJhdGlvbmAuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgIFRoZSBjYWxsYmFjayB0byBpbnZva2UuXG4gICAgICogQHBhcmFtICBpbnRlcnZhbCAgIFRoZSBkdXJhdGlvbiBiZXR3ZWVuIHN1Y2Nlc3NpdmUgY2FsbGJhY2tzLiBNdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lICBXaGVuIGFsb25nIHRoZSB0aW1lbGluZSB0aGUgZXZlbnRzIHNob3VsZCBzdGFydCBiZWluZyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIGV2ZW50IHNob3VsZCByZXBlYXQuXG4gICAgICogQHJldHVybiAgVGhlIElEIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQuIFVzZSB0aGlzIHRvIGNhbmNlbCB0aGUgZXZlbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gYSBjYWxsYmFjayBpbnZva2VkIGV2ZXJ5IGVpZ2h0aCBub3RlIGFmdGVyIHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQoKHRpbWUpID0+IHtcbiAgICAgKiBcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpO1xuICAgICAqIH0sIFwiOG5cIiwgXCIxbVwiKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZVJlcGVhdChjYWxsYmFjaywgaW50ZXJ2YWwsIHN0YXJ0VGltZSwgZHVyYXRpb24gPSBJbmZpbml0eSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRSZXBlYXRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIGR1cmF0aW9uOiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgZHVyYXRpb24pLnRvVGlja3MoKSxcbiAgICAgICAgICAgIGludGVydmFsOiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgaW50ZXJ2YWwpLnRvVGlja3MoKSxcbiAgICAgICAgICAgIHRpbWU6IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGtpY2sgaXQgb2ZmIGlmIHRoZSBUcmFuc3BvcnQgaXMgc3RhcnRlZFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fcmVwZWF0ZWRFdmVudHMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhbiBldmVudCB0aGF0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBpdCBpcyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIG9uY2UuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm5zIFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50LlxuICAgICAqL1xuICAgIHNjaGVkdWxlT25jZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIG9uY2U6IHRydWUsXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBwYXNzZWQgaW4gZXZlbnQgaWQgZnJvbSB0aGUgdGltZWxpbmVcbiAgICAgKiBAcGFyYW0gZXZlbnRJZCBUaGUgaWQgb2YgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIGNsZWFyKGV2ZW50SWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NjaGVkdWxlZEV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudElkKSkge1xuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudElkLnRvU3RyaW5nKCldO1xuICAgICAgICAgICAgaXRlbS50aW1lbGluZS5yZW1vdmUoaXRlbS5ldmVudCk7XG4gICAgICAgICAgICBpdGVtLmV2ZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnRJZC50b1N0cmluZygpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGV2ZW50IHRvIHRoZSBjb3JyZWN0IHRpbWVsaW5lLiBLZWVwIHRyYWNrIG9mIHRoZVxuICAgICAqIHRpbWVsaW5lIGl0IHdhcyBhZGRlZCB0by5cbiAgICAgKiBAcmV0dXJucyB0aGUgZXZlbnQgaWQgd2hpY2ggd2FzIGp1c3QgYWRkZWRcbiAgICAgKi9cbiAgICBfYWRkRXZlbnQoZXZlbnQsIHRpbWVsaW5lKSB7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudC5pZC50b1N0cmluZygpXSA9IHtcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGltZWxpbmUsXG4gICAgICAgIH07XG4gICAgICAgIHRpbWVsaW5lLmFkZChldmVudCk7XG4gICAgICAgIHJldHVybiBldmVudC5pZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHNjaGVkdWxlZCBldmVudHMgZnJvbSB0aGUgdGltZWxpbmUgYWZ0ZXJcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZS4gUmVwZWF0ZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGlmIHRoZWlyIHN0YXJ0VGltZSBpcyBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSBhZnRlciBDbGVhciBhbGwgZXZlbnRzIGFmdGVyIHRoaXMgdGltZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIgPSAwKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkQWZ0ZXIgPSB0aGlzLnRvVGlja3MoYWZ0ZXIpO1xuICAgICAgICB0aGlzLl90aW1lbGluZS5mb3JFYWNoRnJvbShjb21wdXRlZEFmdGVyLCBldmVudCA9PiB0aGlzLmNsZWFyKGV2ZW50LmlkKSk7XG4gICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzLmZvckVhY2hGcm9tKGNvbXB1dGVkQWZ0ZXIsIGV2ZW50ID0+IHRoaXMuY2xlYXIoZXZlbnQuaWQpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U1RBUlQvU1RPUC9QQVVTRVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEJpbmQgc3RhcnQvc3RvcC9wYXVzZSBldmVudHMgZnJvbSB0aGUgY2xvY2sgYW5kIGVtaXQgdGhlbS5cbiAgICAgKi9cbiAgICBfYmluZENsb2NrRXZlbnRzKCkge1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0YXJ0XCIsICh0aW1lLCBvZmZzZXQpID0+IHtcbiAgICAgICAgICAgIG9mZnNldCA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgb2Zmc2V0KS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIHRpbWUsIG9mZnNldCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0b3BcIiwgKHRpbWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgdGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInBhdXNlXCIsICh0aW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJwYXVzZVwiLCB0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIsIG9yIFwicGF1c2VkXCJcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIHRyYW5zcG9ydCBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIHRpbWVsaW5lIG9mZnNldCB0byBzdGFydCB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydCBpbiBvbmUgc2Vjb25kIHN0YXJ0aW5nIGF0IGJlZ2lubmluZyBvZiB0aGUgNXRoIG1lYXN1cmUuXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoXCIrMVwiLCBcIjQ6MDowXCIpO1xuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBsZXQgb2Zmc2V0VGlja3M7XG4gICAgICAgIGlmIChpc0RlZmluZWQob2Zmc2V0KSkge1xuICAgICAgICAgICAgb2Zmc2V0VGlja3MgPSB0aGlzLnRvVGlja3Mob2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzdGFydCB0aGUgY2xvY2tcbiAgICAgICAgdGhpcy5fY2xvY2suc3RhcnQodGltZSwgb2Zmc2V0VGlja3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSB0cmFuc3BvcnQgc2hvdWxkIHN0b3AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdG9wKCk7XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnBhdXNlKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB0cmFuc3BvcnQuIElmIGl0IGlzXG4gICAgICogc3RhcnRlZCwgaXQgd2lsbCBzdG9wIGl0LCBvdGhlcndpc2UgaXQgd2lsbCBzdGFydCB0aGUgVHJhbnNwb3J0LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0b2dnbGUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnQodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U0VUVEVSUy9HRVRURVJTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2lnbmF0dXJlIGFzIGp1c3QgdGhlIG51bWVyYXRvciBvdmVyIDQuXG4gICAgICogRm9yIGV4YW1wbGUgNC80IHdvdWxkIGJlIGp1c3QgNCBhbmQgNi84IHdvdWxkIGJlIDMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBjb21tb24gdGltZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmUgPSA0O1xuICAgICAqIC8vIDcvOFxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmUgPSBbNywgOF07XG4gICAgICogLy8gdGhpcyB3aWxsIGJlIHJlZHVjZWQgdG8gYSBzaW5nbGUgbnVtYmVyXG4gICAgICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZTsgLy8gcmV0dXJucyAzLjVcbiAgICAgKi9cbiAgICBnZXQgdGltZVNpZ25hdHVyZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVTaWduYXR1cmU7XG4gICAgfVxuICAgIHNldCB0aW1lU2lnbmF0dXJlKHRpbWVTaWcpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodGltZVNpZykpIHtcbiAgICAgICAgICAgIHRpbWVTaWcgPSAodGltZVNpZ1swXSAvIHRpbWVTaWdbMV0pICogNDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gdGltZVNpZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgVHJhbnNwb3J0Lmxvb3AgPSB0cnVlLCB0aGlzIGlzIHRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KHN0YXJ0UG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKHN0YXJ0UG9zaXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBUcmFuc3BvcnQubG9vcCA9IHRydWUsIHRoaXMgaXMgdGhlIGVuZGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wRW5kLCBcImlcIikudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MoZW5kUG9zaXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgdHJhbnNwb3J0IGxvb3BzIG9yIG5vdC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3AuZ2V0KHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3Auc2V0KGxvb3AsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIHN0b3AgYXQgdGhlIHNhbWUgdGltZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGxvb3Agb3ZlciB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNldExvb3BQb2ludHMoMCwgXCIxbVwiKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXRMb29wUG9pbnRzKHN0YXJ0UG9zaXRpb24sIGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gc3RhcnRQb3NpdGlvbjtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gZW5kUG9zaXRpb247XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3dpbmcgdmFsdWUuIEJldHdlZW4gMC0xIHdoZXJlIDEgZXF1YWwgdG8gdGhlIG5vdGUgKyBoYWxmIHRoZSBzdWJkaXZpc2lvbi5cbiAgICAgKi9cbiAgICBnZXQgc3dpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zd2luZ0Ftb3VudDtcbiAgICB9XG4gICAgc2V0IHN3aW5nKGFtb3VudCkge1xuICAgICAgICAvLyBzY2FsZSB0aGUgdmFsdWVzIHRvIGEgbm9ybWFsIHJhbmdlXG4gICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gYW1vdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHN1YmRpdmlzaW9uIHdoaWNoIHRoZSBzd2luZyB3aWxsIGJlIGFwcGxpZWQgdG8uXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgYW4gOHRoIG5vdGUuIFZhbHVlIG11c3QgYmUgbGVzc1xuICAgICAqIHRoYW4gYSBxdWFydGVyIG5vdGUuXG4gICAgICovXG4gICAgZ2V0IHN3aW5nU3ViZGl2aXNpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N3aW5nVGlja3MpLnRvTm90YXRpb24oKTtcbiAgICB9XG4gICAgc2V0IHN3aW5nU3ViZGl2aXNpb24oc3ViZGl2aXNpb24pIHtcbiAgICAgICAgdGhpcy5fc3dpbmdUaWNrcyA9IHRoaXMudG9UaWNrcyhzdWJkaXZpc2lvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBCYXJzOkJlYXRzOlNpeHRlZW50aHMuXG4gICAgICogU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBqdW1wIHRvIHRoYXQgcG9zaXRpb24gcmlnaHQgYXdheS5cbiAgICAgKi9cbiAgICBnZXQgcG9zaXRpb24oKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpLnRvQmFyc0JlYXRzU2l4dGVlbnRocygpO1xuICAgIH1cbiAgICBzZXQgcG9zaXRpb24ocHJvZ3Jlc3MpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3MocHJvZ3Jlc3MpO1xuICAgICAgICB0aGlzLnRpY2tzID0gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBzZWNvbmRzXG4gICAgICogU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBqdW1wIHRvIHRoYXQgcG9zaXRpb24gcmlnaHQgYXdheS5cbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLnNlY29uZHM7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5mcmVxdWVuY3kudGltZVRvVGlja3Mocywgbm93KTtcbiAgICAgICAgdGhpcy50aWNrcyA9IHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgbG9vcCBwb3NpdGlvbiBhcyBhIG5vcm1hbGl6ZWQgdmFsdWUuIEFsd2F5c1xuICAgICAqIHJldHVybnMgMCBpZiB0aGUgdHJhbnNwb3J0IGlmIGxvb3AgaXMgbm90IHRydWUuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgcmV0dXJuICh0aWNrcyAtIHRoaXMuX2xvb3BTdGFydCkgLyAodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHJhbnNwb3J0cyBjdXJyZW50IHRpY2sgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2sudGlja3M7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIGlmICh0aGlzLl9jbG9jay50aWNrcyAhPT0gdCkge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIC8vIHN0b3AgZXZlcnl0aGluZyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgICAgIC8vIHNjaGVkdWxlIHRvIHN0YXJ0IG9uIHRoZSBuZXh0IHRpY2ssICM1NzNcbiAgICAgICAgICAgICAgICBjb25zdCByZW1haW5pbmdUaWNrID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcyhNYXRoLmNlaWwodGlja3MpIC0gdGlja3MsIG5vdyk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGltZSA9IG5vdyArIHJlbWFpbmluZ1RpY2s7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0LCB0aW1lKTtcbiAgICAgICAgICAgICAgICAvLyByZXN0YXJ0IGl0IHdpdGggdGhlIG5ldyB0aW1lXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgdGltZSwgdGhpcy5fY2xvY2suZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0LCBub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgdGljayB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKHRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1bHNlcyBQZXIgUXVhcnRlciBub3RlLiBUaGlzIGlzIHRoZSBzbWFsbGVzdCByZXNvbHV0aW9uXG4gICAgICogdGhlIFRyYW5zcG9ydCB0aW1pbmcgc3VwcG9ydHMuIFRoaXMgc2hvdWxkIGJlIHNldCBvbmNlXG4gICAgICogb24gaW5pdGlhbGl6YXRpb24gYW5kIG5vdCBzZXQgYWdhaW4uIENoYW5naW5nIHRoaXMgdmFsdWVcbiAgICAgKiBhZnRlciBvdGhlciBvYmplY3RzIGhhdmUgYmVlbiBjcmVhdGVkIGNhbiBjYXVzZSBwcm9ibGVtcy5cbiAgICAgKi9cbiAgICBnZXQgUFBRKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suZnJlcXVlbmN5Lm11bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBQUFEocHBxKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5tdWx0aXBsaWVyID0gcHBxO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNZTkNJTkdcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aW1lIGFsaWduZWQgdG8gdGhlIG5leHQgc3ViZGl2aXNpb25cbiAgICAgKiBvZiB0aGUgVHJhbnNwb3J0LiBJZiB0aGUgVHJhbnNwb3J0IGlzIG5vdCBzdGFydGVkLFxuICAgICAqIGl0IHdpbGwgcmV0dXJuIDAuXG4gICAgICogTm90ZTogdGhpcyB3aWxsIG5vdCB3b3JrIHByZWNpc2VseSBkdXJpbmcgdGVtcG8gcmFtcHMuXG4gICAgICogQHBhcmFtICBzdWJkaXZpc2lvbiAgVGhlIHN1YmRpdmlzaW9uIHRvIHF1YW50aXplIHRvXG4gICAgICogQHJldHVybiAgVGhlIGNvbnRleHQgdGltZSBvZiB0aGUgbmV4dCBzdWJkaXZpc2lvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHRoZSB0cmFuc3BvcnQgbXVzdCBiZSBzdGFydGVkLCBvdGhlcndpc2UgcmV0dXJucyAwXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5uZXh0U3ViZGl2aXNpb24oXCI0blwiKTtcbiAgICAgKi9cbiAgICBuZXh0U3ViZGl2aXNpb24oc3ViZGl2aXNpb24pIHtcbiAgICAgICAgc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Moc3ViZGl2aXNpb24pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZSB0cmFuc3BvcnQncyBub3Qgc3RhcnRlZCwgcmV0dXJuIDBcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIC8vIHRoZSByZW1haW5kZXIgb2YgdGhlIGN1cnJlbnQgdGlja3MgYW5kIHRoZSBzdWJkaXZpc2lvblxuICAgICAgICAgICAgY29uc3QgdHJhbnNwb3J0UG9zID0gdGhpcy5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVGlja3MgPSBzdWJkaXZpc2lvbiAtIHRyYW5zcG9ydFBvcyAlIHN1YmRpdmlzaW9uO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLm5leHRUaWNrVGltZShyZW1haW5pbmdUaWNrcywgbm93KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBdHRhY2hlcyB0aGUgc2lnbmFsIHRvIHRoZSB0ZW1wbyBjb250cm9sIHNpZ25hbCBzbyB0aGF0XG4gICAgICogYW55IGNoYW5nZXMgaW4gdGhlIHRlbXBvIHdpbGwgY2hhbmdlIHRoZSBzaWduYWwgaW4gdGhlIHNhbWVcbiAgICAgKiByYXRpby5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzaWduYWxcbiAgICAgKiBAcGFyYW0gcmF0aW8gT3B0aW9uYWxseSBwYXNzIGluIHRoZSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gc2lnbmFscy5cbiAgICAgKiBcdFx0XHRPdGhlcndpc2UgaXQgd2lsbCBiZSBjb21wdXRlZCBiYXNlZCBvbiB0aGVpciBjdXJyZW50IHZhbHVlcy5cbiAgICAgKi9cbiAgICBzeW5jU2lnbmFsKHNpZ25hbCwgcmF0aW8pIHtcbiAgICAgICAgaWYgKCFyYXRpbykge1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBzeW5jIHJhdGlvXG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgaWYgKHNpZ25hbC5nZXRWYWx1ZUF0VGltZShub3cpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnBtID0gdGhpcy5icG0uZ2V0VmFsdWVBdFRpbWUobm93KTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wdXRlZEZyZXEgPSAxIC8gKDYwIC8gYnBtIC8gdGhpcy5QUFEpO1xuICAgICAgICAgICAgICAgIHJhdGlvID0gc2lnbmFsLmdldFZhbHVlQXRUaW1lKG5vdykgLyBjb21wdXRlZEZyZXE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByYXRpbyA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmF0aW9TaWduYWwgPSBuZXcgR2FpbihyYXRpbyk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5icG0uY29ubmVjdChyYXRpb1NpZ25hbCk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmF0aW9TaWduYWwuY29ubmVjdChzaWduYWwuX3BhcmFtKTtcbiAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscy5wdXNoKHtcbiAgICAgICAgICAgIGluaXRpYWw6IHNpZ25hbC52YWx1ZSxcbiAgICAgICAgICAgIHJhdGlvOiByYXRpb1NpZ25hbCxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpZ25hbC52YWx1ZSA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmNzIGEgcHJldmlvdXNseSBzeW5jZWQgc2lnbmFsIGZyb20gdGhlIHRyYW5zcG9ydCdzIGNvbnRyb2wuXG4gICAgICogU2VlIFRyYW5zcG9ydC5zeW5jU2lnbmFsLlxuICAgICAqL1xuICAgIHVuc3luY1NpZ25hbChzaWduYWwpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuX3N5bmNlZFNpZ25hbHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHN5bmNlZFNpZ25hbCA9IHRoaXMuX3N5bmNlZFNpZ25hbHNbaV07XG4gICAgICAgICAgICBpZiAoc3luY2VkU2lnbmFsLnNpZ25hbCA9PT0gc2lnbmFsKSB7XG4gICAgICAgICAgICAgICAgc3luY2VkU2lnbmFsLnJhdGlvLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICBzeW5jZWRTaWduYWwuc2lnbmFsLnZhbHVlID0gc3luY2VkU2lnbmFsLmluaXRpYWw7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZGlzcG9zZSgpO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBcImJwbVwiKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbkVtaXR0ZXIubWl4aW4oVHJhbnNwb3J0KTtcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQudHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydCh7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQudHJhbnNwb3J0LmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0LmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCBcIi4uL2NvcmUvY29udGV4dC9EZXN0aW5hdGlvblwiO1xuaW1wb3J0IFwiLi4vY29yZS9jbG9jay9UcmFuc3BvcnRcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzVW5kZWYgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0LCBhc3NlcnRDb250ZXh0UnVubmluZyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IEdUIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHNvdXJjZXMuXG4gKiBzdGFydC9zdG9wIG9mIHRoaXMuY29udGV4dC50cmFuc3BvcnQuXG4gKlxuICogYGBgXG4gKiAvLyBNdWx0aXBsZSBzdGF0ZSBjaGFuZ2UgZXZlbnRzIGNhbiBiZSBjaGFpbmVkIHRvZ2V0aGVyLFxuICogLy8gYnV0IG11c3QgYmUgc2V0IGluIHRoZSBjb3JyZWN0IG9yZGVyIGFuZCB3aXRoIGFzY2VuZGluZyB0aW1lc1xuICogLy8gT0tcbiAqIHN0YXRlLnN0YXJ0KCkuc3RvcChcIiswLjJcIik7XG4gKiAvLyBPS1xuICogc3RhdGUuc3RhcnQoKS5zdG9wKFwiKzAuMlwiKS5zdGFydChcIiswLjRcIikuc3RvcChcIiswLjdcIilcbiAqIC8vIEJBRFxuICogc3RhdGUuc3RvcChcIiswLjJcIikuc3RhcnQoKTtcbiAqIC8vIEJBRFxuICogc3RhdGUuc3RhcnQoXCIrMC4zXCIpLnN0b3AoXCIrMC4yXCIpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTb3VyY2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogU291cmNlcyBoYXZlIG5vIGlucHV0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIHNjaGVkdWxlZCBzdGF0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN5bmNlZCBgc3RhcnRgIGNhbGxiYWNrIGZ1bmN0aW9uIGZyb20gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIGFsbCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50IGlkc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQbGFjZWhvbGRlciBmdW5jdGlvbnMgZm9yIHN5bmNpbmcvdW5zeW5jaW5nIHRvIHRyYW5zcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQgPSBub09wO1xuICAgICAgICB0aGlzLl9zeW5jZWRTdG9wID0gbm9PcDtcbiAgICAgICAgdGhpcy5fc3RhdGUubWVtb3J5ID0gMTAwO1xuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG11dGU6IG9wdGlvbnMubXV0ZSxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLm9uc3RvcCA9IG9wdGlvbnMub25zdG9wO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBvbnN0b3A6IG5vT3AsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9haG50b25lX2MzLm1wM1wiLCAoKSA9PiB7XG4gICAgICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAgICAgKiBcdGNvbnNvbGUubG9nKHBsYXllci5zdGF0ZSk7XG4gICAgICogfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIG9zYy5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5zdXJlIHRoYXQgdGhlIHNjaGVkdWxlZCB0aW1lIGlzIG5vdCBiZWZvcmUgdGhlIGN1cnJlbnQgdGltZS5cbiAgICAgKiBTaG91bGQgb25seSBiZSB1c2VkIHdoZW4gc2NoZWR1bGVkIHVuc3luY2VkLlxuICAgICAqL1xuICAgIF9jbGFtcFRvQ3VycmVudFRpbWUodGltZSkge1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1heCh0aW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzb3VyY2UgYXQgdGhlIHNwZWNpZmllZCB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLFxuICAgICAqIHN0YXJ0IHRoZSBzb3VyY2Ugbm93LlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBzb3VyY2Ugc2hvdWxkIGJlIHN0YXJ0ZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHNvdXJjZS5zdGFydChcIiswLjVcIik7IC8vIHN0YXJ0cyB0aGUgc291cmNlIDAuNSBzZWNvbmRzIGZyb20gbm93XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBsZXQgY29tcHV0ZWRUaW1lID0gaXNVbmRlZih0aW1lKSAmJiB0aGlzLl9zeW5jZWQgPyB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMgOiB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29tcHV0ZWRUaW1lID0gdGhpcy5fY2xhbXBUb0N1cnJlbnRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIC8vIGlmIGl0J3Mgc3RhcnRlZCwgc3RvcCBpdCBhbmQgcmVzdGFydCBpdFxuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCAmJiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gdGltZSBzaG91bGQgYmUgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZSBwcmV2aW91cyBzdGFydCB0aW1lXG4gICAgICAgICAgICBhc3NlcnQoR1QoY29tcHV0ZWRUaW1lLCB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKS50aW1lKSwgXCJTdGFydCB0aW1lIG11c3QgYmUgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHByZXZpb3VzIHN0YXJ0IHRpbWVcIik7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5sb2coXCJyZXN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLnJlc3RhcnQoY29tcHV0ZWRUaW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgb2Zmc2V0IHRpbWUgdG8gdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQub2Zmc2V0ID0gdGhpcy50b1NlY29uZHMoZGVmYXVsdEFyZyhvZmZzZXQsIDApKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZHVyYXRpb24gPSBkdXJhdGlvbiA/IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0LCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZC5wdXNoKHNjaGVkKTtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdHJhbnNwb3J0IGlzIGFscmVhZHkgc3RhcnRlZFxuICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgdGltZSBpcyBncmVhdGVyIHRoYW4gd2hlcmUgdGhlIHRyYW5zcG9ydCBpc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFNlY29uZHNBdFRpbWUodGhpcy5pbW1lZGlhdGUoKSkgPiBjb21wdXRlZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQodGhpcy5ub3coKSwgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRDb250ZXh0UnVubmluZyh0aGlzLmNvbnRleHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sXG4gICAgICogc3RvcCB0aGUgc291cmNlIG5vdy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgc291cmNlIHNob3VsZCBiZSBzdG9wcGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc291cmNlID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzb3VyY2Uuc3RhcnQoKTtcbiAgICAgKiBzb3VyY2Uuc3RvcChcIiswLjVcIik7IC8vIHN0b3BzIHRoZSBzb3VyY2UgMC41IHNlY29uZHMgZnJvbSBub3dcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgbGV0IGNvbXB1dGVkVGltZSA9IGlzVW5kZWYodGltZSkgJiYgdGhpcy5fc3luY2VkID8gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzIDogdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbXB1dGVkVGltZSA9IHRoaXMuX2NsYW1wVG9DdXJyZW50VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIgfHwgaXNEZWZpbmVkKHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKSkpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUodGhpcy5fc3RvcC5iaW5kKHRoaXMpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZC5wdXNoKHNjaGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc3RhcnQgdGhlIHNvdXJjZS5cbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG4gICAgICAgICAgICB0aGlzLl9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzb3VyY2UgdG8gdGhlIFRyYW5zcG9ydCBzbyB0aGF0IGFsbCBzdWJzZXF1ZW50XG4gICAgICogY2FsbHMgdG8gYHN0YXJ0YCBhbmQgYHN0b3BgIGFyZSBzeW5jZWQgdG8gdGhlIFRyYW5zcG9ydFRpbWVcbiAgICAgKiBpbnN0ZWFkIG9mIHRoZSBBdWRpb0NvbnRleHQgdGltZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzeW5jIHRoZSBzb3VyY2Ugc28gdGhhdCBpdCBwbGF5cyBiZXR3ZWVuIDAgYW5kIDAuMyBvbiB0aGUgVHJhbnNwb3J0J3MgdGltZWxpbmVcbiAgICAgKiBvc2Muc3luYygpLnN0YXJ0KDApLnN0b3AoMC4zKTtcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0LlxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICogLy8gc2V0IGl0IHRvIGxvb3Agb25jZSBhIHNlY29uZFxuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3AgPSB0cnVlO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3BFbmQgPSAxO1xuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICghdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQgPSAodGltZSwgb2Zmc2V0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVFdmVudCA9IHRoaXMuX3N0YXRlLmdldChvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAvLyBsaXN0ZW4gZm9yIHN0YXJ0IGV2ZW50cyB3aGljaCBtYXkgb2NjdXIgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3luYydlZCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50ICYmIHN0YXRlRXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIHN0YXRlRXZlbnQudGltZSAhPT0gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIG9mZnNldFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRPZmZzZXQgPSBvZmZzZXQgLSB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGR1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlRXZlbnQuZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHN0YXRlRXZlbnQuZHVyYXRpb24pIC0gc3RhcnRPZmZzZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0aW1lLCB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50Lm9mZnNldCkgKyBzdGFydE9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0b3AgPSB0aW1lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRTZWNvbmRzQXRUaW1lKE1hdGgubWF4KHRpbWUgLSB0aGlzLnNhbXBsZVRpbWUsIDApKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoc2Vjb25kcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwibG9vcFN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdG9wXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcImxvb3BFbmRcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQuIFNlZSBTb3VyY2Uuc3luY1xuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdG9wXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwibG9vcEVuZFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJsb29wU3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICAvLyBjbGVhciBhbGwgb2YgdGhlIHNjaGVkdWxlZCBpZHNcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkLmZvckVhY2goaWQgPT4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihpZCkpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWQgPSBbXTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKDApO1xuICAgICAgICAvLyBzdG9wIGl0IGFsc29cbiAgICAgICAgdGhpcy5fc3RvcCgwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vbnN0b3AgPSBub09wO1xuICAgICAgICB0aGlzLnVuc3luYygpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IE9uZVNob3RTb3VyY2UgfSBmcm9tIFwiLi4vT25lU2hvdFNvdXJjZVwiO1xuaW1wb3J0IHsgRVEsIEdURSwgTFQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL01hdGhcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBCdWZmZXJTb3VyY2VOb2RlLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUJ1ZmZlclNvdXJjZSBleHRlbmRzIE9uZVNob3RTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQnVmZmVyU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUJ1ZmZlclNvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9zb3VyY2VdO1xuICAgICAgICAvKipcbiAgICAgICAgICogaW5kaWNhdG9ycyBpZiB0aGUgc291cmNlIGhhcyBzdGFydGVkL3N0b3BwZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc291cmNlU3RvcHBlZCA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUJ1ZmZlclNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc291cmNlLCB0aGlzLl9nYWluTm9kZSk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5vbmVuZGVkID0gKCkgPT4gdGhpcy5fc3RvcFNvdXJjZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBsYXliYWNrUmF0ZSBvZiB0aGUgYnVmZmVyXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wbGF5YmFja1JhdGUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzZXQgc29tZSB2YWx1ZXMgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKG9wdGlvbnMudXJsLCBvcHRpb25zLm9ubG9hZCwgb3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscy5wdXNoKHRoaXMuX3NvdXJjZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB1cmw6IG5ldyBUb25lQXVkaW9CdWZmZXIoKSxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKHQpIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlT3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZU91dDtcbiAgICB9XG4gICAgc2V0IGZhZGVPdXQodCkge1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnZlIGFwcGxpZWQgdG8gdGhlIGZhZGVzLCBlaXRoZXIgXCJsaW5lYXJcIiBvciBcImV4cG9uZW50aWFsXCJcbiAgICAgKi9cbiAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGN1cnZlKHQpIHtcbiAgICAgICAgdGhpcy5fY3VydmUgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgYnVmZmVyXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLCBpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICogQHBhcmFtICBnYWluICBUaGUgZ2FpbiB0byBwbGF5IHRoZSBidWZmZXIgYmFjayBhdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uLCBnYWluID0gMSkge1xuICAgICAgICBhc3NlcnQodGhpcy5idWZmZXIubG9hZGVkLCBcImJ1ZmZlciBpcyBlaXRoZXIgbm90IHNldCBvciBub3QgbG9hZGVkXCIpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gYXBwbHkgdGhlIGdhaW4gZW52ZWxvcGVcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSwgZ2Fpbik7XG4gICAgICAgIC8vIGlmIGl0J3MgYSBsb29wIHRoZSBkZWZhdWx0IG9mZnNldCBpcyB0aGUgbG9vcHN0YXJ0IHBvaW50XG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLmxvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIDBcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIG9mZnNldCBpcyBub3QgbGVzcyB0aGFuIDBcbiAgICAgICAgbGV0IGNvbXB1dGVkT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy50b1NlY29uZHMob2Zmc2V0KSwgMCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBidWZmZXIgc291cmNlXG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIC8vIG1vZGlmeSB0aGUgb2Zmc2V0IGlmIGl0J3MgZ3JlYXRlciB0aGFuIHRoZSBsb29wIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BFbmQpIHx8IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgbG9vcFN0YXJ0ID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wU3RhcnQpO1xuICAgICAgICAgICAgY29uc3QgbG9vcER1cmF0aW9uID0gbG9vcEVuZCAtIGxvb3BTdGFydDtcbiAgICAgICAgICAgIC8vIG1vdmUgdGhlIG9mZnNldCBiYWNrXG4gICAgICAgICAgICBpZiAoR1RFKGNvbXB1dGVkT2Zmc2V0LCBsb29wRW5kKSkge1xuICAgICAgICAgICAgICAgIGNvbXB1dGVkT2Zmc2V0ID0gKChjb21wdXRlZE9mZnNldCAtIGxvb3BTdGFydCkgJSBsb29wRHVyYXRpb24pICsgbG9vcFN0YXJ0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gd2hlbiB0aGUgb2Zmc2V0IGlzIHZlcnkgY2xvc2UgdG8gdGhlIGR1cmF0aW9uLCBzZXQgaXQgdG8gMFxuICAgICAgICAgICAgaWYgKEVRKGNvbXB1dGVkT2Zmc2V0LCB0aGlzLmJ1ZmZlci5kdXJhdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlZE9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhpcy5idWZmZXIubG9hZGVkIHdvdWxkIGhhdmUgcmV0dXJuIGZhbHNlIGlmIHRoZSBBdWRpb0J1ZmZlciB3YXMgdW5kZWZpbmVkXG4gICAgICAgIHRoaXMuX3NvdXJjZS5idWZmZXIgPSB0aGlzLmJ1ZmZlci5nZXQoKTtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BFbmQpIHx8IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICBpZiAoTFQoY29tcHV0ZWRPZmZzZXQsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlU3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQoY29tcHV0ZWRUaW1lLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgYSBkdXJhdGlvbiBpcyBnaXZlbiwgc2NoZWR1bGUgYSBzdG9wXG4gICAgICAgIGlmIChpc0RlZmluZWQoZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBsZXQgY29tcHV0ZWREdXIgPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgICAgICAvLyBtYWtlIHN1cmUgaXQncyBuZXZlciBuZWdhdGl2ZVxuICAgICAgICAgICAgY29tcHV0ZWREdXIgPSBNYXRoLm1heChjb21wdXRlZER1ciwgMCk7XG4gICAgICAgICAgICB0aGlzLnN0b3AoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIGlmICghdGhpcy5fc291cmNlU3RvcHBlZCAmJiB0aGlzLl9zb3VyY2VTdGFydGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKGxvb3BTdGFydCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wRW5kID0gdGhpcy50b1NlY29uZHMobG9vcEVuZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgYmVsb25naW5nIHRvIHRoZSBwbGF5ZXIuXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3AgPSBsb29wO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlU3RhcnRlZCkge1xuICAgICAgICAgICAgdGhpcy5jYW5jZWxTdG9wKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uub25lbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUJ1ZmZlclNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG4vKipcbiAqIE5vaXNlIGlzIGEgbm9pc2UgZ2VuZXJhdG9yLiBJdCB1c2VzIGxvb3BlZCBub2lzZSBidWZmZXJzIHRvIHNhdmUgb24gcGVyZm9ybWFuY2UuXG4gKiBOb2lzZSBzdXBwb3J0cyB0aGUgbm9pc2UgdHlwZXM6IFwicGlua1wiLCBcIndoaXRlXCIsIGFuZCBcImJyb3duXCIuIFJlYWQgbW9yZSBhYm91dFxuICogY29sb3JzIG9mIG5vaXNlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbG9yc19vZl9ub2lzZSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemUgdGhlIG5vaXNlIGFuZCBzdGFydFxuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZShcInBpbmtcIikuc3RhcnQoKTtcbiAqIC8vIG1ha2UgYW4gYXV0b2ZpbHRlciB0byBzaGFwZSB0aGUgbm9pc2VcbiAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKHtcbiAqIFx0ZnJlcXVlbmN5OiBcIjhuXCIsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAqIFx0b2N0YXZlczogOFxuICogfSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBjb25uZWN0IHRoZSBub2lzZVxuICogbm9pc2UuY29ubmVjdChhdXRvRmlsdGVyKTtcbiAqIC8vIHN0YXJ0IHRoZSBhdXRvZmlsdGVyIExGT1xuICogYXV0b0ZpbHRlci5zdGFydCgpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgTm9pc2UgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOb2lzZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSByZWZlcmVuY2UgdG8gdGhlIHNvdXJjZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgdHlwZTogXCJ3aGl0ZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG5vaXNlLiBDYW4gYmUgXCJ3aGl0ZVwiLCBcImJyb3duXCIsIG9yIFwicGlua1wiLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG5vaXNlLnR5cGUgPSBcImJyb3duXCI7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGFzc2VydCh0eXBlIGluIF9ub2lzZUJ1ZmZlcnMsIFwiTm9pc2U6IGludmFsaWQgdHlwZTogXCIgKyB0eXBlKTtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBwbGF5aW5nLCBzdG9wIGFuZCByZXN0YXJ0IGl0XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0b3Aobm93KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydChub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub2lzZS4gQWZmZWN0c1xuICAgICAqIHRoZSBcImZyZXF1ZW5jeVwiIG9mIHRoZSBub2lzZS5cbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZS52YWx1ZSA9IHJhdGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogaW50ZXJuYWwgc3RhcnQgbWV0aG9kXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gX25vaXNlQnVmZmVyc1t0aGlzLl90eXBlXTtcbiAgICAgICAgdGhpcy5fc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgdXJsOiBidWZmZXIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmYWRlSW46IHRoaXMuX2ZhZGVJbixcbiAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX2ZhZGVPdXQsXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgb25lbmRlZDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMuX3BsYXliYWNrUmF0ZSxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdGFydCh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgTWF0aC5yYW5kb20oKSAqIChidWZmZXIuZHVyYXRpb24gLSAwLjAwMSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBpbnRlcm5hbCBzdG9wIG1ldGhvZFxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnN0b3AodGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gdGltZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmZhZGVJbiA9IHRoaXMuX2ZhZGVJbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVPdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlT3V0O1xuICAgIH1cbiAgICBzZXQgZmFkZU91dCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSB0aW1lO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZmFkZU91dCA9IHRoaXMuX2ZhZGVPdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICAvLyBUT0RPIGNvdWxkIGJlIG9wdGltaXplZCBieSBjYW5jZWxsaW5nIHRoZSBidWZmZXIgc291cmNlICdzdG9wJ1xuICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRIRSBOT0lTRSBCVUZGRVJTXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBOb2lzZSBidWZmZXIgc3RhdHNcbmNvbnN0IEJVRkZFUl9MRU5HVEggPSA0NDEwMCAqIDU7XG5jb25zdCBOVU1fQ0hBTk5FTFMgPSAyO1xuLyoqXG4gKiBDYWNoZSB0aGUgbm9pc2UgYnVmZmVyc1xuICovXG5jb25zdCBfbm9pc2VDYWNoZSA9IHtcbiAgICBicm93bjogbnVsbCxcbiAgICBwaW5rOiBudWxsLFxuICAgIHdoaXRlOiBudWxsLFxufTtcbi8qKlxuICogVGhlIG5vaXNlIGFycmF5cy4gR2VuZXJhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuICogYm9ycm93ZWQgaGVhdmlseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS96YWNoYXJ5ZGVudG9uL25vaXNlLmpzXG4gKiAoYykgMjAxMyBaYWNoIERlbnRvbiAoTUlUKVxuICovXG5jb25zdCBfbm9pc2VCdWZmZXJzID0ge1xuICAgIGdldCBicm93bigpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS5icm93bikge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdE91dCA9IDAuMDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGl0ZSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IChsYXN0T3V0ICsgKDAuMDIgKiB3aGl0ZSkpIC8gMS4wMjtcbiAgICAgICAgICAgICAgICAgICAgbGFzdE91dCA9IGNoYW5uZWxbaV07XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gKj0gMy41OyAvLyAocm91Z2hseSkgY29tcGVuc2F0ZSBmb3IgZ2FpblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLmJyb3duID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS5icm93bjtcbiAgICB9LFxuICAgIGdldCBwaW5rKCkge1xuICAgICAgICBpZiAoIV9ub2lzZUNhY2hlLnBpbmspIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgbGV0IGIwLCBiMSwgYjIsIGIzLCBiNCwgYjUsIGI2O1xuICAgICAgICAgICAgICAgIGIwID0gYjEgPSBiMiA9IGIzID0gYjQgPSBiNSA9IGI2ID0gMC4wO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQlVGRkVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoaXRlID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgICAgICBiMCA9IDAuOTk4ODYgKiBiMCArIHdoaXRlICogMC4wNTU1MTc5O1xuICAgICAgICAgICAgICAgICAgICBiMSA9IDAuOTkzMzIgKiBiMSArIHdoaXRlICogMC4wNzUwNzU5O1xuICAgICAgICAgICAgICAgICAgICBiMiA9IDAuOTY5MDAgKiBiMiArIHdoaXRlICogMC4xNTM4NTIwO1xuICAgICAgICAgICAgICAgICAgICBiMyA9IDAuODY2NTAgKiBiMyArIHdoaXRlICogMC4zMTA0ODU2O1xuICAgICAgICAgICAgICAgICAgICBiNCA9IDAuNTUwMDAgKiBiNCArIHdoaXRlICogMC41MzI5NTIyO1xuICAgICAgICAgICAgICAgICAgICBiNSA9IC0wLjc2MTYgKiBiNSAtIHdoaXRlICogMC4wMTY4OTgwO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gYjAgKyBiMSArIGIyICsgYjMgKyBiNCArIGI1ICsgYjYgKyB3aGl0ZSAqIDAuNTM2MjtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSAqPSAwLjExOyAvLyAocm91Z2hseSkgY29tcGVuc2F0ZSBmb3IgZ2FpblxuICAgICAgICAgICAgICAgICAgICBiNiA9IHdoaXRlICogMC4xMTU5MjY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX25vaXNlQ2FjaGUucGluayA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUucGluaztcbiAgICB9LFxuICAgIGdldCB3aGl0ZSgpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS53aGl0ZSkge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLndoaXRlID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS53aGl0ZTtcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5vaXNlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgY29ubmVjdCwgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVXNlck1lZGlhIHVzZXMgTWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSB0byBvcGVuIHVwIGFuZCBleHRlcm5hbCBtaWNyb3Bob25lIG9yIGF1ZGlvIGlucHV0LlxuICogQ2hlY2sgW01lZGlhRGV2aWNlcyBBUEkgU3VwcG9ydF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhRGV2aWNlcy9nZXRVc2VyTWVkaWEpXG4gKiB0byBzZWUgd2hpY2ggYnJvd3NlcnMgYXJlIHN1cHBvcnRlZC4gQWNjZXNzIHRvIGFuIGV4dGVybmFsIGlucHV0XG4gKiBpcyBsaW1pdGVkIHRvIHNlY3VyZSAoSFRUUFMpIGNvbm5lY3Rpb25zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpLmNvbm5lY3QobWV0ZXIpO1xuICogbWljLm9wZW4oKS50aGVuKCgpID0+IHtcbiAqIFx0Ly8gcHJvbWlzZSByZXNvbHZlcyB3aGVuIGlucHV0IGlzIGF2YWlsYWJsZVxuICogXHRjb25zb2xlLmxvZyhcIm1pYyBvcGVuXCIpO1xuICogXHQvLyBwcmludCB0aGUgaW5jb21pbmcgbWljIGxldmVscyBpbiBkZWNpYmVsc1xuICogXHRzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhtZXRlci5nZXRWYWx1ZSgpKSwgMTAwKTtcbiAqIH0pLmNhdGNoKGUgPT4ge1xuICogXHQvLyBwcm9taXNlIGlzIHJlamVjdGVkIHdoZW4gdGhlIHVzZXIgZG9lc24ndCBoYXZlIG9yIGFsbG93IG1pYyBhY2Nlc3NcbiAqIFx0Y29uc29sZS5sb2coXCJtaWMgbm90IG9wZW5cIik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFVzZXJNZWRpYSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhVc2VyTWVkaWEuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJVc2VyTWVkaWFcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFVzZXJNZWRpYS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE9wZW4gdGhlIG1lZGlhIHN0cmVhbS4gSWYgYSBzdHJpbmcgaXMgcGFzc2VkIGluLCBpdCBpcyBhc3N1bWVkXG4gICAgICogdG8gYmUgdGhlIGxhYmVsIG9yIGlkIG9mIHRoZSBzdHJlYW0sIGlmIGEgbnVtYmVyIGlzIHBhc3NlZCBpbixcbiAgICAgKiBpdCBpcyB0aGUgaW5wdXQgbnVtYmVyIG9mIHRoZSBzdHJlYW0uXG4gICAgICogQHBhcmFtICBsYWJlbE9ySWQgVGhlIGxhYmVsIG9yIGlkIG9mIHRoZSBhdWRpbyBpbnB1dCBtZWRpYSBkZXZpY2UuXG4gICAgICogICAgICAgICAgICAgICAgICAgV2l0aCBubyBhcmd1bWVudCwgdGhlIGRlZmF1bHQgc3RyZWFtIGlzIG9wZW5lZC5cbiAgICAgKiBAcmV0dXJuIFRoZSBwcm9taXNlIGlzIHJlc29sdmVkIHdoZW4gdGhlIHN0cmVhbSBpcyBvcGVuLlxuICAgICAqL1xuICAgIG9wZW4obGFiZWxPcklkKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQoVXNlck1lZGlhLnN1cHBvcnRlZCwgXCJVc2VyTWVkaWEgaXMgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgICAgIC8vIGNsb3NlIHRoZSBwcmV2aW91cyBzdHJlYW1cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRldmljZXMgPSB5aWVsZCBVc2VyTWVkaWEuZW51bWVyYXRlRGV2aWNlcygpO1xuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGxhYmVsT3JJZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzW2xhYmVsT3JJZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzLmZpbmQoKGRldmljZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlLmxhYmVsID09PSBsYWJlbE9ySWQgfHwgZGV2aWNlLmRldmljZUlkID09PSBsYWJlbE9ySWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gZGlkbid0IGZpbmQgYSBtYXRjaGluZyBkZXZpY2VcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2RldmljZSAmJiBkZXZpY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlc1swXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZCh0aGlzLl9kZXZpY2UpLCBgTm8gbWF0Y2hpbmcgZGV2aWNlICR7bGFiZWxPcklkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG8gZ2V0VXNlck1lZGlhXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUsXG4gICAgICAgICAgICAgICAgICAgIG5vaXNlU3VwcHJlc3Npb246IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtb3pOb2lzZVN1cHByZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50cy5hdWRpby5kZXZpY2VJZCA9IHRoaXMuX2RldmljZS5kZXZpY2VJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IHlpZWxkIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIC8vIHN0YXJ0IGEgbmV3IHNvdXJjZSBvbmx5IGlmIHRoZSBwcmV2aW91cyBvbmUgaXMgY2xvc2VkXG4gICAgICAgICAgICBpZiAoIXRoaXMuX3N0cmVhbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgICAgICAgICAvLyBXcmFwIGEgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIGFyb3VuZCB0aGUgbGl2ZSBpbnB1dCBzdHJlYW0uXG4gICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW1Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgICAgICAgICAgICAgLy8gQ29ubmVjdCB0aGUgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIHRvIGEgZ2F0ZSBnYWluIG5vZGVcbiAgICAgICAgICAgICAgICBjb25uZWN0KG1lZGlhU3RyZWFtTm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtID0gbWVkaWFTdHJlYW1Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgbWVkaWEgc3RyZWFtXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zdHJlYW0gJiYgdGhpcy5fbWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMuX3N0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9zdHJlYW0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIG9sZCBtZWRpYSBzdHJlYW1cbiAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RldmljZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdGhlIGxpc3Qgb2YgYXVkaW8gaW5wdXQgZGV2aWNlcyBhdmFpbGFibGUuXG4gICAgICogQHJldHVybiBUaGUgcHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGRldmljZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVXNlck1lZGlhLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VzKSA9PiB7XG4gICAgICogXHQvLyBwcmludCB0aGUgZGV2aWNlIGxhYmVsc1xuICAgICAqIFx0Y29uc29sZS5sb2coZGV2aWNlcy5tYXAoZGV2aWNlID0+IGRldmljZS5sYWJlbCkpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHN0YXRpYyBlbnVtZXJhdGVEZXZpY2VzKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgYWxsRGV2aWNlcyA9IHlpZWxkIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpO1xuICAgICAgICAgICAgcmV0dXJuIGFsbERldmljZXMuZmlsdGVyKGRldmljZSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRldmljZS5raW5kID09PSBcImF1ZGlvaW5wdXRcIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgXCJzdGFydGVkXCIgd2hlbiB0aGUgbWljcm9waG9uZSBpcyBvcGVuXG4gICAgICogYW5kIFwic3RvcHBlZFwiIHdoZW4gdGhlIG1pYyBpcyBjbG9zZWQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RyZWFtICYmIHRoaXMuX3N0cmVhbS5hY3RpdmUgPyBcInN0YXJ0ZWRcIiA6IFwic3RvcHBlZFwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGlkZW50aWZpZXIgZm9yIHRoZSByZXByZXNlbnRlZCBkZXZpY2UgdGhhdCBpc1xuICAgICAqIHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMuIEl0IGlzIHVuLWd1ZXNzYWJsZSBieSBvdGhlciBhcHBsaWNhdGlvbnMgYW5kXG4gICAgICogdW5pcXVlIHRvIHRoZSBvcmlnaW4gb2YgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24uIEl0IGlzIHJlc2V0IHdoZW4gdGhlXG4gICAgICogdXNlciBjbGVhcnMgY29va2llcyAoZm9yIFByaXZhdGUgQnJvd3NpbmcsIGEgZGlmZmVyZW50IGlkZW50aWZpZXIgaXNcbiAgICAgKiB1c2VkIHRoYXQgaXMgbm90IHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMpLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZVxuICAgICAqIGRldmljZSBpcyBub3Qgb3Blbi5cbiAgICAgKi9cbiAgICBnZXQgZGV2aWNlSWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZGV2aWNlSWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBncm91cCBpZGVudGlmaWVyLiBUd28gZGV2aWNlcyBoYXZlIHRoZVxuICAgICAqIHNhbWUgZ3JvdXAgaWRlbnRpZmllciBpZiB0aGV5IGJlbG9uZyB0byB0aGUgc2FtZSBwaHlzaWNhbCBkZXZpY2UuXG4gICAgICogUmV0dXJucyBudWxsICB3aGVuIHRoZSBkZXZpY2UgaXMgbm90IG9wZW4uXG4gICAgICovXG4gICAgZ2V0IGdyb3VwSWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZ3JvdXBJZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGxhYmVsIGRlc2NyaWJpbmcgdGhpcyBkZXZpY2UgKGZvciBleGFtcGxlIFwiQnVpbHQtaW4gTWljcm9waG9uZVwiKS5cbiAgICAgKiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZSBkZXZpY2UgaXMgbm90IG9wZW4gb3IgbGFiZWwgaXMgbm90IGF2YWlsYWJsZVxuICAgICAqIGJlY2F1c2Ugb2YgcGVybWlzc2lvbnMuXG4gICAgICovXG4gICAgZ2V0IGxhYmVsKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmxhYmVsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAgICAgKiBtaWMub3BlbigpLnRoZW4oKCkgPT4ge1xuICAgICAqIFx0Ly8gcHJvbWlzZSByZXNvbHZlcyB3aGVuIGlucHV0IGlzIGF2YWlsYWJsZVxuICAgICAqIH0pO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIG1pYy5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGdldFVzZXJNZWRpYSBpcyBzdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgc3RhdGljIGdldCBzdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiBpc0RlZmluZWQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcykgJiZcbiAgICAgICAgICAgIGlzRGVmaW5lZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VXNlck1lZGlhLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG4vKipcbiAqIFJlbmRlciBhIHNlZ21lbnQgb2YgdGhlIG9zY2lsbGF0b3IgdG8gYW4gb2ZmbGluZSBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdHMgYXMgYW4gYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlV2F2ZWZvcm0oaW5zdGFuY2UsIGxlbmd0aCkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gbGVuZ3RoIC8gaW5zdGFuY2UuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDEsIGR1cmF0aW9uLCBpbnN0YW5jZS5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBjbG9uZSA9IG5ldyBpbnN0YW5jZS5jb25zdHJ1Y3RvcihPYmplY3QuYXNzaWduKGluc3RhbmNlLmdldCgpLCB7XG4gICAgICAgICAgICAvLyBzaG91bGQgZG8gMiBpdGVyYXRpb25zXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDIgLyBkdXJhdGlvbixcbiAgICAgICAgICAgIC8vIHplcm8gb3V0IHRoZSBkZXR1bmVcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgfSkpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgY2xvbmUuc3RhcnQoMCk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgIHJldHVybiBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Pc2NpbGxhdG9ySW50ZXJmYWNlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVTaG90U291cmNlIH0gZnJvbSBcIi4uL09uZVNob3RTb3VyY2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBmaXJlLWFuZC1mb3JnZXQgT3NjaWxsYXRvck5vZGUuXG4gKiBBZGRzIHRoZSBhYmlsaXR5IHRvIHJlc2NoZWR1bGUgdGhlIHN0b3AgbWV0aG9kLlxuICogKioqW1tPc2NpbGxhdG9yXV0gaXMgYmV0dGVyIGZvciBtb3N0IHVzZS1jYXNlcyoqKlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZU9zY2lsbGF0b3JOb2RlIGV4dGVuZHMgT25lU2hvdFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVPc2NpbGxhdG9yTm9kZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lT3NjaWxsYXRvck5vZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5jb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9vc2NpbGxhdG9yXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVPc2NpbGxhdG9yTm9kZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX29zY2lsbGF0b3IsIHRoaXMuX2dhaW5Ob2RlKTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBvc2NpbGxhdG9yIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9zdG9wU291cmNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIGFuIGFyYml0cmFyeSBjdXN0b20gcGVyaW9kaWMgd2F2ZWZvcm0gZ2l2ZW4gYSBQZXJpb2RpY1dhdmUuXG4gICAgICogQHBhcmFtICBwZXJpb2RpY1dhdmUgUGVyaW9kaWNXYXZlIHNob3VsZCBiZSBjcmVhdGVkIHdpdGggY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmVcbiAgICAgKi9cbiAgICBzZXRQZXJpb2RpY1dhdmUocGVyaW9kaWNXYXZlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlLiBFaXRoZXIgJ3NpbmUnLCAnc2F3dG9vdGgnLCAnc3F1YXJlJywgb3IgJ3RyaWFuZ2xlJ1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVPc2NpbGxhdG9yTm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGRlZXBFcXVhbHMsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZU9zY2lsbGF0b3JOb2RlIH0gZnJvbSBcIi4vVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIE9zY2lsbGF0b3Igc3VwcG9ydHMgYSBudW1iZXIgb2YgZmVhdHVyZXMgaW5jbHVkaW5nXG4gKiBwaGFzZSByb3RhdGlvbiwgbXVsdGlwbGUgb3NjaWxsYXRvciB0eXBlcyAoc2VlIE9zY2lsbGF0b3IudHlwZSksXG4gKiBhbmQgVHJhbnNwb3J0IHN5bmNpbmcgKHNlZSBPc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3kpLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBtYWtlIGFuZCBzdGFydCBhIDQ0MGh6IHNpbmUgdG9uZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBtYWluIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRldHVuZVwiKTtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBvcHRpb25zLnBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBvcHRpb25zLnBhcnRpYWxDb3VudDtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgaWYgKG9wdGlvbnMucGFydGlhbENvdW50ICYmIG9wdGlvbnMudHlwZSAhPT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuYmFzZVR5cGUgKyBvcHRpb25zLnBhcnRpYWxDb3VudC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIHBhcnRpYWxDb3VudDogMCxcbiAgICAgICAgICAgIHBhcnRpYWxzOiBbXSxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyBuZXcgb3NjaWxsYXRvciB3aXRoIHByZXZpb3VzIHZhbHVlc1xuICAgICAgICBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmVPc2NpbGxhdG9yTm9kZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvbmVuZGVkOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBvc2NpbGxhdG9yO1xuICAgICAgICBpZiAodGhpcy5fd2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGNvbnRyb2wgc2lnbmFsIHRvIHRoZSBvc2NpbGxhdG9yIGZyZXF1ZW5jeSAmIGRldHVuZVxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXN0YXJ0IHRoZSBvc2NpbGxhdG9yLiBEb2VzIG5vdCBzdG9wIHRoZSBvc2NpbGxhdG9yLCBidXQgaW5zdGVhZFxuICAgICAqIGp1c3QgY2FuY2VscyBhbnkgc2NoZWR1bGVkICdzdG9wJyBmcm9tIGJlaW5nIGludm9rZWQuXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJyZXN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNhbmNlbFN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHNpZ25hbCB0byB0aGUgVHJhbnNwb3J0J3MgYnBtLiBBbnkgY2hhbmdlcyB0byB0aGUgdHJhbnNwb3J0cyBicG0sXG4gICAgICogd2lsbCBhbHNvIGFmZmVjdCB0aGUgb3NjaWxsYXRvcnMgZnJlcXVlbmN5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG9zYy5mcmVxdWVuY3kudmFsdWUgPSA0NDA7XG4gICAgICogLy8gdGhlIHJhdGlvIGJldHdlZW4gdGhlIGJwbSBhbmQgdGhlIGZyZXF1ZW5jeSB3aWxsIGJlIG1haW50YWluZWRcbiAgICAgKiBvc2Muc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAqIC8vIGRvdWJsZSB0aGUgdGVtcG9cbiAgICAgKiBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgKj0gMjtcbiAgICAgKiAvLyB0aGUgZnJlcXVlbmN5IG9mIHRoZSBvc2NpbGxhdG9yIGlzIGRvdWJsZWQgdG8gODgwXG4gICAgICovXG4gICAgc3luY0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgb3NjaWxsYXRvcidzIGZyZXF1ZW5jeSBmcm9tIHRoZSBUcmFuc3BvcnQuXG4gICAgICogU2VlIE9zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeVxuICAgICAqL1xuICAgIHVuc3luY0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC51bnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgY2FjaGVkIHBlcmlvZGljIHdhdmUuIEF2b2lkcyBoYXZpbmcgdG8gcmVjb21wdXRlXG4gICAgICogdGhlIG9zY2lsbGF0b3IgdmFsdWVzIHdoZW4gdGhleSBoYXZlIGFscmVhZHkgYmVlbiBjb21wdXRlZFxuICAgICAqIHdpdGggdGhlIHNhbWUgdmFsdWVzLlxuICAgICAqL1xuICAgIF9nZXRDYWNoZWRQZXJpb2RpY1dhdmUoKSB7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBjb25zdCBvc2NQcm9wcyA9IE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmZpbmQoZGVzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbi5waGFzZSA9PT0gdGhpcy5fcGhhc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgZGVlcEVxdWFscyhkZXNjcmlwdGlvbi5wYXJ0aWFscywgdGhpcy5fcGFydGlhbHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gb3NjUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBvc2NQcm9wcyA9IE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmZpbmQoZGVzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbi50eXBlID09PSB0aGlzLl90eXBlICYmXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnBoYXNlID09PSB0aGlzLl9waGFzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gb3NjUHJvcHMgPyBvc2NQcm9wcy5wYXJ0aWFsQ291bnQgOiB0aGlzLl9wYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICByZXR1cm4gb3NjUHJvcHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICBjb25zdCBpc0Jhc2ljVHlwZSA9IFtcInNpbmVcIiwgXCJzcXVhcmVcIiwgXCJzYXd0b290aFwiLCBcInRyaWFuZ2xlXCJdLmluZGV4T2YodHlwZSkgIT09IC0xO1xuICAgICAgICBpZiAodGhpcy5fcGhhc2UgPT09IDAgJiYgaXNCYXNpY1R5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3dhdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSAwO1xuICAgICAgICAgICAgLy8ganVzdCBnbyB3aXRoIHRoZSBiYXNpYyBhcHByb2FjaFxuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHRlc3RlZCB0aGF0IGl0J3MgYSBiYXNpYyB0eXBlXG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHRoZSB2YWx1ZSBpcyBjYWNoZWRcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fZ2V0Q2FjaGVkUGVyaW9kaWNXYXZlKCk7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKGNhY2hlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgcGFydGlhbHMsIHdhdmUgfSA9IGNhY2hlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dhdmUgPSB3YXZlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgW3JlYWwsIGltYWddID0gdGhpcy5fZ2V0UmVhbEltYWdpbmFyeSh0eXBlLCB0aGlzLl9waGFzZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGVyaW9kaWNXYXZlID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gcGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIGNhY2hlXG4gICAgICAgICAgICAgICAgT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGltYWcsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudDogdGhpcy5fcGFydGlhbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsczogdGhpcy5fcGFydGlhbHMsXG4gICAgICAgICAgICAgICAgICAgIHBoYXNlOiB0aGlzLl9waGFzZSxcbiAgICAgICAgICAgICAgICAgICAgcmVhbCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgd2F2ZTogdGhpcy5fd2F2ZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUubGVuZ3RoID4gMTAwKSB7XG4gICAgICAgICAgICAgICAgICAgIE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGUucmVwbGFjZSh0aGlzLnBhcnRpYWxDb3VudC50b1N0cmluZygpLCBcIlwiKTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIGlmICh0aGlzLnBhcnRpYWxDb3VudCAmJiB0aGlzLl90eXBlICE9PSBcImN1c3RvbVwiICYmIGJhc2VUeXBlICE9PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZSArIHRoaXMucGFydGlhbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHAsIDApO1xuICAgICAgICBsZXQgdHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgIGNvbnN0IHBhcnRpYWwgPSAvXihzaW5lfHRyaWFuZ2xlfHNxdWFyZXxzYXd0b290aCkoXFxkKykkLy5leGVjKHRoaXMuX3R5cGUpO1xuICAgICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAgICAgdHlwZSA9IHBhcnRpYWxbMV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIGlmIChwID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGUgKyBwLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBleHRlbmQgb3Igc2hvcnRlbiB0aGUgcGFydGlhbHMgYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IGZ1bGxQYXJ0aWFscyA9IG5ldyBGbG9hdDMyQXJyYXkocCk7XG4gICAgICAgICAgICAvLyBjb3B5IG92ZXIgdGhlIHBhcnRpYWxzIGFycmF5XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscy5mb3JFYWNoKCh2LCBpKSA9PiBmdWxsUGFydGlhbHNbaV0gPSB2KTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gQXJyYXkuZnJvbShmdWxsUGFydGlhbHMpO1xuICAgICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSByZWFsIGFuZCBpbWFnaW5hcnkgY29tcG9uZW50cyBiYXNlZFxuICAgICAqIG9uIHRoZSBvc2NpbGxhdG9yIHR5cGUuXG4gICAgICogQHJldHVybnMgW3JlYWw6IEZsb2F0MzJBcnJheSwgaW1hZ2luYXJ5OiBGbG9hdDMyQXJyYXldXG4gICAgICovXG4gICAgX2dldFJlYWxJbWFnaW5hcnkodHlwZSwgcGhhc2UpIHtcbiAgICAgICAgY29uc3QgZmZ0U2l6ZSA9IDQwOTY7XG4gICAgICAgIGxldCBwZXJpb2RpY1dhdmVTaXplID0gZmZ0U2l6ZSAvIDI7XG4gICAgICAgIGNvbnN0IHJlYWwgPSBuZXcgRmxvYXQzMkFycmF5KHBlcmlvZGljV2F2ZVNpemUpO1xuICAgICAgICBjb25zdCBpbWFnID0gbmV3IEZsb2F0MzJBcnJheShwZXJpb2RpY1dhdmVTaXplKTtcbiAgICAgICAgbGV0IHBhcnRpYWxDb3VudCA9IDE7XG4gICAgICAgIGlmICh0eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGggKyAxO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwYXJ0aWFsIGNvdW50IGlzIDAsIGRvbid0IGJvdGhlciBkb2luZyBhbnkgY29tcHV0YXRpb25cbiAgICAgICAgICAgIGlmICh0aGlzLl9wYXJ0aWFscy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW3JlYWwsIGltYWddO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFydGlhbCA9IC9eKHNpbmV8dHJpYW5nbGV8c3F1YXJlfHNhd3Rvb3RoKShcXGQrKSQvLmV4ZWModHlwZSk7XG4gICAgICAgICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IHBhcnNlSW50KHBhcnRpYWxbMl0sIDEwKSArIDE7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gcGFyc2VJbnQocGFydGlhbFsyXSwgMTApO1xuICAgICAgICAgICAgICAgIHR5cGUgPSBwYXJ0aWFsWzFdO1xuICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IE1hdGgubWF4KHBhcnRpYWxDb3VudCwgMik7XG4gICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG4gPSAxOyBuIDwgcGVyaW9kaWNXYXZlU2l6ZTsgKytuKSB7XG4gICAgICAgICAgICBjb25zdCBwaUZhY3RvciA9IDIgLyAobiAqIE1hdGguUEkpO1xuICAgICAgICAgICAgbGV0IGI7XG4gICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwic2luZVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gKG4gPD0gcGFydGlhbENvdW50KSA/IDEgOiAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsc1tuIC0gMV0gPSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwic3F1YXJlXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSAobiAmIDEpID8gMiAqIHBpRmFjdG9yIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNhd3Rvb3RoXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSBwaUZhY3RvciAqICgobiAmIDEpID8gMSA6IC0xKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInRyaWFuZ2xlXCI6XG4gICAgICAgICAgICAgICAgICAgIGlmIChuICYgMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYiA9IDIgKiAocGlGYWN0b3IgKiBwaUZhY3RvcikgKiAoKCgobiAtIDEpID4+IDEpICYgMSkgPyAtMSA6IDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYiA9IDA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImN1c3RvbVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gdGhpcy5fcGFydGlhbHNbbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT3NjaWxsYXRvcjogaW52YWxpZCB0eXBlOiBcIiArIHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGIgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZWFsW25dID0gLWIgKiBNYXRoLnNpbihwaGFzZSAqIG4pO1xuICAgICAgICAgICAgICAgIGltYWdbbl0gPSBiICogTWF0aC5jb3MocGhhc2UgKiBuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlYWxbbl0gPSAwO1xuICAgICAgICAgICAgICAgIGltYWdbbl0gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbcmVhbCwgaW1hZ107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbXB1dGUgdGhlIGludmVyc2UgRkZUIGZvciBhIGdpdmVuIHBoYXNlLlxuICAgICAqL1xuICAgIF9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIHBoYXNlKSB7XG4gICAgICAgIGxldCBzdW0gPSAwO1xuICAgICAgICBjb25zdCBsZW4gPSByZWFsLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgc3VtICs9IHJlYWxbaV0gKiBNYXRoLmNvcyhpICogcGhhc2UpICsgaW1hZ1tpXSAqIE1hdGguc2luKGkgKiBwaGFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1bTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgb3NjaWxsYXRvciB3aGVuIHN0b3BwZWQuXG4gICAgICogRS5nLiBhIFwic2luZVwiIG9zY2lsbGF0b3Igd2l0aCBwaGFzZSA9IDkwIHdvdWxkIHJldHVybiBhbiBpbml0aWFsIHZhbHVlIG9mIC0xLlxuICAgICAqL1xuICAgIGdldEluaXRpYWxWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgW3JlYWwsIGltYWddID0gdGhpcy5fZ2V0UmVhbEltYWdpbmFyeSh0aGlzLl90eXBlLCAwKTtcbiAgICAgICAgbGV0IG1heFZhbHVlID0gMDtcbiAgICAgICAgY29uc3QgdHdvUGkgPSBNYXRoLlBJICogMjtcbiAgICAgICAgY29uc3QgdGVzdFBvc2l0aW9ucyA9IDMyO1xuICAgICAgICAvLyBjaGVjayBmb3IgcGVha3MgaW4gMTYgcGxhY2VzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVzdFBvc2l0aW9uczsgaSsrKSB7XG4gICAgICAgICAgICBtYXhWYWx1ZSA9IE1hdGgubWF4KHRoaXMuX2ludmVyc2VGRlQocmVhbCwgaW1hZywgKGkgLyB0ZXN0UG9zaXRpb25zKSAqIHR3b1BpKSwgbWF4VmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbGFtcCgtdGhpcy5faW52ZXJzZUZGVChyZWFsLCBpbWFnLCB0aGlzLl9waGFzZSkgLyBtYXhWYWx1ZSwgLTEsIDEpO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0aWFscy5zbGljZSgwLCB0aGlzLnBhcnRpYWxDb3VudCk7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGg7XG4gICAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiY3VzdG9tXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGhhc2UgKiAoMTgwIC8gTWF0aC5QSSk7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9waGFzZSA9IHBoYXNlICogTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgLy8gcmVzZXQgdGhlIHR5cGVcbiAgICAgICAgdGhpcy50eXBlID0gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fd2F2ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogQ2FjaGUgdGhlIHBlcmlvZGljIHdhdmVzIHRvIGF2b2lkIGhhdmluZyB0byByZWRvIGNvbXB1dGF0aW9uc1xuICovXG5Pc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZSA9IFtdO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbi8qKlxuICogQSBzaWduYWwgb3BlcmF0b3IgaGFzIGFuIGlucHV0IGFuZCBvdXRwdXQgYW5kIG1vZGlmaWVzIHRoZSBzaWduYWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxPcGVyYXRvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY29udGV4dFwiXSkpKTtcbiAgICB9XG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaWduYWxPcGVyYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRnVuY3Rpb24gfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFdyYXBzIHRoZSBuYXRpdmUgV2ViIEF1ZGlvIEFQSVxuICogW1dhdmVTaGFwZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS13YXZlc2hhcGVybm9kZS1pbnRlcmZhY2UpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBtdWx0aXBseSB0aGUgb3V0cHV0IG9mIHRoZSBzaWduYWwgYnkgMiB1c2luZyB0aGUgd2F2ZXNoYXBlcidzIGZ1bmN0aW9uXG4gKiBjb25zdCB0aW1lc1R3byA9IG5ldyBUb25lLldhdmVTaGFwZXIoKHZhbCkgPT4gdmFsICogMiwgMjA0OCkuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAqIGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCg0NDApLmNvbm5lY3QodGltZXNUd28pO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgV2F2ZVNoYXBlciBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlU2hhcGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWFwcGluZ1wiLCBcImxlbmd0aFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJXYXZlU2hhcGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgd2F2ZXNoYXBlciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IHRvIHRoZSB3YXZlc2hhcGVyIG5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc2hhcGVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBmcm9tIHRoZSB3YXZlc2hhcGVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc2hhcGVyO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZVNoYXBlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1hcHBpbmdcIiwgXCJsZW5ndGhcIl0pO1xuICAgICAgICBpZiAoaXNBcnJheShvcHRpb25zLm1hcHBpbmcpIHx8IG9wdGlvbnMubWFwcGluZyBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSkge1xuICAgICAgICAgICAgdGhpcy5jdXJ2ZSA9IEZsb2F0MzJBcnJheS5mcm9tKG9wdGlvbnMubWFwcGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNGdW5jdGlvbihvcHRpb25zLm1hcHBpbmcpKSB7XG4gICAgICAgICAgICB0aGlzLnNldE1hcChvcHRpb25zLm1hcHBpbmcsIG9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBsZW5ndGg6IDEwMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgbWFwcGluZyBmdW5jdGlvbiB0byBzZXQgdGhlIHZhbHVlIG9mIHRoZSBjdXJ2ZS5cbiAgICAgKiBAcGFyYW0gbWFwcGluZyBUaGUgZnVuY3Rpb24gdXNlZCB0byBkZWZpbmUgdGhlIHZhbHVlcy5cbiAgICAgKiAgICAgICAgICAgICAgICBUaGUgbWFwcGluZyBmdW5jdGlvbiB0YWtlIHR3byBhcmd1bWVudHM6XG4gICAgICogICAgICAgICAgICAgICAgdGhlIGZpcnN0IGlzIHRoZSB2YWx1ZSBhdCB0aGUgY3VycmVudCBwb3NpdGlvblxuICAgICAqICAgICAgICAgICAgICAgIHdoaWNoIGdvZXMgZnJvbSAtMSB0byAxIG92ZXIgdGhlIG51bWJlciBvZiBlbGVtZW50c1xuICAgICAqICAgICAgICAgICAgICAgIGluIHRoZSBjdXJ2ZSBhcnJheS4gVGhlIHNlY29uZCBhcmd1bWVudCBpcyB0aGUgYXJyYXkgcG9zaXRpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzaGFwZXIgPSBuZXcgVG9uZS5XYXZlU2hhcGVyKCk7XG4gICAgICogLy8gbWFwIHRoZSBpbnB1dCBzaWduYWwgZnJvbSBbLTEsIDFdIHRvIFswLCAxMF1cbiAgICAgKiBzaGFwZXIuc2V0TWFwKCh2YWwsIGluZGV4KSA9PiAodmFsICsgMSkgKiA1KTtcbiAgICAgKi9cbiAgICBzZXRNYXAobWFwcGluZywgbGVuZ3RoID0gMTAyNCkge1xuICAgICAgICBjb25zdCBhcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkID0gKGkgLyAobGVuIC0gMSkpICogMiAtIDE7XG4gICAgICAgICAgICBhcnJheVtpXSA9IG1hcHBpbmcobm9ybWFsaXplZCwgaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJ2ZSA9IGFycmF5O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IHRvIHNldCBhcyB0aGUgd2F2ZXNoYXBlciBjdXJ2ZS4gRm9yIGxpbmVhciBjdXJ2ZXNcbiAgICAgKiBhcnJheSBsZW5ndGggZG9lcyBub3QgbWFrZSBtdWNoIGRpZmZlcmVuY2UsIGJ1dCBmb3IgY29tcGxleCBjdXJ2ZXNcbiAgICAgKiBsb25nZXIgYXJyYXlzIHdpbGwgcHJvdmlkZSBzbW9vdGhlciBpbnRlcnBvbGF0aW9uLlxuICAgICAqL1xuICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5jdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGN1cnZlKG1hcHBpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmN1cnZlID0gbWFwcGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiBvdmVyc2FtcGxpbmcgKGlmIGFueSkgc2hvdWxkIGJlIHVzZWQgd2hlblxuICAgICAqIGFwcGx5aW5nIHRoZSBzaGFwaW5nIGN1cnZlLiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICBjb25zdCBpc092ZXJTYW1wbGVUeXBlID0gW1wibm9uZVwiLCBcIjJ4XCIsIFwiNHhcIl0uc29tZShzdHIgPT4gc3RyLmluY2x1ZGVzKG92ZXJzYW1wbGluZykpO1xuICAgICAgICBhc3NlcnQoaXNPdmVyU2FtcGxlVHlwZSwgXCJvdmVyc2FtcGxpbmcgbXVzdCBiZSBlaXRoZXIgJ25vbmUnLCAnMngnLCBvciAnNHgnXCIpO1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1XYXZlU2hhcGVyLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIEF1ZGlvVG9HYWluIGNvbnZlcnRzIGFuIGlucHV0IGluIEF1ZGlvUmFuZ2UgWy0xLDFdIHRvIE5vcm1hbFJhbmdlIFswLDFdLlxuICogU2VlIFtbR2FpblRvQXVkaW9dXS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEF1ZGlvVG9HYWluIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1ZGlvVG9HYWluXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ub3JtID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogeCA9PiAoeCArIDEpIC8gMixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBpbnB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbm9ybTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBHYWluUmFuZ2Ugb3V0cHV0IFswLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9ub3JtO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbm9ybS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1ZGlvVG9HYWluLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG4vKipcbiAqIE11bHRpcGx5IHR3byBpbmNvbWluZyBzaWduYWxzLiBPciwgaWYgYSBudW1iZXIgaXMgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yLFxuICogbXVsdGlwbGllcyB0aGUgaW5jb21pbmcgc2lnbmFsIGJ5IHRoYXQgdmFsdWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIG11bHRpcGx5IHR3byBzaWduYWxzXG4gKiBjb25zdCBtdWx0ID0gbmV3IFRvbmUuTXVsdGlwbHkoKTtcbiAqIGNvbnN0IHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMyk7XG4gKiBjb25zdCBzaWdCID0gbmV3IFRvbmUuU2lnbmFsKDQpO1xuICogc2lnQS5jb25uZWN0KG11bHQpO1xuICogc2lnQi5jb25uZWN0KG11bHQuZmFjdG9yKTtcbiAqIC8vIG91dHB1dCBvZiBtdWx0IGlzIDEyLlxuICogQGV4YW1wbGVcbiAqIC8vIG11bHRpcGx5IGEgc2lnbmFsIGFuZCBhIG51bWJlclxuICogY29uc3QgbXVsdCA9IG5ldyBUb25lLk11bHRpcGx5KDEwKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgyKS5jb25uZWN0KG11bHQpO1xuICogLy8gdGhlIG91dHB1dCBvZiBtdWx0IGlzIDIwLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgTXVsdGlwbHkgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpcGx5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGlwbHlcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIG92ZXJyaWRkZW4gb24gY29ubmVjdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGlwbHkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX211bHQgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mYWN0b3IgPSB0aGlzLl9wYXJhbSA9IHRoaXMuX211bHQuZ2FpbjtcbiAgICAgICAgdGhpcy5mYWN0b3Iuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGlwbHkuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEF1ZGlvVG9HYWluIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BdWRpb1RvR2FpblwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbi8qKlxuICogQW4gYW1wbGl0dWRlIG1vZHVsYXRlZCBvc2NpbGxhdG9yIG5vZGUuIEl0IGlzIGltcGxlbWVudGVkIHdpdGhcbiAqIHR3byBvc2NpbGxhdG9ycywgb25lIHdoaWNoIG1vZHVsYXRvcnMgdGhlIG90aGVyJ3MgYW1wbGl0dWRlXG4gKiB0aHJvdWdoIGEgZ2FpbiBub2RlLlxuICogYGBgXG4gKiAgICArLS0tLS0tLS0tLS0tLSsgICAgICAgKy0tLS0tLS0tLS0rXG4gKiAgICB8IENhcnJpZXIgT3NjICs+LS0tLS0tPiBHYWluTm9kZSB8XG4gKiAgICArLS0tLS0tLS0tLS0tLSsgICAgICAgfCAgICAgICAgICArLS0tPk91dHB1dFxuICogICAgICAgICAgICAgICAgICAgICAgKy0tLT4gZ2FpbiAgICAgfFxuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgfCAgICstLS0tLS0tLS0tK1xuICogfCBNb2R1bGF0b3IgT3NjICs+LS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhbU9zYyA9IG5ldyBUb25lLkFNT3NjaWxsYXRvcigzMCwgXCJzaW5lXCIsIFwic3F1YXJlXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4yLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEFNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFNT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29udmVydCB0aGUgLTEsMSBvdXRwdXQgdG8gMCwxXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUgPSBuZXcgQXVkaW9Ub0dhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLm1vZHVsYXRpb25UeXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX21vZHVsYXRpb25TY2FsZSwgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiaGFybW9uaWNpdHlcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBjYXJyaWVyIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG4vKipcbiAqIEZNT3NjaWxsYXRvciBpbXBsZW1lbnRzIGEgZnJlcXVlbmN5IG1vZHVsYXRpb24gc3ludGhlc2lzXG4gKiBgYGBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgICAgICstLS0tLS0tLS0tLS0tKyAgICAgfCBDYXJyaWVyIE9zYyB8XG4gKiB8IE1vZHVsYXRvciBPc2MgKz4tLS0tLS0tPiBHYWluTm9kZSAgICB8ICAgICB8ICAgICAgICAgICAgICstLS0+T3V0cHV0XG4gKiArLS0tLS0tLS0tLS0tLS0tKyAgICAgICAgfCAgICAgICAgICAgICArPi0tLS0+IGZyZXF1ZW5jeSAgIHxcbiAqICAgICAgICAgICAgICAgICAgICAgICArLS0+IGdhaW4gICAgICAgIHwgICAgICstLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgICAgICAgICAgICAgIHwgICstLS0tLS0tLS0tLS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLS0tKyAgIHxcbiAqIHwgbW9kdWxhdGlvbkluZGV4ICs+LS0rXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGZtT3NjID0gbmV3IFRvbmUuRk1Pc2NpbGxhdG9yKHtcbiAqIFx0XHRmcmVxdWVuY3k6IDIwMCxcbiAqIFx0XHR0eXBlOiBcInNxdWFyZVwiLFxuICogXHRcdG1vZHVsYXRpb25UeXBlOiBcInRyaWFuZ2xlXCIsXG4gKiBcdFx0aGFybW9uaWNpdHk6IDAuMixcbiAqIFx0XHRtb2R1bGF0aW9uSW5kZXg6IDNcbiAqIFx0fSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgRk1Pc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRk1Pc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKTtcbiAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX2NhcnJpZXIuZGV0dW5lO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMubW9kdWxhdGlvblR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMubW9kdWxhdGlvbkluZGV4LCB0aGlzLl9tb2R1bGF0aW9uTm9kZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibW9kdWxhdGlvbkluZGV4XCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiaGFybW9uaWNpdHlcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDIsXG4gICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuLyoqXG4gKiBQdWxzZU9zY2lsbGF0b3IgaXMgYW4gb3NjaWxsYXRvciB3aXRoIGNvbnRyb2wgb3ZlciBwdWxzZSB3aWR0aCxcbiAqIGFsc28ga25vd24gYXMgdGhlIGR1dHkgY3ljbGUuIEF0IDUwJSBkdXR5IGN5Y2xlICh3aWR0aCA9IDApIHRoZSB3YXZlIGlzXG4gKiBhIHNxdWFyZSB3YXZlLlxuICogW1JlYWQgbW9yZV0oaHR0cHM6Ly93aWdnbGV3YXZlLndvcmRwcmVzcy5jb20vMjAxNC8wOC8xNi9wdWxzZS13YXZlZm9ybXMtYW5kLWhhcm1vbmljcy8pLlxuICogYGBgXG4gKiAgICB3aWR0aCA9IC0wLjI1ICAgICAgICB3aWR0aCA9IDAuMCAgICAgICAgICB3aWR0aCA9IDAuMjVcbiAqXG4gKiAgICstLS0tLSsgICAgICAgICAgICArLS0tLS0tLSsgICAgICAgKyAgICArLS0tLS0tLSsgICAgICstK1xuICogICB8ICAgICB8ICAgICAgICAgICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgICAgICB8ICAgICB8XG4gKiAgIHwgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgfCAgICAgICAgICAgIHwgICAgIHxcbiAqICstKyAgICAgKy0tLS0tLS0rICAgICsgICAgICAgKy0tLS0tLS0rICAgICAgICAgICAgKy0tLS0tK1xuICpcbiAqXG4gKiAgICB3aWR0aCA9IC0wLjUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNVxuICpcbiAqICAgICArLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKyAgICstLS0rXG4gKiAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8XG4gKiAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8XG4gKiArLS0tKyAgICstLS0tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0rXG4gKlxuICpcbiAqICAgIHdpZHRoID0gLTAuNzUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC43NVxuICpcbiAqICAgICAgICstKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKyArLS0tLS0rXG4gKiAgICAgICB8IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgfFxuICogICAgICAgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHxcbiAqICstLS0tLSsgKy0tLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgcHVsc2UgPSBuZXcgVG9uZS5QdWxzZU9zY2lsbGF0b3IoNTAsIDAuNCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUHVsc2VPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwid2lkdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQdWxzZU9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGdhdGUgdGhlIHdpZHRoIGFtb3VudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaHJlc2hvbGQgdGhlIHNpZ25hbCB0byB0dXJuIGl0IGludG8gYSBzcXVhcmVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RocmVzaCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHZhbCA9PiB2YWwgPD0gMCA/IC0xIDogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQdWxzZU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImF1ZGlvUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLndpZHRoLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fdHJpYW5nbGUuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX3RyaWFuZ2xlLmRldHVuZTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuY2hhaW4odGhpcy5fdGhyZXNoLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMud2lkdGguY2hhaW4odGhpcy5fd2lkdGhHYXRlLCB0aGlzLl90aHJlc2gpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3aWR0aFwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInB1bHNlXCIsXG4gICAgICAgICAgICB3aWR0aDogMC4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5zdG9wKHRpbWUpO1xuICAgICAgICAvLyB0aGUgd2lkdGggaXMgc3RpbGwgY29ubmVjdGVkIHRvIHRoZSBvdXRwdXQuXG4gICAgICAgIC8vIHRoYXQgbmVlZHMgdG8gYmUgc3RvcHBlZCBhbHNvXG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJpYW5nbGUucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwdWxzZVwiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwdWxzZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZVR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHVsc2VcIi5cbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB1bHNlXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYXJ0aWFscyBvZiB0aGUgd2F2ZWZvcm0uIENhbm5vdCBzZXQgcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBObyBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlLlxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqSW50ZXJuYWwgdXNlKiBUaGUgY2FycmllciBvc2NpbGxhdG9yIHR5cGUgaXMgZmVkIHRocm91Z2ggdGhlXG4gICAgICogd2F2ZXNoYXBlciBub2RlIHRvIGNyZWF0ZSB0aGUgcHVsc2UuIFVzaW5nIGRpZmZlcmVudCBjYXJyaWVyIG9zY2lsbGF0b3JzXG4gICAgICogY2hhbmdlcyBvc2NpbGxhdG9yJ3MgYmVoYXZpb3IuXG4gICAgICovXG4gICAgc2V0IGNhcnJpZXJUeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwIG1ldGhvZC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RocmVzaC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVB1bHNlT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEZhdE9zY2lsbGF0b3IgaXMgYW4gYXJyYXkgb2Ygb3NjaWxsYXRvcnMgd2l0aCBkZXR1bmUgc3ByZWFkIGJldHdlZW4gdGhlIG9zY2lsbGF0b3JzXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcihcIkFiM1wiLCBcInNhd3Rvb3RoXCIsIDQwKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEZhdE9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInNwcmVhZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZhdE9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhcnJheSBvZiBvc2NpbGxhdG9yc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwic3ByZWFkXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IG9wdGlvbnMucGFydGlhbENvdW50O1xuICAgICAgICAvLyBzZXQgdGhlIGNvdW50IGluaXRpYWxseVxuICAgICAgICB0aGlzLmNvdW50ID0gb3B0aW9ucy5jb3VudDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvdW50OiAzLFxuICAgICAgICAgICAgc3ByZWFkOiAyMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2Muc3RhcnQodGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5zdG9wKHRpbWUpKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucmVzdGFydCh0aW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIG9zY2lsbGF0b3JzXG4gICAgICovXG4gICAgX2ZvckVhY2goaXRlcmF0b3IpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaXRlcmF0b3IodGhpcy5fb3NjaWxsYXRvcnNbaV0sIGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MudHlwZSA9IHR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycy4gSWYgXCJjb3VudFwiIGlzXG4gICAgICogc2V0IHRvIDMgb3NjaWxsYXRvcnMgYW5kIHRoZSBcInNwcmVhZFwiIGlzIHNldCB0byA0MCxcbiAgICAgKiB0aGUgdGhyZWUgb3NjaWxsYXRvcnMgd291bGQgYmUgZGV0dW5lZCBsaWtlIHRoaXM6IFstMjAsIDAsIDIwXVxuICAgICAqIGZvciBhIHRvdGFsIGRldHVuZSBzcHJlYWQgb2YgNDAgY2VudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogZmF0T3NjLnNwcmVhZCA9IDcwO1xuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zcHJlYWQ7XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX3NwcmVhZCA9IHNwcmVhZDtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gLXNwcmVhZCAvIDI7XG4gICAgICAgICAgICBjb25zdCBzdGVwID0gc3ByZWFkIC8gKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaCgob3NjLCBpKSA9PiBvc2MuZGV0dW5lLnZhbHVlID0gc3RhcnQgKyBzdGVwICogaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkZXR1bmVkIG9zY2lsbGF0b3JzLiBNdXN0IGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDEuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKFwiQyMzXCIsIFwic2F3dG9vdGhcIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gdXNlIDQgc2F3dG9vdGggb3NjaWxsYXRvcnNcbiAgICAgKiBmYXRPc2MuY291bnQgPSA0O1xuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aDtcbiAgICB9XG4gICAgc2V0IGNvdW50KGNvdW50KSB7XG4gICAgICAgIGFzc2VydFJhbmdlKGNvdW50LCAxKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAhPT0gY291bnQpIHtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2UgdGhlIHByZXZpb3VzIG9zY2lsbGF0b3JzXG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MuZGlzcG9zZSgpKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvc2MgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgdm9sdW1lOiAtNiAtIGNvdW50ICogMS4xLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLl90eXBlLFxuICAgICAgICAgICAgICAgICAgICBwaGFzZTogdGhpcy5fcGhhc2UgKyAoaSAvIGNvdW50KSAqIDM2MCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGlhbENvdW50OiB0aGlzLl9wYXJ0aWFsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIG9uc3RvcDogaSA9PT0gMCA/ICgpID0+IHRoaXMub25zdG9wKHRoaXMpIDogbm9PcCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIG9zYy5wYXJ0aWFscyA9IHRoaXMuX3BhcnRpYWxzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KG9zYy5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3Qob3NjLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgb3NjLmRldHVuZS5vdmVycmlkZGVuID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgb3NjLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldID0gb3NjO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gc2V0IHRoZSBzcHJlYWRcbiAgICAgICAgICAgIHRoaXMuc3ByZWFkID0gdGhpcy5fc3ByZWFkO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaCgob3NjLCBpKSA9PiBvc2MucGhhc2UgPSB0aGlzLl9waGFzZSArIChpIC8gdGhpcy5jb3VudCkgKiAzNjApO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5iYXNlVHlwZSA9IGJhc2VUeXBlKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuX29zY2lsbGF0b3JzWzBdLnR5cGU7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLl90eXBlID0gXCJjdXN0b21cIjtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5wYXJ0aWFscyA9IHBhcnRpYWxzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0ucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQpO1xuICAgICAgICB0aGlzLl90eXBlID0gdGhpcy5fb3NjaWxsYXRvcnNbMF0udHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZhdE9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBQdWxzZU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QdWxzZU9zY2lsbGF0b3JcIjtcbi8qKlxuICogUFdNT3NjaWxsYXRvciBtb2R1bGF0ZXMgdGhlIHdpZHRoIG9mIGEgVG9uZS5QdWxzZU9zY2lsbGF0b3JcbiAqIGF0IHRoZSBtb2R1bGF0aW9uRnJlcXVlbmN5LiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNvbnRpbnVvdXNseVxuICogY2hhbmdpbmcgdGhlIHRpbWJyZSBvZiB0aGUgb3NjaWxsYXRvciBieSBhbHRlcmluZyB0aGUgaGFybW9uaWNzXG4gKiBnZW5lcmF0ZWQuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IHB3bSA9IG5ldyBUb25lLlBXTU9zY2lsbGF0b3IoNjAsIDAuMykudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUFdNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtb2R1bGF0aW9uRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUFdNT3NjaWxsYXRvclwiO1xuICAgICAgICB0aGlzLnNvdXJjZVR5cGUgPSBcInB3bVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2NhbGUgdGhlIG9zY2lsbGF0b3Igc28gaXQgZG9lc24ndCBnbyBzaWxlbnRcbiAgICAgICAgICogYXQgdGhlIGV4dHJlbWUgdmFsdWVzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NhbGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUFdNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm1vZHVsYXRpb25GcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9wdWxzZSA9IG5ldyBQdWxzZU9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLm1vZHVsYXRpb25GcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjaGFuZ2UgdGhlIHB1bHNlIG9zY2lsbGF0b3IgdHlwZVxuICAgICAgICB0aGlzLl9wdWxzZS5jYXJyaWVyVHlwZSA9IFwic2luZVwiO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25GcmVxdWVuY3kgPSB0aGlzLl9wdWxzZS5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX21vZHVsYXRvci5kZXR1bmU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9zY2FsZSwgdGhpcy5fcHVsc2Uud2lkdGgpO1xuICAgICAgICB0aGlzLl9wdWxzZS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibW9kdWxhdGlvbkZyZXF1ZW5jeVwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkZyZXF1ZW5jeTogMC40LFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInB3bVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fcHVsc2Uuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3B1bHNlLnN0b3AodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJlc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9wdWxzZS5yZXN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwd21cIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHdtXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlVHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwd21cIi5cbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB3bVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBDYW5ub3Qgc2V0IHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGVcbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTm8gcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcHVsc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBXTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzTnVtYmVyLCBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgQU1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vQU1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBGYXRPc2NpbGxhdG9yIH0gZnJvbSBcIi4vRmF0T3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgRk1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vRk1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IFB1bHNlT3NjaWxsYXRvciB9IGZyb20gXCIuL1B1bHNlT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgUFdNT3NjaWxsYXRvciB9IGZyb20gXCIuL1BXTU9zY2lsbGF0b3JcIjtcbmNvbnN0IE9tbmlPc2NpbGxhdG9yU291cmNlTWFwID0ge1xuICAgIGFtOiBBTU9zY2lsbGF0b3IsXG4gICAgZmF0OiBGYXRPc2NpbGxhdG9yLFxuICAgIGZtOiBGTU9zY2lsbGF0b3IsXG4gICAgb3NjaWxsYXRvcjogT3NjaWxsYXRvcixcbiAgICBwdWxzZTogUHVsc2VPc2NpbGxhdG9yLFxuICAgIHB3bTogUFdNT3NjaWxsYXRvcixcbn07XG4vKipcbiAqIE9tbmlPc2NpbGxhdG9yIGFnZ3JlZ2F0ZXMgYWxsIG9mIHRoZSBvc2NpbGxhdG9yIHR5cGVzIGludG8gb25lLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoXCJDIzRcIiwgXCJwd21cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgT21uaU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPbW5pT3NjaWxsYXRvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgICAgICAvLyBzZXQgdGhlIG9wdGlvbnNcbiAgICAgICAgdGhpcy5zZXQob3B0aW9ucyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBGTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgQU1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQ2FuIGJlIGFueSBvZiB0aGUgYmFzaWMgdHlwZXM6IHNpbmUsIHNxdWFyZSwgdHJpYW5nbGUsIHNhd3Rvb3RoLiBPclxuICAgICAqIHByZWZpeCB0aGUgYmFzaWMgdHlwZXMgd2l0aCBcImZtXCIsIFwiYW1cIiwgb3IgXCJmYXRcIiB0byB1c2UgdGhlIEZNT3NjaWxsYXRvciwgQU1Pc2NpbGxhdG9yIG9yIEZhdE9zY2lsbGF0b3JcbiAgICAgKiB0eXBlcy4gVGhlIG9zY2lsbGF0b3IgY291bGQgYWxzbyBiZSBzZXQgdG8gXCJwd21cIiBvciBcInB1bHNlXCIuIEFsbCBvZiB0aGUgcGFyYW1ldGVycyBvZiB0aGVcbiAgICAgKiBvc2NpbGxhdG9yJ3MgY2xhc3MgYXJlIGFjY2Vzc2libGUgd2hlbiB0aGUgb3NjaWxsYXRvciBpcyBzZXQgdG8gdGhhdCB0eXBlLCBidXQgdGhyb3dzIGFuIGVycm9yXG4gICAgICogd2hlbiBpdCdzIG5vdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG9tbmlPc2MudHlwZSA9IFwicHdtXCI7XG4gICAgICogLy8gbW9kdWxhdGlvbkZyZXF1ZW5jeSBpcyBwYXJhbWV0ZXIgd2hpY2ggaXMgYXZhaWxhYmxlXG4gICAgICogLy8gb25seSB3aGVuIHRoZSB0eXBlIGlzIFwicHdtXCIuXG4gICAgICogb21uaU9zYy5tb2R1bGF0aW9uRnJlcXVlbmN5LnZhbHVlID0gMC41O1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICBsZXQgcHJlZml4ID0gXCJcIjtcbiAgICAgICAgaWYgKFtcImFtXCIsIFwiZm1cIiwgXCJmYXRcIl0uc29tZShwID0+IHRoaXMuX3NvdXJjZVR5cGUgPT09IHApKSB7XG4gICAgICAgICAgICBwcmVmaXggPSB0aGlzLl9zb3VyY2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcmVmaXggKyB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgaWYgKHR5cGUuc3Vic3RyKDAsIDIpID09PSBcImZtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJmbVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZS5zdWJzdHIoMCwgMikgPT09IFwiYW1cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImFtXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlLnN1YnN0cigwLCAzKSA9PT0gXCJmYXRcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImZhdFwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gXCJwd21cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcInB3bVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcInB1bHNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcIm9zY2lsbGF0b3JcIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHZhbHVlIGlzIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHR5cGUgaXMgbm90IFwiY3VzdG9tXCIuXG4gICAgICogVGhpcyBpcyBub3QgYXZhaWxhYmxlIG9uIFwicHdtXCIgYW5kIFwicHVsc2VcIiBvc2NpbGxhdG9yIHR5cGVzLlxuICAgICAqIFNlZSBbW09zY2lsbGF0b3IucGFydGlhbHNdXVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICBpZiAoIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSAmJiAhdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiYgIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldChwcm9wcykge1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHR5cGUgaXMgc2V0IGZpcnN0XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhcyhwcm9wcywgXCJ0eXBlXCIpICYmIHByb3BzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHByb3BzLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlbiBzZXQgdGhlIHJlc3RcbiAgICAgICAgc3VwZXIuc2V0KHByb3BzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3IgdG8gdGhlIGZyZXF1ZW5jeSBhbmQgZGV0dW5lIHNpZ25hbHNcbiAgICAgKi9cbiAgICBfY3JlYXRlTmV3T3NjaWxsYXRvcihvc2NUeXBlKSB7XG4gICAgICAgIGlmIChvc2NUeXBlICE9PSB0aGlzLl9zb3VyY2VUeXBlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VUeXBlID0gb3NjVHlwZTtcbiAgICAgICAgICAgIGNvbnN0IE9zY0NvbnN0cnVjdG9yID0gT21uaU9zY2lsbGF0b3JTb3VyY2VNYXBbb3NjVHlwZV07XG4gICAgICAgICAgICAvLyBzaG9ydCBkZWxheSB0byBhdm9pZCBjbGlja3Mgb24gdGhlIGNoYW5nZVxuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkT3NjID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgICAgICBvbGRPc2Muc3RvcChub3cpO1xuICAgICAgICAgICAgICAgIC8vIGRpc3Bvc2UgdGhlIG9sZCBvbmVcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiBvbGRPc2MuZGlzcG9zZSgpLCB0aGlzLmJsb2NrVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY0NvbnN0cnVjdG9yKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5vbnN0b3AgPSAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQobm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc291cmNlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoNDQwLCBcImZtc3F1YXJlXCIpO1xuICAgICAqIGNvbnNvbGUubG9nKG9tbmlPc2Muc291cmNlVHlwZSk7IC8vICdmbSdcbiAgICAgKi9cbiAgICBnZXQgc291cmNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZVR5cGU7XG4gICAgfVxuICAgIHNldCBzb3VyY2VUeXBlKHNUeXBlKSB7XG4gICAgICAgIC8vIHRoZSBiYXNldHlwZSBkZWZhdWx0cyB0byBzaW5lXG4gICAgICAgIGxldCBiYXNlVHlwZSA9IFwic2luZVwiO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvci50eXBlICE9PSBcInB3bVwiICYmIHRoaXMuX29zY2lsbGF0b3IudHlwZSAhPT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICBiYXNlVHlwZSA9IHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHR5cGVcbiAgICAgICAgaWYgKHNUeXBlID09PSBcImZtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiZm1cIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcImFtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiYW1cIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcImZhdFwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImZhdFwiICsgYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwib3NjaWxsYXRvclwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcInB1bHNlXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwicHdtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwicHdtXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2dldE9zY1R5cGUob3NjLCBzb3VyY2VUeXBlKSB7XG4gICAgICAgIHJldHVybiBvc2MgaW5zdGFuY2VvZiBPbW5pT3NjaWxsYXRvclNvdXJjZU1hcFtzb3VyY2VUeXBlXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gU2VlIFtbT3NjaWxsYXRvci5iYXNlVHlwZV1dXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoNDQwLCBcImZtc3F1YXJlNFwiKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvbW5pT3NjLnNvdXJjZVR5cGUsIG9tbmlPc2MuYmFzZVR5cGUsIG9tbmlPc2MucGFydGlhbENvdW50KTtcbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiZcbiAgICAgICAgICAgICF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpICYmXG4gICAgICAgICAgICBiYXNlVHlwZSAhPT0gXCJwdWxzZVwiICYmIGJhc2VUeXBlICE9PSBcInB3bVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmJhc2VUeXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHdpZHRoIG9mIHRoZSBvc2NpbGxhdG9yIHdoZW4gc291cmNlVHlwZSA9PT0gXCJwdWxzZVwiLlxuICAgICAqIFNlZSBbW1BXTU9zY2lsbGF0b3Iud2lkdGhdXVxuICAgICAqL1xuICAgIGdldCB3aWR0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGV0dW5lZCBvc2NpbGxhdG9ycyB3aGVuIHNvdXJjZVR5cGUgPT09IFwiZmF0XCIuXG4gICAgICogU2VlIFtbRmF0T3NjaWxsYXRvci5jb3VudF1dXG4gICAgICovXG4gICAgZ2V0IGNvdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IuY291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBjb3VudChjb3VudCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSAmJiBpc051bWJlcihjb3VudCkpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY291bnQgPSBjb3VudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycyB3aGVuIHNvdXJjZVR5cGUgPT09IFwiZmF0XCIuXG4gICAgICogU2VlIFtbRmF0T3NjaWxsYXRvci5jb3VudF1dXG4gICAgICovXG4gICAgZ2V0IHNwcmVhZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnNwcmVhZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikgJiYgaXNOdW1iZXIoc3ByZWFkKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zcHJlYWQgPSBzcHJlYWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yLiBPbmx5IGlmIHRoZSBvc2NpbGxhdG9yIGlzIHNldCB0byBcImFtXCIgb3IgXCJmbVwiIHR5cGVzLlxuICAgICAqIFNlZSBbW0FNT3NjaWxsYXRvcl1dIG9yIFtbRk1Pc2NpbGxhdG9yXV1cbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikgfHwgdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImFtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKG1UeXBlKSB7XG4gICAgICAgIGlmICgodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpIHx8IHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJhbVwiKSkgJiYgaXNTdHJpbmcobVR5cGUpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25UeXBlID0gbVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb24gaW5kZXggd2hlbiB0aGUgc291cmNlVHlwZSA9PT0gXCJmbVwiXG4gICAgICogU2VlIFtbRk1Pc2NpbGxhdG9yXV0uXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25JbmRleCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvbkluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYXJtb25pY2l0eSBpcyB0aGUgZnJlcXVlbmN5IHJhdGlvIGJldHdlZW4gdGhlIGNhcnJpZXIgYW5kIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvcnMuXG4gICAgICogU2VlIFtbQU1Pc2NpbGxhdG9yXV0gb3IgW1tGTU9zY2lsbGF0b3JdXVxuICAgICAqL1xuICAgIGdldCBoYXJtb25pY2l0eSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSB8fCB0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiYW1cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmhhcm1vbmljaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbW9kdWxhdGlvbkZyZXF1ZW5jeSBTaWduYWwgb2YgdGhlIG9zY2lsbGF0b3Igd2hlbiBzb3VyY2VUeXBlID09PSBcInB3bVwiXG4gICAgICogc2VlIFtbUFdNT3NjaWxsYXRvcl1dXG4gICAgICogQG1pbiAwLjFcbiAgICAgKiBAbWF4IDVcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvbkZyZXF1ZW5jeSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25GcmVxdWVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbW5pT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuLyoqXG4gKiBBZGQgYSBzaWduYWwgYW5kIGEgbnVtYmVyIG9yIHR3byBzaWduYWxzLiBXaGVuIG5vIHZhbHVlIGlzXG4gKiBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIFRvbmUuQWRkIHdpbGwgc3VtIGlucHV0IGFuZCBgYWRkZW5kYFxuICogSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIHRoZSBpdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBpbnB1dC5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFkZCA9IG5ldyBUb25lLkFkZCgyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGFkZC5hZGRlbmQuc2V0VmFsdWVBdFRpbWUoMSwgMC4yKTtcbiAqIFx0Y29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDIpO1xuICogXHQvLyBhZGQgYSBzaWduYWwgYW5kIGEgc2NhbGFyXG4gKiBcdHNpZ25hbC5jb25uZWN0KGFkZCk7XG4gKiBcdHNpZ25hbC5zZXRWYWx1ZUF0VGltZSgxLCAwLjEpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEFkZCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoQWRkLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBZGRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzdW1taW5nIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N1bSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB3aGljaCBpcyBhZGRlZCB0byB0aGUgaW5wdXQgc2lnbmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFkZGVuZCA9IHRoaXMuX3BhcmFtO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuX2NvbnN0YW50U291cmNlLCB0aGlzLl9zdW0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWRkLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4vQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIHNjYWxpbmcgb24gYW4gaW5wdXQgc2lnbmFsLlxuICogU2NhbGVzIGEgTm9ybWFsUmFuZ2UgaW5wdXQgdG8gYmV0d2VlblxuICogb3V0cHV0TWluIGFuZCBvdXRwdXRNYXguXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNjYWxlID0gbmV3IFRvbmUuU2NhbGUoNTAsIDEwMCk7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlKTtcbiAqIC8vIHRoZSBvdXRwdXQgb2Ygc2NhbGUgZXF1YWxzIDc1XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2FsZSBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTY2FsZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0ID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tYXggLSBvcHRpb25zLm1pbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FkZCA9IHRoaXMub3V0cHV0ID0gbmV3IEFkZCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5taW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taW4gPSBvcHRpb25zLm1pbjtcbiAgICAgICAgdGhpcy5fbWF4ID0gb3B0aW9ucy5tYXg7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlbiB0aGUgdmFsdWUgaW5wdXQgdmFsdWUgaXMgMC5cbiAgICAgKi9cbiAgICBnZXQgbWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWluO1xuICAgIH1cbiAgICBzZXQgbWluKG1pbikge1xuICAgICAgICB0aGlzLl9taW4gPSBtaW47XG4gICAgICAgIHRoaXMuX3NldFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG91dHB1dCB2YWx1ZS4gVGhpcyBudW1iZXIgaXMgb3V0cHV0IHdoZW4gdGhlIHZhbHVlIGlucHV0IHZhbHVlIGlzIDEuXG4gICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heDtcbiAgICB9XG4gICAgc2V0IG1heChtYXgpIHtcbiAgICAgICAgdGhpcy5fbWF4ID0gbWF4O1xuICAgICAgICB0aGlzLl9zZXRSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXQgdGhlIHZhbHVlc1xuICAgICAqL1xuICAgIF9zZXRSYW5nZSgpIHtcbiAgICAgICAgdGhpcy5fYWRkLnZhbHVlID0gdGhpcy5fbWluO1xuICAgICAgICB0aGlzLl9tdWx0LnZhbHVlID0gdGhpcy5fbWF4IC0gdGhpcy5fbWluO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX211bHQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TY2FsZS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBkaXNjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogVG9uZS5aZXJvIG91dHB1dHMgMCdzIGF0IGF1ZGlvLXJhdGUuIFRoZSByZWFzb24gdGhpcyBoYXMgdG8gYmVcbiAqIGl0J3Mgb3duIGNsYXNzIGlzIHRoYXQgbWFueSBicm93c2VycyBvcHRpbWl6ZSBvdXQgVG9uZS5TaWduYWxcbiAqIHdpdGggYSB2YWx1ZSBvZiAwIGFuZCB3aWxsIG5vdCBwcm9jZXNzIG5vZGVzIGZ1cnRoZXIgZG93biB0aGUgZ3JhcGguXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBaZXJvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFplcm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlplcm9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBnYWluIG5vZGUgd2hpY2ggY29ubmVjdHMgdGhlIGNvbnN0YW50IHNvdXJjZSB0byB0aGUgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nYWluID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPbmx5IG91dHB1dHMgMFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluO1xuICAgICAgICAvKipcbiAgICAgICAgICogbm8gaW5wdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMCksIHRoaXMuX2dhaW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgZGlzY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMCksIHRoaXMuX2dhaW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1aZXJvLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi8uLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgY29ubmVjdFNpZ25hbCwgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFplcm8gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1plcm9cIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG4vKipcbiAqIExGTyBzdGFuZHMgZm9yIGxvdyBmcmVxdWVuY3kgb3NjaWxsYXRvci4gTEZPIHByb2R1Y2VzIGFuIG91dHB1dCBzaWduYWxcbiAqIHdoaWNoIGNhbiBiZSBhdHRhY2hlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsXG4gKiBpbiBvcmRlciB0byBtb2R1bGF0ZSB0aGF0IHBhcmFtZXRlciB3aXRoIGFuIG9zY2lsbGF0b3IuIFRoZSBMRk8gY2FuXG4gKiBhbHNvIGJlIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0IHRvIHN0YXJ0L3N0b3AgYW5kIGNoYW5nZSB3aGVuIHRoZSB0ZW1wbyBjaGFuZ2VzLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBsZm8gPSBuZXcgVG9uZS5MRk8oXCI0blwiLCA0MDAsIDQwMDApLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIExGTyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhMRk8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtaW5cIiwgXCJtYXhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMRk9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB0aGF0IHRoZSBMRk8gb3V0cHV0cyB3aGVuIGl0J3Mgc3RvcHBlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgcHJpdmF0ZSBwbGFjZWhvbGRlciBmb3IgdGhlIHVuaXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl91bml0cyA9IFwibnVtYmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgaW5wdXQgdmFsdWUgaXMgY29udmVydGVkIHVzaW5nIHRoZSBbW3VuaXRzXV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY29udmVydCA9IHRydWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIG1ldGhvZHMgYm9ycm93ZWQgZnJvbSBQYXJhbVxuICAgICAgICAgKi9cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9mcm9tVHlwZSA9IFBhcmFtLnByb3RvdHlwZS5fZnJvbVR5cGU7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fdG9UeXBlID0gUGFyYW0ucHJvdG90eXBlLl90b1R5cGU7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5faXMgPSBQYXJhbS5wcm90b3R5cGUuX2lzO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2NsYW1wVmFsdWUgPSBQYXJhbS5wcm90b3R5cGUuX2NsYW1wVmFsdWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMRk8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtaW5cIiwgXCJtYXhcIl0pO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY2lsbGF0b3Iob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUdhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmFtcGxpdHVkZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFtcGxpdHVkZSA9IHRoaXMuX2FtcGxpdHVkZUdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbCA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiYXVkaW9SYW5nZVwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl96ZXJvcyA9IG5ldyBaZXJvKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hMmcgPSBuZXcgQXVkaW9Ub0dhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3NjYWxlciA9IHRoaXMub3V0cHV0ID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heDogb3B0aW9ucy5tYXgsXG4gICAgICAgICAgICBtaW46IG9wdGlvbnMubWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51bml0cyA9IG9wdGlvbnMudW5pdHM7XG4gICAgICAgIHRoaXMubWluID0gb3B0aW9ucy5taW47XG4gICAgICAgIHRoaXMubWF4ID0gb3B0aW9ucy5tYXg7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jaGFpbih0aGlzLl9hbXBsaXR1ZGVHYWluLCB0aGlzLl9hMmcsIHRoaXMuX3NjYWxlcik7XG4gICAgICAgIHRoaXMuX3plcm9zLmNvbm5lY3QodGhpcy5fYTJnKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5jb25uZWN0KHRoaXMuX2EyZyk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImFtcGxpdHVkZVwiLCBcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMucGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYW1wbGl0dWRlOiAxLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBcIjRuXCIsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIExGTy5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0aGUgTEZPIHdpbGwgc3RhcnRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIExGTy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdGhlIExGTyB3aWxsIHN0b3BcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnNldFZhbHVlQXRUaW1lKHRoaXMuX3N0b3BwZWRWYWx1ZSwgdGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHN0YXJ0L3N0b3AvcGF1c2UgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAqIGFuZCB0aGUgZnJlcXVlbmN5IHRvIHRoZSBicG0gb2YgdGhlIHRyYW5zcG9ydFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGZvID0gbmV3IFRvbmUuTEZPKFwiOG5cIik7XG4gICAgICogbGZvLnN5bmMoKS5zdGFydCgwKTtcbiAgICAgKiAvLyB0aGUgcmF0ZSBvZiB0aGUgTEZPIHdpbGwgYWx3YXlzIGJlIGFuIGVpZ2h0aCBub3RlLCBldmVuIGFzIHRoZSB0ZW1wbyBjaGFuZ2VzXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zeW5jKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogdW5zeW5jIHRoZSBMRk8gZnJvbSB0cmFuc3BvcnQgY29udHJvbFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmNGcmVxdWVuY3koKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFmdGVyIHRoZSBvc2NpbGxhdG9yIHdhdmVmb3JtIGlzIHVwZGF0ZWQsIHJlc2V0IHRoZSBgX3N0b3BwZWRTaWduYWxgIHZhbHVlIHRvIG1hdGNoIHRoZSB1cGRhdGVkIHdhdmVmb3JtXG4gICAgICovXG4gICAgX3NldFN0b3BwZWRWYWx1ZSgpIHtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gdGhpcy5fb3NjaWxsYXRvci5nZXRJbml0aWFsVmFsdWUoKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC52YWx1ZSA9IHRoaXMuX3N0b3BwZWRWYWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9zY2FsZXIubWluKTtcbiAgICB9XG4gICAgc2V0IG1pbihtaW4pIHtcbiAgICAgICAgbWluID0gdGhpcy5fZnJvbVR5cGUobWluKTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLm1pbiA9IG1pbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9zY2FsZXIubWF4KTtcbiAgICB9XG4gICAgc2V0IG1heChtYXgpIHtcbiAgICAgICAgbWF4ID0gdGhpcy5fZnJvbVR5cGUobWF4KTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLm1heCA9IG1heDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3I6IFNlZSBbW09zY2lsbGF0b3IudHlwZV1dXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fc2V0U3RvcHBlZFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yJ3MgcGFydGlhbHMgYXJyYXk6IFNlZSBbW09zY2lsbGF0b3IucGFydGlhbHNdXVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3NldFN0b3BwZWRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGhhc2Ugb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9zZXRTdG9wcGVkVmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG91dHB1dCB1bml0cyBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCB1bml0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VuaXRzO1xuICAgIH1cbiAgICBzZXQgdW5pdHModmFsKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNaW4gPSB0aGlzLm1pbjtcbiAgICAgICAgY29uc3QgY3VycmVudE1heCA9IHRoaXMubWF4O1xuICAgICAgICAvLyBjb252ZXJ0IHRoZSBtaW4gYW5kIHRoZSBtYXhcbiAgICAgICAgdGhpcy5fdW5pdHMgPSB2YWw7XG4gICAgICAgIHRoaXMubWluID0gY3VycmVudE1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBjdXJyZW50TWF4O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG5vZGUgdGhlIGRlc3RpbmF0aW9uIHRvIGNvbm5lY3QgdG9cbiAgICAgKiBAcGFyYW0gb3V0cHV0TnVtIHRoZSBvcHRpb25hbCBvdXRwdXQgbnVtYmVyXG4gICAgICogQHBhcmFtIGlucHV0TnVtIHRoZSBpbnB1dCBudW1iZXJcbiAgICAgKi9cbiAgICBjb25uZWN0KG5vZGUsIG91dHB1dE51bSwgaW5wdXROdW0pIHtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBQYXJhbSB8fCBub2RlIGluc3RhbmNlb2YgU2lnbmFsKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnZlcnQgPSBub2RlLmNvbnZlcnQ7XG4gICAgICAgICAgICB0aGlzLnVuaXRzID0gbm9kZS51bml0cztcbiAgICAgICAgfVxuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIG5vZGUsIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3plcm9zLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYTJnLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYW1wbGl0dWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TEZPLmpzLm1hcCIsImltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIG51bWJlciBpcyBpbiB0aGUgZ2l2ZW4gcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5nZShtaW4sIG1heCA9IEluZmluaXR5KSB7XG4gICAgY29uc3QgdmFsdWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2UobmV3VmFsdWUsIG1pbiwgbWF4KTtcbiAgICAgICAgICAgICAgICB2YWx1ZU1hcC5zZXQodGhpcywgbmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuLyoqXG4gKiBDb252ZXJ0IHRoZSB0aW1lIHRvIHNlY29uZHMgYW5kIGFzc2VydCB0aGF0IHRoZSB0aW1lIGlzIGluIGJldHdlZW4gdGhlIHR3b1xuICogdmFsdWVzIHdoZW4gYmVpbmcgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGltZVJhbmdlKG1pbiwgbWF4ID0gSW5maW5pdHkpIHtcbiAgICBjb25zdCB2YWx1ZU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZU1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhuZXdWYWx1ZSksIG1pbiwgbWF4KTtcbiAgICAgICAgICAgICAgICB2YWx1ZU1hcC5zZXQodGhpcywgbmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVjb3JhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciwgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc1VuZGVmIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQnVmZmVyU291cmNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIFBsYXllciBpcyBhbiBhdWRpbyBmaWxlIHBsYXllciB3aXRoIHN0YXJ0LCBsb29wLCBhbmQgc3RvcCBmdW5jdGlvbnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvZ29uZ18xLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBwbGF5IGFzIHNvb24gYXMgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUGxheWVyIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGxheWVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGFjdGl2ZSBidWZmZXIgc291cmNlIG5vZGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gbmV3IFNldCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcih7XG4gICAgICAgICAgICBvbmxvYWQ6IHRoaXMuX29ubG9hZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSxcbiAgICAgICAgICAgIG9uZXJyb3I6IG9wdGlvbnMub25lcnJvcixcbiAgICAgICAgICAgIHJldmVyc2U6IG9wdGlvbnMucmV2ZXJzZSxcbiAgICAgICAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF1dG9zdGFydCA9IG9wdGlvbnMuYXV0b3N0YXJ0O1xuICAgICAgICB0aGlzLl9sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXV0b3N0YXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2FkIHRoZSBhdWRpbyBmaWxlIGFzIGFuIGF1ZGlvIGJ1ZmZlci5cbiAgICAgKiBEZWNvZGVzIHRoZSBhdWRpbyBhc3luY2hyb25vdXNseSBhbmQgaW52b2tlc1xuICAgICAqIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG4gICAgICogTm90ZTogdGhpcyBkb2VzIG5vdCBuZWVkIHRvIGJlIGNhbGxlZCBpZiBhIHVybFxuICAgICAqIHdhcyBwYXNzZWQgaW4gdG8gdGhlIGNvbnN0cnVjdG9yLiBPbmx5IHVzZSB0aGlzXG4gICAgICogaWYgeW91IHdhbnQgdG8gbWFudWFsbHkgbG9hZCBhIG5ldyB1cmwuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC4gRmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl9idWZmZXIubG9hZCh1cmwpO1xuICAgICAgICAgICAgdGhpcy5fb25sb2FkKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGNhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcyBsb2FkZWQuXG4gICAgICovXG4gICAgX29ubG9hZChjYWxsYmFjayA9IG5vT3ApIHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgaWYgKHRoaXMuYXV0b3N0YXJ0KSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgY2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGRvbmUgcGxheWluZy5cbiAgICAgKi9cbiAgICBfb25Tb3VyY2VFbmQoc291cmNlKSB7XG4gICAgICAgIC8vIGludm9rZSB0aGUgb25zdG9wIGZ1bmN0aW9uXG4gICAgICAgIHRoaXMub25zdG9wKHRoaXMpO1xuICAgICAgICAvLyBkZWxldGUgdGhlIHNvdXJjZSBmcm9tIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmRlbGV0ZShzb3VyY2UpO1xuICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcy5zaXplID09PSAwICYmICF0aGlzLl9zeW5jZWQgJiZcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSAnaW1wbGljaXRFbmQnIGV2ZW50IGFuZCByZXBsYWNlIHdpdGggYW4gZXhwbGljaXQgZW5kXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGhpcy5ub3coKSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUGxheSB0aGUgYnVmZmVyIGF0IHRoZSBnaXZlbiBzdGFydFRpbWUuIE9wdGlvbmFsbHkgYWRkIGFuIG9mZnNldFxuICAgICAqIGFuZC9vciBkdXJhdGlvbiB3aGljaCB3aWxsIHBsYXkgdGhlIGJ1ZmZlciBmcm9tIGEgcG9zaXRpb25cbiAgICAgKiB3aXRoaW4gdGhlIGJ1ZmZlciBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLCBpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBzdXBlci5zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydChzdGFydFRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgLy8gaWYgaXQncyBhIGxvb3AgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIHRoZSBsb29wU3RhcnQgcG9pbnRcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG9mZnNldCBpcyAwXG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgdmFsdWVzIGluIHNlY29uZHNcbiAgICAgICAgY29uc3QgY29tcHV0ZWRPZmZzZXQgPSB0aGlzLnRvU2Vjb25kcyhvZmZzZXQpO1xuICAgICAgICAvLyBjb21wdXRlIHRoZSBkdXJhdGlvbiB3aGljaCBpcyBlaXRoZXIgdGhlIHBhc3NlZCBpbiBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLmR1cmF0aW9uIC0gb2Zmc2V0XG4gICAgICAgIGNvbnN0IG9yaWdEdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgICAgICBkdXJhdGlvbiA9IGRlZmF1bHRBcmcoZHVyYXRpb24sIE1hdGgubWF4KHRoaXMuX2J1ZmZlci5kdXJhdGlvbiAtIGNvbXB1dGVkT2Zmc2V0LCAwKSk7XG4gICAgICAgIGxldCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAvLyBzY2FsZSBpdCBieSB0aGUgcGxheWJhY2sgcmF0ZVxuICAgICAgICBjb21wdXRlZER1cmF0aW9uID0gY29tcHV0ZWREdXJhdGlvbiAvIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICAgICAgLy8gZ2V0IHRoZSBzdGFydCB0aW1lXG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIHNvdXJjZVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICB1cmw6IHRoaXMuX2J1ZmZlcixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZhZGVJbjogdGhpcy5mYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLmZhZGVPdXQsXG4gICAgICAgICAgICBsb29wOiB0aGlzLl9sb29wLFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5fbG9vcEVuZCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5fbG9vcFN0YXJ0LFxuICAgICAgICAgICAgb25lbmRlZDogdGhpcy5fb25Tb3VyY2VFbmQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5fcGxheWJhY2tSYXRlLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgLy8gc2V0IHRoZSBsb29waW5nIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCF0aGlzLl9sb29wICYmICF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0YXJ0VGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgbG9vcGluZywgc2V0IHRoZSBzdGF0ZSBjaGFuZ2UgYXQgdGhlIGVuZCBvZiB0aGUgc2FtcGxlXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgc3RhcnRUaW1lICsgY29tcHV0ZWREdXJhdGlvbiwge1xuICAgICAgICAgICAgICAgIGltcGxpY2l0RW5kOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhcnJheSBvZiBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmFkZChzb3VyY2UpO1xuICAgICAgICAvLyBzdGFydCBpdFxuICAgICAgICBpZiAodGhpcy5fbG9vcCAmJiBpc1VuZGVmKG9yaWdEdXJhdGlvbikpIHtcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydChzdGFydFRpbWUsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHN1YnRyYWN0IHRoZSBmYWRlIG91dCB0aW1lXG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQoc3RhcnRUaW1lLCBjb21wdXRlZE9mZnNldCwgY29tcHV0ZWREdXJhdGlvbiAtIHRoaXMudG9TZWNvbmRzKHRoaXMuZmFkZU91dCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgcGxheWJhY2suXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbmQgdGhlbiByZXN0YXJ0IHRoZSBwbGF5ZXIgZnJvbSB0aGUgYmVnaW5uaW5nIChvciBvZmZzZXQpXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLFxuICAgICAqIFx0XHRcdFx0XHRpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHN1cGVyLnJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWVrIHRvIGEgc3BlY2lmaWMgdGltZSBpbiB0aGUgcGxheWVyJ3MgYnVmZmVyLiBJZiB0aGVcbiAgICAgKiBzb3VyY2UgaXMgbm8gbG9uZ2VyIHBsYXlpbmcgYXQgdGhhdCB0aW1lLCBpdCB3aWxsIHN0b3AuXG4gICAgICogQHBhcmFtIG9mZnNldCBUaGUgdGltZSB0byBzZWVrIHRvLlxuICAgICAqIEBwYXJhbSB3aGVuIFRoZSB0aW1lIGZvciB0aGUgc2VlayBldmVudCB0byBvY2N1ci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2d1cmdsaW5nX3RoZXJlbWluXzEubXAzXCIsICgpID0+IHtcbiAgICAgKiBcdHBsYXllci5zdGFydCgpO1xuICAgICAqIFx0Ly8gc2VlayB0byB0aGUgb2Zmc2V0IGluIDEgc2Vjb25kIGZyb20gbm93XG4gICAgICogXHRwbGF5ZXIuc2VlaygwLjQsIFwiKzFcIik7XG4gICAgICogfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIHNlZWsob2Zmc2V0LCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkT2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgY3VycmVudGx5IHBsYXlpbmcsIHN0b3AgaXRcbiAgICAgICAgICAgIHRoaXMuX3N0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIC8vIHJlc3RhcnQgaXQgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0KGNvbXB1dGVkVGltZSwgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIGVuZC4gV2lsbCBvbmx5IGxvb3AgaWYgbG9vcCBpcyBzZXQgdG8gdHJ1ZS5cbiAgICAgKiBAcGFyYW0gbG9vcFN0YXJ0IFRoZSBsb29wIHN0YXJ0IHRpbWVcbiAgICAgKiBAcGFyYW0gbG9vcEVuZCBUaGUgbG9vcCBlbmQgdGltZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvbWFsZXZvaWNlc19hYTJfRjMubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBsb29wIGJldHdlZW4gdGhlIGdpdmVuIHBvaW50c1xuICAgICAqIHBsYXllci5zZXRMb29wUG9pbnRzKDAuMiwgMC4zKTtcbiAgICAgKiBwbGF5ZXIubG9vcCA9IHRydWU7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0TG9vcFBvaW50cyhsb29wU3RhcnQsIGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKGxvb3BTdGFydCksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZXQgdGhlIGN1cnJlbnQgc291cmNlXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3BTdGFydCA9IGxvb3BTdGFydDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKGxvb3BFbmQpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2V0IHRoZSBjdXJyZW50IHNvdXJjZVxuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgYmVsb25naW5nIHRvIHRoZSBwbGF5ZXIuXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9icmVha2JlYXQubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwbGF5ZXIubG9vcCA9IHRydWU7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIC8vIGlmIG5vIGNoYW5nZSwgZG8gbm90aGluZ1xuICAgICAgICBpZiAodGhpcy5fbG9vcCA9PT0gbG9vcCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICAvLyBzZXQgdGhlIGxvb3Agb2YgYWxsIG9mIHRoZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3AgPSBsb29wO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGxvb3ApIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbmV4dCBzdG9wRXZlbnRcbiAgICAgICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0b3BwZWRcIiwgdGhpcy5ub3coKSk7XG4gICAgICAgICAgICBpZiAoc3RvcEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBOb3JtYWwgc3BlZWQgaXMgMS4gVGhlIHBpdGNoIHdpbGwgY2hhbmdlIHdpdGggdGhlIHBsYXliYWNrIHJhdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9mZW1hbGV2b2ljZXNfYWEyX0E1Lm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gcGxheSBhdCAxLzQgc3BlZWRcbiAgICAgKiBwbGF5ZXIucGxheWJhY2tSYXRlID0gMC4yNTtcbiAgICAgKiAvLyBwbGF5IGFzIHNvb24gYXMgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBzdG9wIGV2ZW50IHNpbmNlIGl0J3MgYXQgYSBkaWZmZXJlbnQgdGltZSBub3dcbiAgICAgICAgY29uc3Qgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TmV4dFN0YXRlKFwic3RvcHBlZFwiLCBub3cpO1xuICAgICAgICBpZiAoc3RvcEV2ZW50ICYmIHN0b3BFdmVudC5pbXBsaWNpdEVuZCkge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLmNhbmNlbFN0b3AoKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IGFsbCB0aGUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUuc2V0VmFsdWVBdFRpbWUocmF0ZSwgbm93KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgc2hvdWxkIGJlIHJldmVyc2VkXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9jaGltZV8xLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogcGxheWVyLnJldmVyc2UgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCByZXZlcnNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLnJldmVyc2U7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICB0aGlzLl9idWZmZXIucmV2ZXJzZSA9IHJldjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmxvYWRlZDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICAvLyBkaXNjb25uZWN0IGFsbCBvZiB0aGUgcGxheWVyc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgUGxheWVyLnByb3RvdHlwZSwgXCJmYWRlSW5cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgUGxheWVyLnByb3RvdHlwZSwgXCJmYWRlT3V0XCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbGF5ZXIuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBQbGF5ZXIgfSBmcm9tIFwiLi9QbGF5ZXJcIjtcbi8qKlxuICogUGxheWVycyBjb21iaW5lcyBtdWx0aXBsZSBbW1BsYXllcl1dIG9iamVjdHMuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBQbGF5ZXJzIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllcnMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCJdLCBcInVybHNcIikpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsYXllcnNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBsYXllcnMgaGFzIG5vIGlucHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb250YWluZXIgb2YgYWxsIG9mIHRoZSBwbGF5ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wbGF5ZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVycy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgdm9sdW1lIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBUb25lQXVkaW9CdWZmZXJzKHtcbiAgICAgICAgICAgIHVybHM6IG9wdGlvbnMudXJscyxcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3JcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG11dGUgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlSW4gdGltZSBvZiB0aGUgZW52ZWxvcGUgYXBwbGllZCB0byB0aGUgc291cmNlLlxuICAgICAqL1xuICAgIGdldCBmYWRlSW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlSW47XG4gICAgfVxuICAgIHNldCBmYWRlSW4oZmFkZUluKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IGZhZGVJbjtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiB7XG4gICAgICAgICAgICBwbGF5ZXIuZmFkZUluID0gZmFkZUluO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgZWFjaCBvZiB0aGUgc291cmNlcy5cbiAgICAgKi9cbiAgICBnZXQgZmFkZU91dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG4gICAgfVxuICAgIHNldCBmYWRlT3V0KGZhZGVPdXQpIHtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IGZhZGVPdXQ7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4ge1xuICAgICAgICAgICAgcGxheWVyLmZhZGVPdXQgPSBmYWRlT3V0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXRlIG9mIHRoZSBwbGF5ZXJzIG9iamVjdC4gUmV0dXJucyBcInN0YXJ0ZWRcIiBpZiBhbnkgb2YgdGhlIHBsYXllcnMgYXJlIHBsYXlpbmcuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICBjb25zdCBwbGF5aW5nID0gQXJyYXkuZnJvbSh0aGlzLl9wbGF5ZXJzKS5zb21lKChbXywgcGxheWVyXSkgPT4gcGxheWVyLnN0YXRlID09PSBcInN0YXJ0ZWRcIik7XG4gICAgICAgIHJldHVybiBwbGF5aW5nID8gXCJzdGFydGVkXCIgOiBcInN0b3BwZWRcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJ1ZSBpZiB0aGUgYnVmZmVycyBvYmplY3QgaGFzIGEgYnVmZmVyIGJ5IHRoYXQgbmFtZS5cbiAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmhhcyhuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgcGxheWVyIGJ5IG5hbWUuXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUgcGxheWVycyBuYW1lIGFzIGRlZmluZWQgaW4gdGhlIGNvbnN0cnVjdG9yIG9iamVjdCBvciBgYWRkYCBtZXRob2QuXG4gICAgICovXG4gICAgcGxheWVyKG5hbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuaGFzKG5hbWUpLCBgTm8gUGxheWVyIHdpdGggdGhlIG5hbWUgJHtuYW1lfSBleGlzdHMgb24gdGhpcyBvYmplY3RgKTtcbiAgICAgICAgaWYgKCF0aGlzLl9wbGF5ZXJzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgY29uc3QgcGxheWVyID0gbmV3IFBsYXllcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGZhZGVJbjogdGhpcy5fZmFkZUluLFxuICAgICAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX2ZhZGVPdXQsXG4gICAgICAgICAgICAgICAgdXJsOiB0aGlzLl9idWZmZXJzLmdldChuYW1lKSxcbiAgICAgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fcGxheWVycy5zZXQobmFtZSwgcGxheWVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWVycy5nZXQobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGFsbCB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmxvYWRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgcGxheWVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgUGxheWVyc1xuICAgICAqIEBwYXJhbSAgbmFtZSBBIHVuaXF1ZSBuYW1lIHRvIGdpdmUgdGhlIHBsYXllclxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZXIgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGFkZChuYW1lLCB1cmwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5fYnVmZmVycy5oYXMobmFtZSksIFwiQSBidWZmZXIgd2l0aCB0aGF0IG5hbWUgYWxyZWFkeSBleGlzdHMgb24gdGhpcyBvYmplY3RcIik7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5hbWUsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbGwgb2YgdGhlIHBsYXllcnMgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0byBzdG9wIGFsbCBvZiB0aGUgcGxheWVycy5cbiAgICAgKi9cbiAgICBzdG9wQWxsKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiBwbGF5ZXIuc3RvcCh0aW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiBwbGF5ZXIuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsYXllcnMuanMubWFwIiwiaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBDbG9jayB9IGZyb20gXCIuLi8uLi9jb3JlL2Nsb2NrL0Nsb2NrXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vVG9uZUJ1ZmZlclNvdXJjZVwiO1xuaW1wb3J0IHsgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEdyYWluUGxheWVyIGltcGxlbWVudHMgW2dyYW51bGFyIHN5bnRoZXNpc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvR3JhbnVsYXJfc3ludGhlc2lzKS5cbiAqIEdyYW51bGFyIFN5bnRoZXNpcyBlbmFibGVzIHlvdSB0byBhZGp1c3QgcGl0Y2ggYW5kIHBsYXliYWNrIHJhdGUgaW5kZXBlbmRlbnRseS4gVGhlIGdyYWluU2l6ZSBpcyB0aGVcbiAqIGFtb3VudCBvZiB0aW1lIGVhY2ggc21hbGwgY2h1bmsgb2YgYXVkaW8gaXMgcGxheWVkIGZvciBhbmQgdGhlIG92ZXJsYXAgaXMgdGhlXG4gKiBhbW91bnQgb2YgY3Jvc3NmYWRpbmcgdHJhbnNpdGlvbiB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmFpblBsYXllciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyYWluUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR3JhaW5QbGF5ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEludGVybmFsIGxvb3BTdGFydCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEludGVybmFsIGxvb3BTdGFydCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGN1cnJlbnRseSBwbGF5aW5nIEJ1ZmZlclNvdXJjZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyYWluUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKHtcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgICAgICByZXZlcnNlOiBvcHRpb25zLnJldmVyc2UsXG4gICAgICAgICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sgPSBuZXcgQ2xvY2soe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSAvIG9wdGlvbnMuZ3JhaW5TaXplXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fZ3JhaW5TaXplID0gb3B0aW9ucy5ncmFpblNpemU7XG4gICAgICAgIHRoaXMuX292ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gb3B0aW9ucy5kZXR1bmU7XG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIHRoaXMub3ZlcmxhcCA9IG9wdGlvbnMub3ZlcmxhcDtcbiAgICAgICAgdGhpcy5sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IG9wdGlvbnMuZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9IG9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdG9wXCIsIHRoaXMuX29uc3RvcC5iaW5kKHRoaXMpKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG92ZXJsYXA6IDAuMSxcbiAgICAgICAgICAgIGdyYWluU2l6ZTogMC4yLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgb2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBncmFpblNpemUgPSAxIC8gdGhpcy5fY2xvY2suZnJlcXVlbmN5LmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLl9jbG9jay5zdGFydCh0aW1lLCBvZmZzZXQgLyBncmFpblNpemUpO1xuICAgICAgICBpZiAoZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIGFuZCB0aGVuIHJlc3RhcnQgdGhlIHBsYXllciBmcm9tIHRoZSBiZWdpbm5pbmcgKG9yIG9mZnNldClcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcGxheWVyIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc2FtcGxlIHRvIHN0YXJ0IGF0LlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb24gaXMgZ2l2ZW4sXG4gICAgICogXHRcdFx0XHRcdGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgc3VwZXIucmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0b3AgbWV0aG9kXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gdGhlIGNsb2NrIGlzIHN0b3BwZWRcbiAgICAgKi9cbiAgICBfb25zdG9wKHRpbWUpIHtcbiAgICAgICAgLy8gc3RvcCB0aGUgcGxheWVyc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4ge1xuICAgICAgICAgICAgc291cmNlLmZhZGVPdXQgPSAwO1xuICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCBvbiBlYWNoIGNsb2NrIHRpY2suIHNjaGVkdWxlZCBhIG5ldyBncmFpbiBhdCB0aGlzIHRpbWUuXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICAvLyBjaGVjayBpZiBpdCBzaG91bGQgc3RvcCBsb29waW5nXG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRpY2tzICogdGhpcy5fZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLmxvZyhcIm9mZnNldFwiLCBvZmZzZXQpO1xuICAgICAgICBpZiAoIXRoaXMubG9vcCAmJiBvZmZzZXQgPiB0aGlzLmJ1ZmZlci5kdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUsIHRoZSBmYWRlIGluIHNob3VsZCBiZSAwXG4gICAgICAgIGNvbnN0IGZhZGVJbiA9IG9mZnNldCA8IHRoaXMuX292ZXJsYXAgPyAwIDogdGhpcy5fb3ZlcmxhcDtcbiAgICAgICAgLy8gY3JlYXRlIGEgYnVmZmVyIHNvdXJjZVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1cmw6IHRoaXMuYnVmZmVyLFxuICAgICAgICAgICAgZmFkZUluOiBmYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9vdmVybGFwLFxuICAgICAgICAgICAgbG9vcDogdGhpcy5sb29wLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLl9sb29wU3RhcnQsXG4gICAgICAgICAgICBsb29wRW5kOiB0aGlzLl9sb29wRW5kLFxuICAgICAgICAgICAgLy8gY29tcHV0ZSB0aGUgcGxheWJhY2tSYXRlIGJhc2VkIG9uIHRoZSBkZXR1bmVcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKHRoaXMuZGV0dW5lIC8gMTAwKVxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgc291cmNlLnN0YXJ0KHRpbWUsIHRoaXMuX2dyYWluU2l6ZSAqIHRpY2tzKTtcbiAgICAgICAgc291cmNlLnN0b3AodGltZSArIHRoaXMuX2dyYWluU2l6ZSAvIHRoaXMucGxheWJhY2tSYXRlKTtcbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnB1c2goc291cmNlKTtcbiAgICAgICAgLy8gcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG4gICAgICAgIHNvdXJjZS5vbmVuZGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9hY3RpdmVTb3VyY2VzLmluZGV4T2Yoc291cmNlKTtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBzYW1wbGVcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgYXNzZXJ0UmFuZ2UocmF0ZSwgMC4wMDEpO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IHRoaXMuX2dyYWluU2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3Agc3RhcnQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHModGltZSksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3AgZW5kIHRpbWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGlyZWN0aW9uIHRoZSBidWZmZXIgc2hvdWxkIHBsYXkgaW5cbiAgICAgKi9cbiAgICBnZXQgcmV2ZXJzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLnJldmVyc2U7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICB0aGlzLmJ1ZmZlci5yZXZlcnNlID0gcmV2O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2l6ZSBvZiBlYWNoIGNodW5rIG9mIGF1ZGlvIHRoYXQgdGhlXG4gICAgICogYnVmZmVyIGlzIGNob3BwZWQgaW50byBhbmQgcGxheWVkIGJhY2sgYXQuXG4gICAgICovXG4gICAgZ2V0IGdyYWluU2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dyYWluU2l6ZTtcbiAgICB9XG4gICAgc2V0IGdyYWluU2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2dyYWluU2l6ZSA9IHRoaXMudG9TZWNvbmRzKHNpemUpO1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUodGhpcy5fcGxheWJhY2tSYXRlIC8gdGhpcy5fZ3JhaW5TaXplLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIG9mIHRoZSBjcm9zcy1mYWRlIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG4gICAgICovXG4gICAgZ2V0IG92ZXJsYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vdmVybGFwO1xuICAgIH1cbiAgICBzZXQgb3ZlcmxhcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZShjb21wdXRlZFRpbWUsIDApO1xuICAgICAgICB0aGlzLl9vdmVybGFwID0gY29tcHV0ZWRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBhbGwgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIubG9hZGVkO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4gc291cmNlLmRpc3Bvc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdyYWluUGxheWVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL05vaXNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Vc2VyTWVkaWFcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9BTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvRk1Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1B1bHNlT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9GYXRPc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1BXTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0xGT1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9QbGF5ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9QbGF5ZXJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvR3JhaW5QbGF5ZXJcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIFJldHVybiB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgYW4gaW5jb21pbmcgc2lnbmFsLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYWJzID0gbmV3IFRvbmUuQWJzKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMSk7XG4gKiBcdHNpZ25hbC5yYW1wVG8oLTEsIDAuNSk7XG4gKiBcdHNpZ25hbC5jb25uZWN0KGFicyk7XG4gKiB9LCAwLjUsIDEpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgQWJzIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFic1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWJzID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogdmFsID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoTWF0aC5hYnModmFsKSA8IDAuMDAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBpbnB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fYWJzO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCByYW5nZSBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fYWJzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWJzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWJzLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIEdhaW5Ub0F1ZGlvIGNvbnZlcnRzIGFuIGlucHV0IGluIE5vcm1hbFJhbmdlIFswLDFdIHRvIEF1ZGlvUmFuZ2UgWy0xLDFdLlxuICogU2VlIFtbQXVkaW9Ub0dhaW5dXS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdhaW5Ub0F1ZGlvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdhaW5Ub0F1ZGlvXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ub3JtID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogeCA9PiBNYXRoLmFicyh4KSAqIDIgLSAxLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBOb3JtYWxSYW5nZSBpbnB1dCBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9ub3JtO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2Ugb3V0cHV0IFstMSwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbm9ybTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vcm0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYWluVG9BdWRpby5qcy5tYXAiLCJpbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIE5lZ2F0ZSB0aGUgaW5jb21pbmcgc2lnbmFsLiBpLmUuIGFuIGlucHV0IHNpZ25hbCBvZiAxMCB3aWxsIG91dHB1dCAtMTBcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbmVnID0gbmV3IFRvbmUuTmVnYXRlKCk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoLTIpLmNvbm5lY3QobmVnKTtcbiAqIC8vIG91dHB1dCBvZiBuZWcgaXMgcG9zaXRpdmUgMi5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIE5lZ2F0ZSBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOZWdhdGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5lZ2F0aW9uIGlzIGRvbmUgYnkgbXVsdGlwbHlpbmcgYnkgLTFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX211bHRpcGx5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAtMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgYW5kIG91dHB1dCBhcmUgZXF1YWwgdG8gdGhlIG11bHRpcGx5IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9tdWx0aXBseTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9tdWx0aXBseTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKiBAcmV0dXJucyB7TmVnYXRlfSB0aGlzXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5lZ2F0ZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5lZ2F0ZSB9IGZyb20gXCIuLi9zaWduYWwvTmVnYXRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuLyoqXG4gKiBTdWJ0cmFjdCB0aGUgc2lnbmFsIGNvbm5lY3RlZCB0byB0aGUgaW5wdXQgaXMgc3VidHJhY3RlZCBmcm9tIHRoZSBzaWduYWwgY29ubmVjdGVkXG4gKiBUaGUgc3VidHJhaGVuZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gc3VidHJhY3QgYSBzY2FsYXIgZnJvbSBhIHNpZ25hbFxuICogY29uc3Qgc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoMSk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoNCkuY29ubmVjdChzdWIpO1xuICogLy8gdGhlIG91dHB1dCBvZiBzdWIgaXMgMy5cbiAqIEBleGFtcGxlXG4gKiAvLyBzdWJ0cmFjdCB0d28gc2lnbmFsc1xuICogY29uc3Qgc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoKTtcbiAqIGNvbnN0IHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMTApO1xuICogY29uc3Qgc2lnQiA9IG5ldyBUb25lLlNpZ25hbCgyLjUpO1xuICogc2lnQS5jb25uZWN0KHN1Yik7XG4gKiBzaWdCLmNvbm5lY3Qoc3ViLnN1YnRyYWhlbmQpO1xuICogLy8gb3V0cHV0IG9mIHN1YiBpcyA3LjVcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnRyYWN0IGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTdWJ0cmFjdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3VidHJhY3RcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzdW1taW5nIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N1bSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5lZ2F0ZSB0aGUgaW5wdXQgb2YgdGhlIHNlY29uZCBpbnB1dCBiZWZvcmUgY29ubmVjdGluZyBpdCB0byB0aGUgc3VtbWluZyBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmVnID0gbmV3IE5lZ2F0ZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB3aGljaCBpcyBzdWJ0cmFjdGVkIGZyb20gdGhlIG1haW4gc2lnbmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN1YnRyYWhlbmQgPSB0aGlzLl9wYXJhbTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLl9jb25zdGFudFNvdXJjZSwgdGhpcy5fbmVnLCB0aGlzLl9zdW0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbmVnLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3VidHJhY3QuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBHcmVhdGVyVGhhblplcm8gb3V0cHV0cyAxIHdoZW4gdGhlIGlucHV0IGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiB6ZXJvXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGd0MCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuWmVybygpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChndDApO1xuICogXHRzaWcuc2V0VmFsdWVBdFRpbWUoLTEsIDAuMDUpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuWmVybyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhblplcm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyZWF0ZXJUaGFuWmVyb1wiO1xuICAgICAgICB0aGlzLl90aHJlc2ggPSB0aGlzLm91dHB1dCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxlbmd0aDogMTI3LFxuICAgICAgICAgICAgbWFwcGluZzogKHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDEwMDAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9zY2FsZS5jb25uZWN0KHRoaXMuX3RocmVzaCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aHJlc2guZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmVhdGVyVGhhblplcm8uanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuWmVybyB9IGZyb20gXCIuL0dyZWF0ZXJUaGFuWmVyb1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBPdXRwdXQgMSBpZiB0aGUgc2lnbmFsIGlzIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUsIG90aGVyd2lzZSBvdXRwdXRzIDAuXG4gKiBjYW4gY29tcGFyZSB0d28gc2lnbmFscyBvciBhIHNpZ25hbCBhbmQgYSBudW1iZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBndCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuKDIpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDQpLmNvbm5lY3QoZ3QpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyZWF0ZXJUaGFuXCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyZWF0ZXJUaGFuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9zdWJ0cmFjdCA9IHRoaXMuaW5wdXQgPSBuZXcgU3VidHJhY3Qoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2d0eiA9IHRoaXMub3V0cHV0ID0gbmV3IEdyZWF0ZXJUaGFuWmVybyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5jb21wYXJhdG9yID0gdGhpcy5fcGFyYW0gPSB0aGlzLl9zdWJ0cmFjdC5zdWJ0cmFoZW5kO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImNvbXBhcmF0b3JcIik7XG4gICAgICAgIC8vIGNvbm5lY3RcbiAgICAgICAgdGhpcy5fc3VidHJhY3QuY29ubmVjdCh0aGlzLl9ndHopO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ3R6LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VidHJhY3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbXBhcmF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmVhdGVyVGhhbi5qcy5tYXAiLCJpbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFBvdyBhcHBsaWVzIGFuIGV4cG9uZW50IHRvIHRoZSBpbmNvbWluZyBzaWduYWwuIFRoZSBpbmNvbWluZyBzaWduYWwgbXVzdCBiZSBBdWRpb1JhbmdlIFstMSwgMV1cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcG93ID0gbmV3IFRvbmUuUG93KDIpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChwb3cpO1xuICogLy8gb3V0cHV0IG9mIHBvdyBpcyAwLjI1LlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgUG93IGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvdy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBvd1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUG93LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHRoaXMuX2V4cEZ1bmMob3B0aW9ucy52YWx1ZSksXG4gICAgICAgICAgICBsZW5ndGg6IDgxOTIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IG9wdGlvbnMudmFsdWU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB0aGUgZnVuY3Rpb24gd2hpY2ggbWFwcyB0aGUgd2F2ZXNoYXBlclxuICAgICAqIEBwYXJhbSBleHBvbmVudCBleHBvbmVudCB2YWx1ZVxuICAgICAqL1xuICAgIF9leHBGdW5jKGV4cG9uZW50KSB7XG4gICAgICAgIHJldHVybiAodmFsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5wb3coTWF0aC5hYnModmFsKSwgZXhwb25lbnQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgb2YgdGhlIGV4cG9uZW50LlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cG9uZW50O1xuICAgIH1cbiAgICBzZXQgdmFsdWUoZXhwb25lbnQpIHtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSBleHBvbmVudDtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIuc2V0TWFwKHRoaXMuX2V4cEZ1bmModGhpcy5fZXhwb25lbnQpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBvdy5qcy5tYXAiLCJpbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuL1NjYWxlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBvdyB9IGZyb20gXCIuL1Bvd1wiO1xuLyoqXG4gKiBQZXJmb3JtcyBhbiBleHBvbmVudGlhbCBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cbiAqIFNjYWxlcyBhIE5vcm1hbFJhbmdlIHZhbHVlIFswLDFdIGV4cG9uZW50aWFsbHlcbiAqIHRvIHRoZSBvdXRwdXQgcmFuZ2Ugb2Ygb3V0cHV0TWluIHRvIG91dHB1dE1heC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzY2FsZUV4cCA9IG5ldyBUb25lLlNjYWxlRXhwKDAsIDEwMCwgMik7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlRXhwKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNjYWxlRXhwIGV4dGVuZHMgU2NhbGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlRXhwLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCIsIFwiZXhwb25lbnRcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2NhbGVFeHBcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlRXhwLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCIsIFwiZXhwb25lbnRcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZXhwID0gbmV3IFBvdyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5leHBvbmVudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V4cC5jb25uZWN0KHRoaXMuX211bHQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNjYWxlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGV4cG9uZW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zdGVhZCBvZiBpbnRlcnBvbGF0aW5nIGxpbmVhcmx5IGJldHdlZW4gdGhlIFtbbWluXV0gYW5kXG4gICAgICogW1ttYXhdXSB2YWx1ZXMsIHNldHRpbmcgdGhlIGV4cG9uZW50IHdpbGwgaW50ZXJwb2xhdGUgYmV0d2VlblxuICAgICAqIHRoZSB0d28gdmFsdWVzIHdpdGggYW4gZXhwb25lbnRpYWwgY3VydmUuXG4gICAgICovXG4gICAgZ2V0IGV4cG9uZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgZXhwb25lbnQoZXhwKSB7XG4gICAgICAgIHRoaXMuX2V4cC52YWx1ZSA9IGV4cDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHAuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TY2FsZUV4cC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBUb25lQ29uc3RhbnRTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQ29uc3RhbnRTb3VyY2VcIjtcbi8qKlxuICogQWRkcyB0aGUgYWJpbGl0eSB0byBzeW5jaHJvbml6ZSB0aGUgc2lnbmFsIHRvIHRoZSBbW1RyYW5zcG9ydF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTeW5jZWRTaWduYWwgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3luY2VkU2lnbmFsXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEb24ndCBvdmVycmlkZSB3aGVuIHNvbWV0aGluZyBpcyBjb25uZWN0ZWQgdG8gdGhlIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKTtcbiAgICAgICAgdGhpcy5fbGFzdFZhbCA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGhpcy5fb25UaWNrLmJpbmQodGhpcyksIFwiMWlcIik7XG4gICAgICAgIHRoaXMuX3N5bmNlZENhbGxiYWNrID0gdGhpcy5fYW5jaG9yVmFsdWUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0b3BcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICAvLyBkaXNjb25uZWN0IHRoZSBjb25zdGFudCBzb3VyY2UgZnJvbSB0aGUgb3V0cHV0IGFuZCByZXBsYWNlIGl0IHdpdGggYW5vdGhlciBvbmVcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5zdG9wKDApO1xuICAgICAgICAvLyBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZUNvbnN0YW50U291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICB9KS5zdGFydCgwKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCBldmVyeSB0aWNrLlxuICAgICAqL1xuICAgIF9vblRpY2sodGltZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzdXBlci5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICAvLyBhcHByb3hpbWF0ZSByYW1wIGN1cnZlcyB3aXRoIGxpbmVhciByYW1wc1xuICAgICAgICBpZiAodGhpcy5fbGFzdFZhbCAhPT0gdmFsKSB7XG4gICAgICAgICAgICB0aGlzLl9sYXN0VmFsID0gdmFsO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LnNldFZhbHVlQXRUaW1lKHZhbCwgdGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQW5jaG9yIHRoZSB2YWx1ZSBhdCB0aGUgc3RhcnQgYW5kIHN0b3Agb2YgdGhlIFRyYW5zcG9ydFxuICAgICAqL1xuICAgIF9hbmNob3JWYWx1ZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHN1cGVyLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgIHRoaXMuX2xhc3RWYWwgPSB2YWw7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldC5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQuc2V0VmFsdWVBdFRpbWUodmFsLCB0aW1lKTtcbiAgICB9XG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHJldHVybiBzdXBlci5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgIH1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMoc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgc3VwZXIuc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIGNvbXB1dGVkVGltZSwgZHVyYXRpb24sIHNjYWxpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuY2FuY2VsQW5kSG9sZEF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0UmFtcFBvaW50KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5zZXRSYW1wUG9pbnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5leHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIodGhpcy5fc3luY2VkKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0b3BcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN5bmNlZFNpZ25hbC5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BZGRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Fic1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vQXVkaW9Ub0dhaW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0dhaW5Ub0F1ZGlvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9HcmVhdGVyVGhhblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vR3JlYXRlclRoYW5aZXJvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NdWx0aXBseVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTmVnYXRlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Qb3dcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NpZ25hbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2NhbGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NjYWxlRXhwXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TdWJ0cmFjdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3luY2VkU2lnbmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9aZXJvXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIsIF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwsIFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHJhbmdlLCB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBFbnZlbG9wZSBpcyBhbiBbQURTUl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ludGhlc2l6ZXIjQURTUl9lbnZlbG9wZSlcbiAqIGVudmVsb3BlIGdlbmVyYXRvci4gRW52ZWxvcGUgb3V0cHV0cyBhIHNpZ25hbCB3aGljaFxuICogY2FuIGJlIGNvbm5lY3RlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsLlxuICogYGBgXG4gKiAgICAgICAgICAgL1xcXG4gKiAgICAgICAgICAvICBcXFxuICogICAgICAgICAvICAgIFxcXG4gKiAgICAgICAgLyAgICAgIFxcXG4gKiAgICAgICAvICAgICAgICBcXF9fX19fX19fX19fXG4gKiAgICAgIC8gICAgICAgICAgICAgICAgICAgICBcXFxuICogICAgIC8gICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgICAvICAgICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgIC8gICAgICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogYGBgXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAqIFx0XHRhdHRhY2s6IDAuMSxcbiAqIFx0XHRkZWNheTogMC4yLFxuICogXHRcdHN1c3RhaW46IDAuNSxcbiAqIFx0XHRyZWxlYXNlOiAwLjgsXG4gKiBcdH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0ZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuNSk7XG4gKiB9LCAxLjUsIDEpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRW52ZWxvcGUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRW52ZWxvcGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzaWduYWwgd2hpY2ggaXMgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2lnID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IHNpZ25hbCBvZiB0aGUgZW52ZWxvcGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc2lnO1xuICAgICAgICAvKipcbiAgICAgICAgICogRW52ZWxvcGUgaGFzIG5vIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjaztcbiAgICAgICAgdGhpcy5kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG4gICAgICAgIHRoaXMuc3VzdGFpbiA9IG9wdGlvbnMuc3VzdGFpbjtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLmF0dGFja0N1cnZlID0gb3B0aW9ucy5hdHRhY2tDdXJ2ZTtcbiAgICAgICAgdGhpcy5yZWxlYXNlQ3VydmUgPSBvcHRpb25zLnJlbGVhc2VDdXJ2ZTtcbiAgICAgICAgdGhpcy5kZWNheUN1cnZlID0gb3B0aW9ucy5kZWNheUN1cnZlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwibGluZWFyXCIsXG4gICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgZGVjYXlDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgICAgIHJlbGVhc2VDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgc3VzdGFpbjogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZW52ZWxvcGUuIFVzZWZ1bCBmb3JcbiAgICAgKiBzeW5jaHJvbml6aW5nIHZpc3VhbCBvdXRwdXQgdG8gdGhlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VydmVcbiAgICAgKiBAcGFyYW0gIGN1cnZlXG4gICAgICogQHBhcmFtICBkaXJlY3Rpb24gIEluL091dFxuICAgICAqIEByZXR1cm4gVGhlIGN1cnZlIG5hbWVcbiAgICAgKi9cbiAgICBfZ2V0Q3VydmUoY3VydmUsIGRpcmVjdGlvbikge1xuICAgICAgICBpZiAoaXNTdHJpbmcoY3VydmUpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3VydmU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBjdXJ2ZXMgYXJyYXlcbiAgICAgICAgICAgIGxldCBjdXJ2ZU5hbWU7XG4gICAgICAgICAgICBmb3IgKGN1cnZlTmFtZSBpbiBFbnZlbG9wZUN1cnZlcykge1xuICAgICAgICAgICAgICAgIGlmIChFbnZlbG9wZUN1cnZlc1tjdXJ2ZU5hbWVdW2RpcmVjdGlvbl0gPT09IGN1cnZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJ2ZU5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcmV0dXJuIHRoZSBjdXN0b20gY3VydmVcbiAgICAgICAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3NpZ24gYSB0aGUgY3VydmUgdG8gdGhlIGdpdmVuIG5hbWUgdXNpbmcgdGhlIGRpcmVjdGlvblxuICAgICAqIEBwYXJhbSAgbmFtZVxuICAgICAqIEBwYXJhbSAgZGlyZWN0aW9uIEluL091dFxuICAgICAqIEBwYXJhbSAgY3VydmVcbiAgICAgKi9cbiAgICBfc2V0Q3VydmUobmFtZSwgZGlyZWN0aW9uLCBjdXJ2ZSkge1xuICAgICAgICAvLyBjaGVjayBpZiBpdCdzIGEgdmFsaWQgdHlwZVxuICAgICAgICBpZiAoaXNTdHJpbmcoY3VydmUpICYmIFJlZmxlY3QuaGFzKEVudmVsb3BlQ3VydmVzLCBjdXJ2ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnZlRGVmID0gRW52ZWxvcGVDdXJ2ZXNbY3VydmVdO1xuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGN1cnZlRGVmKSkge1xuICAgICAgICAgICAgICAgIGlmIChuYW1lICE9PSBcIl9kZWNheUN1cnZlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlRGVmW2RpcmVjdGlvbl07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlRGVmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQXJyYXkoY3VydmUpICYmIG5hbWUgIT09IFwiX2RlY2F5Q3VydmVcIikge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRW52ZWxvcGU6IGludmFsaWQgY3VydmU6IFwiICsgY3VydmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgYXR0YWNrLlxuICAgICAqIENhbiBiZSBhbnkgb2YgdGhlc2Ugc3RyaW5nczpcbiAgICAgKiAqIFwibGluZWFyXCJcbiAgICAgKiAqIFwiZXhwb25lbnRpYWxcIlxuICAgICAqICogXCJzaW5lXCJcbiAgICAgKiAqIFwiY29zaW5lXCJcbiAgICAgKiAqIFwiYm91bmNlXCJcbiAgICAgKiAqIFwicmlwcGxlXCJcbiAgICAgKiAqIFwic3RlcFwiXG4gICAgICpcbiAgICAgKiBDYW4gYWxzbyBiZSBhbiBhcnJheSB3aGljaCBkZXNjcmliZXMgdGhlIGN1cnZlLiBWYWx1ZXNcbiAgICAgKiBpbiB0aGUgYXJyYXkgYXJlIGV2ZW5seSBzdWJkaXZpZGVkIGFuZCBsaW5lYXJseVxuICAgICAqIGludGVycG9sYXRlZCBvdmVyIHRoZSBkdXJhdGlvbiBvZiB0aGUgYXR0YWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSgwLjQpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBcdGVudi5hdHRhY2tDdXJ2ZSA9IFwibGluZWFyXCI7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCBhdHRhY2tDdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnZlKHRoaXMuX2F0dGFja0N1cnZlLCBcIkluXCIpO1xuICAgIH1cbiAgICBzZXQgYXR0YWNrQ3VydmUoY3VydmUpIHtcbiAgICAgICAgdGhpcy5fc2V0Q3VydmUoXCJfYXR0YWNrQ3VydmVcIiwgXCJJblwiLCBjdXJ2ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgcmVsZWFzZS4gU2VlIHRoZSBhdHRhY2sgY3VydmUgdHlwZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAgICAgKiBcdFx0cmVsZWFzZTogMC44XG4gICAgICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIFx0Ly8gcmVsZWFzZSBjdXJ2ZSBjb3VsZCBhbHNvIGJlIGRlZmluZWQgYnkgYW4gYXJyYXlcbiAgICAgKiBcdGVudi5yZWxlYXNlQ3VydmUgPSBbMSwgMC4zLCAwLjQsIDAuMiwgMC43LCAwXTtcbiAgICAgKiBcdGVudi50cmlnZ2VyUmVsZWFzZSgwLjIpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCByZWxlYXNlQ3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDdXJ2ZSh0aGlzLl9yZWxlYXNlQ3VydmUsIFwiT3V0XCIpO1xuICAgIH1cbiAgICBzZXQgcmVsZWFzZUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHRoaXMuX3NldEN1cnZlKFwiX3JlbGVhc2VDdXJ2ZVwiLCBcIk91dFwiLCBjdXJ2ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgZGVjYXkgZWl0aGVyIFwibGluZWFyXCIgb3IgXCJleHBvbmVudGlhbFwiXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAgICAgKiBcdFx0c3VzdGFpbjogMC4xLFxuICAgICAqIFx0XHRkZWNheTogMC41XG4gICAgICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYuZGVjYXlDdXJ2ZSA9IFwibGluZWFyXCI7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCBkZWNheUN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjYXlDdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGRlY2F5Q3VydmUoY3VydmUpIHtcbiAgICAgICAgYXNzZXJ0KFtcImxpbmVhclwiLCBcImV4cG9uZW50aWFsXCJdLnNvbWUoYyA9PiBjID09PSBjdXJ2ZSksIGBJbnZhbGlkIGVudmVsb3BlIGN1cnZlOiAke2N1cnZlfWApO1xuICAgICAgICB0aGlzLl9kZWNheUN1cnZlID0gY3VydmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjay9kZWNheSBwb3J0aW9uIG9mIHRoZSBBRFNSIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIGVudmVsb3BlIHNjYWxlcyB0aGUgdmFsZXMuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlciBiZXR3ZWVuIDAtMVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoZW52KS5zdGFydCgpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIGF0dGFjayAwLjUgc2Vjb25kcyBmcm9tIG5vdyB3aXRoIGEgdmVsb2NpdHkgb2YgMC4yXG4gICAgICogZW52LnRyaWdnZXJBdHRhY2soXCIrMC41XCIsIDAuMik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKTtcbiAgICAgICAgbGV0IGF0dGFjayA9IG9yaWdpbmFsQXR0YWNrO1xuICAgICAgICBjb25zdCBkZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpO1xuICAgICAgICAvLyBjaGVjayBpZiBpdCdzIG5vdCBhIGNvbXBsZXRlIGF0dGFja1xuICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID4gMCkge1xuICAgICAgICAgICAgLy8gc3VidHJhY3QgdGhlIGN1cnJlbnQgdmFsdWUgZnJvbSB0aGUgYXR0YWNrIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGF0dGFja1JhdGUgPSAxIC8gYXR0YWNrO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nRGlzdGFuY2UgPSAxIC0gY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgLy8gdGhlIGF0dGFjayBpcyBub3cgdGhlIHJlbWFpbmluZyB0aW1lXG4gICAgICAgICAgICBhdHRhY2sgPSByZW1haW5pbmdEaXN0YW5jZSAvIGF0dGFja1JhdGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYXR0YWNrXG4gICAgICAgIGlmIChhdHRhY2sgPCB0aGlzLnNhbXBsZVRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgICAgICAvLyBjYXNlIHdoZXJlIHRoZSBhdHRhY2sgdGltZSBpcyAwIHNob3VsZCBzZXQgaW5zdGFudGx5XG4gICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVBdFRpbWUodmVsb2NpdHksIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcubGluZWFyUmFtcFRvKHZlbG9jaXR5LCBhdHRhY2ssIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSBcImV4cG9uZW50aWFsXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy50YXJnZXRSYW1wVG8odmVsb2NpdHksIGF0dGFjaywgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgIGxldCBjdXJ2ZSA9IHRoaXMuX2F0dGFja0N1cnZlO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGN1cnZlXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGN1cnZlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhlIHN0YXJ0aW5nIGluZGV4IGlzIGJldHdlZW4gdGhlIHR3byB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAoY3VydmVbaSAtIDFdIDw9IGN1cnJlbnRWYWx1ZSAmJiBjdXJyZW50VmFsdWUgPD0gY3VydmVbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgY3VydmUgPSB0aGlzLl9hdHRhY2tDdXJ2ZS5zbGljZShpKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGluZGV4IGlzIHRoZSBjdXJyZW50IHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlWzBdID0gY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVDdXJ2ZUF0VGltZShjdXJ2ZSwgdGltZSwgYXR0YWNrLCB2ZWxvY2l0eSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZGVjYXlcbiAgICAgICAgaWYgKGRlY2F5ICYmIHRoaXMuc3VzdGFpbiA8IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY2F5VmFsdWUgPSB2ZWxvY2l0eSAqIHRoaXMuc3VzdGFpbjtcbiAgICAgICAgICAgIGNvbnN0IGRlY2F5U3RhcnQgPSB0aW1lICsgYXR0YWNrO1xuICAgICAgICAgICAgdGhpcy5sb2coXCJkZWNheVwiLCBkZWNheVN0YXJ0KTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZWNheUN1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKGRlY2F5VmFsdWUsIGRlY2F5ICsgZGVjYXlTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKGRlY2F5VmFsdWUsIGRlY2F5U3RhcnQsIGRlY2F5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlcnMgdGhlIHJlbGVhc2Ugb2YgdGhlIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlIHNob3VsZCBzdGFydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3Ioe1xuICAgICAqIFx0dHlwZTogXCJzYXd0b290aFwiXG4gICAgICogfSkuY29ubmVjdChlbnYpLnN0YXJ0KCk7XG4gICAgICogZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIGhhbGYgYSBzZWNvbmQgYWZ0ZXIgdGhlIGF0dGFja1xuICAgICAqIGVudi50cmlnZ2VyUmVsZWFzZShcIiswLjVcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIHRpbWUpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCByZWxlYXNlID0gdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKTtcbiAgICAgICAgICAgIGlmIChyZWxlYXNlIDwgdGhpcy5zYW1wbGVUaW1lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fcmVsZWFzZUN1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3JlbGVhc2VDdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnRhcmdldFJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzc2VydChpc0FycmF5KHRoaXMuX3JlbGVhc2VDdXJ2ZSksIFwicmVsZWFzZUN1cnZlIG11c3QgYmUgZWl0aGVyICdsaW5lYXInLCAnZXhwb25lbnRpYWwnIG9yIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUN1cnZlQXRUaW1lKHRoaXMuX3JlbGVhc2VDdXJ2ZSwgdGltZSwgcmVsZWFzZSwgY3VycmVudFZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzY2hlZHVsZWQgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuIFRoaXMgd2lsbFxuICAgICAqIHJldHVybiB0aGUgdW5jb252ZXJ0ZWQgKHJhdykgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSgwLjUsIDEsIDAuNCwgMik7XG4gICAgICogZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDIpO1xuICAgICAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKGVudi5nZXRWYWx1ZUF0VGltZShUb25lLm5vdygpKSksIDEwMCk7XG4gICAgICovXG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2lnLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB0cmlnZ2VyQXR0YWNrUmVsZWFzZSBpcyBzaG9ydGhhbmQgZm9yIHRyaWdnZXJBdHRhY2ssIHRoZW4gd2FpdGluZ1xuICAgICAqIHNvbWUgZHVyYXRpb24sIHRoZW4gdHJpZ2dlclJlbGVhc2UuXG4gICAgICogQHBhcmFtIGR1cmF0aW9uIFRoZSBkdXJhdGlvbiBvZiB0aGUgc3VzdGFpbi5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGVudikuc3RhcnQoKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIDAuNSBzZWNvbmRzIGFmdGVyIHRoZSBhdHRhY2tcbiAgICAgKiBlbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoMC41KTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSh0aW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgYWxsIHNjaGVkdWxlZCBlbnZlbG9wZSBjaGFuZ2VzIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9zaWcuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBlbnZlbG9wZSB0byBhIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICovXG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtYmVyID0gMCwgaW5wdXROdW1iZXIgPSAwKSB7XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIHRoZSBlbnZlbG9wZSBjdXJ2ZSB0byBhbiBhcnJheSBvZiB0aGUgZ2l2ZW4gbGVuZ3RoLlxuICAgICAqIEdvb2QgZm9yIHZpc3VhbGl6aW5nIHRoZSBlbnZlbG9wZSBjdXJ2ZS4gUmVzY2FsZXMgdGhlIGR1cmF0aW9uIG9mIHRoZVxuICAgICAqIGVudmVsb3BlIHRvIGZpdCB0aGUgbGVuZ3RoLlxuICAgICAqL1xuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb24gPSBsZW5ndGggLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMSwgZHVyYXRpb24sIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSB0aGUgQURTUiBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uIHdpdGggMjAlIHN1c3RhaW4gdGltZVxuICAgICAgICAgICAgY29uc3QgYXR0YWNrUG9ydGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpO1xuICAgICAgICAgICAgY29uc3QgZW52ZWxvcGVEdXJhdGlvbiA9IGF0dGFja1BvcnRpb24gKyB0aGlzLnRvU2Vjb25kcyh0aGlzLnJlbGVhc2UpO1xuICAgICAgICAgICAgY29uc3Qgc3VzdGFpblRpbWUgPSBlbnZlbG9wZUR1cmF0aW9uICogMC4xO1xuICAgICAgICAgICAgY29uc3QgdG90YWxEdXJhdGlvbiA9IGVudmVsb3BlRHVyYXRpb24gKyBzdXN0YWluVGltZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGNsb25lID0gbmV3IHRoaXMuY29uc3RydWN0b3IoT2JqZWN0LmFzc2lnbih0aGlzLmdldCgpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgZGVjYXk6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5kZWNheSkgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgY2xvbmUuX3NpZy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAgICBjbG9uZS50cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiAqIChhdHRhY2tQb3J0aW9uICsgc3VzdGFpblRpbWUpIC8gdG90YWxEdXJhdGlvbiwgMCk7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lnLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwiYXR0YWNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJkZWNheVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcmFuZ2UoMCwgMSlcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJzdXN0YWluXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJyZWxlYXNlXCIsIHZvaWQgMCk7XG4vKipcbiAqIEdlbmVyYXRlIHNvbWUgY29tcGxleCBlbnZlbG9wZSBjdXJ2ZXMuXG4gKi9cbmNvbnN0IEVudmVsb3BlQ3VydmVzID0gKCgpID0+IHtcbiAgICBjb25zdCBjdXJ2ZUxlbiA9IDEyODtcbiAgICBsZXQgaTtcbiAgICBsZXQgaztcbiAgICAvLyBjb3NpbmUgY3VydmVcbiAgICBjb25zdCBjb3NpbmVDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGNvc2luZUN1cnZlW2ldID0gTWF0aC5zaW4oKGkgLyAoY3VydmVMZW4gLSAxKSkgKiAoTWF0aC5QSSAvIDIpKTtcbiAgICB9XG4gICAgLy8gcmlwcGxlIGN1cnZlXG4gICAgY29uc3QgcmlwcGxlQ3VydmUgPSBbXTtcbiAgICBjb25zdCByaXBwbGVDdXJ2ZUZyZXEgPSA2LjQ7XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuIC0gMTsgaSsrKSB7XG4gICAgICAgIGsgPSAoaSAvIChjdXJ2ZUxlbiAtIDEpKTtcbiAgICAgICAgY29uc3Qgc2luZVdhdmUgPSBNYXRoLnNpbihrICogKE1hdGguUEkgKiAyKSAqIHJpcHBsZUN1cnZlRnJlcSAtIE1hdGguUEkgLyAyKSArIDE7XG4gICAgICAgIHJpcHBsZUN1cnZlW2ldID0gc2luZVdhdmUgLyAxMCArIGsgKiAwLjgzO1xuICAgIH1cbiAgICByaXBwbGVDdXJ2ZVtjdXJ2ZUxlbiAtIDFdID0gMTtcbiAgICAvLyBzdGFpcnMgY3VydmVcbiAgICBjb25zdCBzdGFpcnNDdXJ2ZSA9IFtdO1xuICAgIGNvbnN0IHN0ZXBzID0gNTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBzdGFpcnNDdXJ2ZVtpXSA9IE1hdGguY2VpbCgoaSAvIChjdXJ2ZUxlbiAtIDEpKSAqIHN0ZXBzKSAvIHN0ZXBzO1xuICAgIH1cbiAgICAvLyBpbi1vdXQgZWFzaW5nIGN1cnZlXG4gICAgY29uc3Qgc2luZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgayA9IGkgLyAoY3VydmVMZW4gLSAxKTtcbiAgICAgICAgc2luZUN1cnZlW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcyhNYXRoLlBJICogaykpO1xuICAgIH1cbiAgICAvLyBhIGJvdW5jZSBjdXJ2ZVxuICAgIGNvbnN0IGJvdW5jZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgayA9IGkgLyAoY3VydmVMZW4gLSAxKTtcbiAgICAgICAgY29uc3QgZnJlcSA9IE1hdGgucG93KGssIDMpICogNCArIDAuMjtcbiAgICAgICAgY29uc3QgdmFsID0gTWF0aC5jb3MoZnJlcSAqIE1hdGguUEkgKiAyICogayk7XG4gICAgICAgIGJvdW5jZUN1cnZlW2ldID0gTWF0aC5hYnModmFsICogKDEgLSBrKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludmVydCBhIHZhbHVlIGN1cnZlIHRvIG1ha2UgaXQgd29yayBmb3IgdGhlIHJlbGVhc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbnZlcnRDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICBjb25zdCBvdXQgPSBuZXcgQXJyYXkoY3VydmUubGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjdXJ2ZS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgb3V0W2pdID0gMSAtIGN1cnZlW2pdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJldmVyc2UgdGhlIGN1cnZlXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmV2ZXJzZUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHJldHVybiBjdXJ2ZS5zbGljZSgwKS5yZXZlcnNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGF0dGFjayBhbmQgcmVsZWFzZSBjdXJ2ZSBhcnJheXNcbiAgICAgKi9cbiAgICByZXR1cm4ge1xuICAgICAgICBib3VuY2U6IHtcbiAgICAgICAgICAgIEluOiBpbnZlcnRDdXJ2ZShib3VuY2VDdXJ2ZSksXG4gICAgICAgICAgICBPdXQ6IGJvdW5jZUN1cnZlLFxuICAgICAgICB9LFxuICAgICAgICBjb3NpbmU6IHtcbiAgICAgICAgICAgIEluOiBjb3NpbmVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogcmV2ZXJzZUN1cnZlKGNvc2luZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwb25lbnRpYWw6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgbGluZWFyOiBcImxpbmVhclwiLFxuICAgICAgICByaXBwbGU6IHtcbiAgICAgICAgICAgIEluOiByaXBwbGVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUocmlwcGxlQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBzaW5lOiB7XG4gICAgICAgICAgICBJbjogc2luZUN1cnZlLFxuICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShzaW5lQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBzdGVwOiB7XG4gICAgICAgICAgICBJbjogc3RhaXJzQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IGludmVydEN1cnZlKHN0YWlyc0N1cnZlKSxcbiAgICAgICAgfSxcbiAgICB9O1xufSkoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBCYXNlLWNsYXNzIGZvciBhbGwgaW5zdHJ1bWVudHNcbiAqL1xuZXhwb3J0IGNsYXNzIEluc3RydW1lbnQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgYWxsIGV2ZW50cyBzY2hlZHVsZWQgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgKiB3aGVuIHRoZSBpbnN0cnVtZW50IGlzICdzeW5jZWQnXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoZSBpbnN0cnVtZW50IGlzIGN1cnJlbnRseSBzeW5jZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyQXR0YWNrID0gdGhpcy50cmlnZ2VyQXR0YWNrO1xuICAgICAgICB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyUmVsZWFzZSA9IHRoaXMudHJpZ2dlclJlbGVhc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGluc3RydW1lbnQgdG8gdGhlIFRyYW5zcG9ydC4gQWxsIHN1YnNlcXVlbnQgY2FsbHMgb2ZcbiAgICAgKiBbW3RyaWdnZXJBdHRhY2tdXSBhbmQgW1t0cmlnZ2VyUmVsZWFzZV1dIHdpbGwgYmUgc2NoZWR1bGVkIGFsb25nIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmbVN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBmbVN5bnRoLnZvbHVtZS52YWx1ZSA9IC02O1xuICAgICAqIGZtU3ludGguc3luYygpO1xuICAgICAqIC8vIHNjaGVkdWxlIDMgbm90ZXMgd2hlbiB0aGUgdHJhbnNwb3J0IGZpcnN0IHN0YXJ0c1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIsIDApO1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJFNFwiLCBcIjhuXCIsIFwiOG5cIik7XG4gICAgICogZm1TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkc0XCIsIFwiOG5cIiwgXCI0blwiKTtcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0IHRvIGhlYXIgdGhlIG5vdGVzXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXQgX3N5bmNcbiAgICAgKi9cbiAgICBfc3luY1N0YXRlKCkge1xuICAgICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGFuZ2VkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcmFwIHRoZSBnaXZlbiBtZXRob2Qgc28gdGhhdCBpdCBjYW4gYmUgc3luY2hyb25pemVkXG4gICAgICogQHBhcmFtIG1ldGhvZCBXaGljaCBtZXRob2QgdG8gd3JhcCBhbmQgc3luY1xuICAgICAqIEBwYXJhbSAgdGltZVBvc2l0aW9uIFdoYXQgcG9zaXRpb24gdGhlIHRpbWUgYXJndW1lbnQgYXBwZWFycyBpblxuICAgICAqL1xuICAgIF9zeW5jTWV0aG9kKG1ldGhvZCwgdGltZVBvc2l0aW9uKSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gdGhpc1tcIl9vcmlnaW5hbF9cIiArIG1ldGhvZF0gPSB0aGlzW21ldGhvZF07XG4gICAgICAgIHRoaXNbbWV0aG9kXSA9ICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0aW1lID0gYXJnc1t0aW1lUG9zaXRpb25dO1xuICAgICAgICAgICAgY29uc3QgaWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgYXJnc1t0aW1lUG9zaXRpb25dID0gdDtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH0sIHRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzLnB1c2goaWQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGluc3RydW1lbnQgZnJvbSB0aGUgVHJhbnNwb3J0XG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMuZm9yRWFjaChpZCA9PiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGlkKSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayA9IHRoaXMuX29yaWdpbmFsX3RyaWdnZXJBdHRhY2s7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlID0gdGhpcy5fb3JpZ2luYWxfdHJpZ2dlclJlbGVhc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgdGhlbiB0aGUgcmVsZWFzZSBhZnRlciB0aGUgZHVyYXRpb24uXG4gICAgICogQHBhcmFtICBub3RlICAgICBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIG5vdGUgc2hvdWxkIGJlIGhlbGQgZm9yIGJlZm9yZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJpbmcgdGhlIHJlbGVhc2UuIFRoaXMgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMC5cbiAgICAgKiBAcGFyYW0gdGltZSAgV2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRoZSBub3RlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgXCJDNFwiIGZvciB0aGUgZHVyYXRpb24gb2YgYW4gOHRoIG5vdGVcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZSwgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqIEByZXR1cm5zIHtJbnN0cnVtZW50fSB0aGlzXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW5zdHJ1bWVudC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuLi9pbnN0cnVtZW50L0luc3RydW1lbnRcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIG90aGVyIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMgdG8gZXh0ZW5kLlxuICovXG5leHBvcnQgY2xhc3MgTW9ub3Bob25pYyBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnBvcnRhbWVudG8gPSBvcHRpb25zLnBvcnRhbWVudG87XG4gICAgICAgIHRoaXMub25zaWxlbmNlID0gb3B0aW9ucy5vbnNpbGVuY2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBvbnNpbGVuY2U6IG5vT3AsXG4gICAgICAgICAgICBwb3J0YW1lbnRvOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIG9mIHRoZSBub3RlIG9wdGlvbmFsbHkgd2l0aCBhIGdpdmVuIHZlbG9jaXR5LlxuICAgICAqIEBwYXJhbSAgbm90ZSBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBub3RlIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBzY2FsZXIgZGV0ZXJtaW5lcyBob3cgXCJsb3VkXCIgdGhlIG5vdGUgd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIG5vdGUgYSBoYWxmIHNlY29uZCBmcm9tIG5vdyBhdCBoYWxmIHZlbG9jaXR5XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIsIFwiKzAuNVwiLCAwLjUpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZSwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHNlY29uZHMsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5zZXROb3RlKG5vdGUsIHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSAgdGltZSBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgcmVsZWFzZSBoYXBwZW5zIGltbWVkaWF0bHlcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2UgYSBzZWNvbmQgZnJvbSBub3dcbiAgICAgKiBzeW50aC50cmlnZ2VyUmVsZWFzZShcIisxXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCB0aW1lKTtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgbm90ZVxuICAgICAqIHdpbGwgc2V0IGltbWVkaWF0ZWx5LlxuICAgICAqIEBwYXJhbSBub3RlIFRoZSBub3RlIHRvIGNoYW5nZSB0by5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgc2V0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFwiQzRcIik7XG4gICAgICogLy8gY2hhbmdlIHRvIEYjNiBpbiBvbmUgcXVhcnRlciBub3RlIGZyb20gbm93LlxuICAgICAqIHN5bnRoLnNldE5vdGUoXCJGIzZcIiwgXCIrNG5cIik7XG4gICAgICovXG4gICAgc2V0Tm90ZShub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZEZyZXF1ZW5jeSA9IG5vdGUgaW5zdGFuY2VvZiBGcmVxdWVuY3lDbGFzcyA/IG5vdGUudG9GcmVxdWVuY3koKSA6IG5vdGU7XG4gICAgICAgIGlmICh0aGlzLnBvcnRhbWVudG8gPiAwICYmIHRoaXMuZ2V0TGV2ZWxBdFRpbWUoY29tcHV0ZWRUaW1lKSA+IDAuMDUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvcnRUaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5wb3J0YW1lbnRvKTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmV4cG9uZW50aWFsUmFtcFRvKGNvbXB1dGVkRnJlcXVlbmN5LCBwb3J0VGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LnNldFZhbHVlQXRUaW1lKGNvbXB1dGVkRnJlcXVlbmN5LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgTW9ub3Bob25pYy5wcm90b3R5cGUsIFwicG9ydGFtZW50b1wiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9ub3Bob25pYy5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4vRW52ZWxvcGVcIjtcbi8qKlxuICogQW1wbGl0dWRlRW52ZWxvcGUgaXMgYSBUb25lLkVudmVsb3BlIGNvbm5lY3RlZCB0byBhIGdhaW4gbm9kZS5cbiAqIFVubGlrZSBUb25lLkVudmVsb3BlLCB3aGljaCBvdXRwdXRzIHRoZSBlbnZlbG9wZSdzIHZhbHVlLCBBbXBsaXR1ZGVFbnZlbG9wZSBhY2NlcHRzXG4gKiBhbiBhdWRpbyBzaWduYWwgYXMgdGhlIGlucHV0IGFuZCB3aWxsIGFwcGx5IHRoZSBlbnZlbG9wZSB0byB0aGUgYW1wbGl0dWRlXG4gKiBvZiB0aGUgc2lnbmFsLlxuICogUmVhZCBtb3JlIGFib3V0IEFEU1IgRW52ZWxvcGVzIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bnRoZXNpemVyI0FEU1JfZW52ZWxvcGUpLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYW1wRW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoe1xuICogXHRcdGF0dGFjazogMC4xLFxuICogXHRcdGRlY2F5OiAwLjIsXG4gKiBcdFx0c3VzdGFpbjogMS4wLFxuICogXHRcdHJlbGVhc2U6IDAuOFxuICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIGNyZWF0ZSBhbiBvc2NpbGxhdG9yIGFuZCBjb25uZWN0IGl0XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGFtcEVudikuc3RhcnQoKTtcbiAqIFx0Ly8gdHJpZ2dlciB0aGUgZW52ZWxvcGVzIGF0dGFjayBhbmQgcmVsZWFzZSBcIjh0XCIgYXBhcnRcbiAqIFx0YW1wRW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiOHRcIik7XG4gKiB9LCAxLjUsIDEpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQW1wbGl0dWRlRW52ZWxvcGUgZXh0ZW5kcyBFbnZlbG9wZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFtcGxpdHVkZUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFtcGxpdHVkZUVudmVsb3BlXCI7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5fc2lnLmNvbm5lY3QodGhpcy5fZ2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QW1wbGl0dWRlRW52ZWxvcGUuanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE9tbmlPc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbi8qKlxuICogU3ludGggaXMgY29tcG9zZWQgc2ltcGx5IG9mIGEgW1tPbW5pT3NjaWxsYXRvcl1dIHJvdXRlZCB0aHJvdWdoIGFuIFtbQW1wbGl0dWRlRW52ZWxvcGVdXS5cbiAqIGBgYFxuICogKy0tLS0tLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8IE9tbmlPc2NpbGxhdG9yICs+LS0+IEFtcGxpdHVkZUVudmVsb3BlICs+LS0+IE91dHB1dFxuICogKy0tLS0tLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBuZXcgT21uaU9zY2lsbGF0b3IoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgfSwgb3B0aW9ucy5vc2NpbGxhdG9yKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLmVudmVsb3BlKSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3JzIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmNoYWluKHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wib3NjaWxsYXRvclwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4zLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFsuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZSAoMC0xKVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgLy8gdGhlIGVudmVsb3Blc1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHJlbGVhc2UgcG9ydGlvbiwgc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkRGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KTtcbiAgICAgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyBjb21wdXRlZEF0dGFjayArIGNvbXB1dGVkRGVjYXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgYm90aCBBTSBhbmQgRk0gc3ludGhzXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2R1bGF0aW9uU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1vZHVsYXRpb25TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgU3ludGgoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogb3B0aW9ucy5vc2NpbGxhdG9yLFxuICAgICAgICAgICAgZW52ZWxvcGU6IG9wdGlvbnMuZW52ZWxvcGUsXG4gICAgICAgICAgICBvbnNpbGVuY2U6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICAgICAgdm9sdW1lOiAtMTAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgU3ludGgoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogb3B0aW9ucy5tb2R1bGF0aW9uLFxuICAgICAgICAgICAgZW52ZWxvcGU6IG9wdGlvbnMubW9kdWxhdGlvbkVudmVsb3BlLFxuICAgICAgICAgICAgdm9sdW1lOiAtMTAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSB0aGlzLl9jYXJyaWVyLm9zY2lsbGF0b3I7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSB0aGlzLl9jYXJyaWVyLmVudmVsb3BlO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb24gPSB0aGlzLl9tb2R1bGF0b3Iub3NjaWxsYXRvcjtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uRW52ZWxvcGUgPSB0aGlzLl9tb2R1bGF0b3IuZW52ZWxvcGU7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICAgICAgbWluVmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJoYXJtb25pY2l0eVwiLCBcIm9zY2lsbGF0b3JcIiwgXCJlbnZlbG9wZVwiLCBcIm1vZHVsYXRpb25cIiwgXCJtb2R1bGF0aW9uRW52ZWxvcGVcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDMsXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFtcbiAgICAgICAgICAgICAgICAuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksXG4gICAgICAgICAgICAgICAgXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgICAgICBcImRldHVuZVwiXG4gICAgICAgICAgICBdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2luZVwiXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1vZHVsYXRpb246IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgW1xuICAgICAgICAgICAgICAgIC4uLk9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSxcbiAgICAgICAgICAgICAgICBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgICAgIFwiZGV0dW5lXCJcbiAgICAgICAgICAgIF0pLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcXVhcmVcIlxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtb2R1bGF0aW9uRW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fY2Fycmllci5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vZHVsYXRpb25TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTW9kdWxhdGlvblN5bnRoIH0gZnJvbSBcIi4vTW9kdWxhdGlvblN5bnRoXCI7XG4vKipcbiAqIEFNU3ludGggdXNlcyB0aGUgb3V0cHV0IG9mIG9uZSBUb25lLlN5bnRoIHRvIG1vZHVsYXRlIHRoZVxuICogYW1wbGl0dWRlIG9mIGFub3RoZXIgVG9uZS5TeW50aC4gVGhlIGhhcm1vbmljaXR5ICh0aGUgcmF0aW8gYmV0d2VlblxuICogdGhlIHR3byBzaWduYWxzKSBhZmZlY3RzIHRoZSB0aW1icmUgb2YgdGhlIG91dHB1dCBzaWduYWwgZ3JlYXRseS5cbiAqIFJlYWQgbW9yZSBhYm91dCBBbXBsaXR1ZGUgTW9kdWxhdGlvbiBTeW50aGVzaXMgb25cbiAqIFtTb3VuZE9uU291bmRdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwNDEwMzY1My9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb206ODAvc29zL21hcjAwL2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLkFNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiNG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFNU3ludGggZXh0ZW5kcyBNb2R1bGF0aW9uU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFNU3ludGhcIjtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlID0gbmV3IEF1ZGlvVG9HYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX21vZHVsYXRpb25TY2FsZSwgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BTVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFRoaW4gd3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBXZWIgQXVkaW8gW0JpcXVhZEZpbHRlck5vZGVdKGh0dHBzOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI2JpcXVhZGZpbHRlcm5vZGUpLlxuICogQmlxdWFkRmlsdGVyIGlzIHNpbWlsYXIgdG8gW1tGaWx0ZXJdXSBidXQgZG9lc24ndCBoYXZlIHRoZSBvcHRpb24gdG8gc2V0IHRoZSBcInJvbGxvZmZcIiB2YWx1ZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEJpcXVhZEZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXF1YWRGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQmlxdWFkRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXF1YWRGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9maWx0ZXI7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5nYWluID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmdhaW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGlzIEJpcXVhZEZpbHRlck5vZGUuIEZvciBhIGNvbXBsZXRlIGxpc3Qgb2YgdHlwZXMgYW5kIHRoZWlyIGF0dHJpYnV0ZXMsIHNlZSB0aGVcbiAgICAgKiBbV2ViIEF1ZGlvIEFQSV0oaHR0cHM6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jZG9tLWJpcXVhZGZpbHRlcnR5cGUtbG93cGFzcylcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbHRlci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gW1wibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsIFwiYmFuZHBhc3NcIixcbiAgICAgICAgICAgIFwibG93c2hlbGZcIiwgXCJoaWdoc2hlbGZcIiwgXCJub3RjaFwiLCBcImFsbHBhc3NcIiwgXCJwZWFraW5nXCJdO1xuICAgICAgICBhc3NlcnQodHlwZXMuaW5kZXhPZih0eXBlKSAhPT0gLTEsIGBJbnZhbGlkIGZpbHRlciB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhbGwgMXNcbiAgICAgICAgY29uc3QgZnJlcVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybSA9IE1hdGgucG93KGkgLyBsZW4sIDIpO1xuICAgICAgICAgICAgY29uc3QgZnJlcSA9IG5vcm0gKiAoMjAwMDAgLSAyMCkgKyAyMDtcbiAgICAgICAgICAgIGZyZXFWYWx1ZXNbaV0gPSBmcmVxO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hZ1ZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgY29uc3QgcGhhc2VWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIC8vIGNsb25lIHRoZSBmaWx0ZXIgdG8gcmVtb3ZlIGFueSBjb25uZWN0aW9ucyB3aGljaCBtYXkgYmUgY2hhbmdpbmcgdGhlIHZhbHVlXG4gICAgICAgIGNvbnN0IGZpbHRlckNsb25lID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICBmaWx0ZXJDbG9uZS50eXBlID0gdGhpcy50eXBlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5RLnZhbHVlID0gdGhpcy5RLnZhbHVlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5mcmVxdWVuY3kudmFsdWUgPSB0aGlzLmZyZXF1ZW5jeS52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZ2Fpbi52YWx1ZSA9IHRoaXMuZ2Fpbi52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcVZhbHVlcywgbWFnVmFsdWVzLCBwaGFzZVZhbHVlcyk7XG4gICAgICAgIHJldHVybiBtYWdWYWx1ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpcXVhZEZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgQmlxdWFkRmlsdGVyIH0gZnJvbSBcIi4vQmlxdWFkRmlsdGVyXCI7XG4vKipcbiAqIFRvbmUuRmlsdGVyIGlzIGEgZmlsdGVyIHdoaWNoIGFsbG93cyBmb3IgYWxsIG9mIHRoZSBzYW1lIG5hdGl2ZSBtZXRob2RzXG4gKiBhcyB0aGUgW0JpcXVhZEZpbHRlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWJpcXVhZGZpbHRlcm5vZGUtaW50ZXJmYWNlKS5cbiAqIFRvbmUuRmlsdGVyIGhhcyB0aGUgYWRkZWQgYWJpbGl0eSB0byBzZXQgdGhlIGZpbHRlciByb2xsb2ZmIGF0IC0xMlxuICogKGRlZmF1bHQpLCAtMjQgYW5kIC00OC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoMTUwMCwgXCJoaWdocGFzc1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBmaWx0ZXIuZnJlcXVlbmN5LnJhbXBUbygyMDAwMCwgMTApO1xuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLmNvbm5lY3QoZmlsdGVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJyb2xsb2ZmXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmlsdGVyXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZmlsdGVycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInJvbGxvZmZcIl0pO1xuICAgICAgICB0aGlzLl9maWx0ZXJzID0gW107XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMucm9sbG9mZiA9IG9wdGlvbnMucm9sbG9mZjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZGV0dW5lXCIsIFwiZnJlcXVlbmN5XCIsIFwiZ2FpblwiLCBcIlFcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMzUwLFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgICAgIHJvbGxvZmY6IC0xMixcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIGZpbHRlci4gVHlwZXM6IFwibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsXG4gICAgICogXCJiYW5kcGFzc1wiLCBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIG9yIFwicGVha2luZ1wiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBjb25zdCB0eXBlcyA9IFtcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLCBcImJhbmRwYXNzXCIsXG4gICAgICAgICAgICBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIFwicGVha2luZ1wiXTtcbiAgICAgICAgYXNzZXJ0KHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xLCBgSW52YWxpZCBmaWx0ZXIgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiBmaWx0ZXIudHlwZSA9IHR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcm9sbG9mZiBvZiB0aGUgZmlsdGVyIHdoaWNoIGlzIHRoZSBkcm9wIGluIGRiXG4gICAgICogcGVyIG9jdGF2ZS4gSW1wbGVtZW50ZWQgaW50ZXJuYWxseSBieSBjYXNjYWRpbmcgZmlsdGVycy5cbiAgICAgKiBPbmx5IGFjY2VwdHMgdGhlIHZhbHVlcyAtMTIsIC0yNCwgLTQ4IGFuZCAtOTYuXG4gICAgICovXG4gICAgZ2V0IHJvbGxvZmYoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb2xsb2ZmO1xuICAgIH1cbiAgICBzZXQgcm9sbG9mZihyb2xsb2ZmKSB7XG4gICAgICAgIGNvbnN0IHJvbGxvZmZOdW0gPSBpc051bWJlcihyb2xsb2ZmKSA/IHJvbGxvZmYgOiBwYXJzZUludChyb2xsb2ZmLCAxMCk7XG4gICAgICAgIGNvbnN0IHBvc3NpYmlsaXRpZXMgPSBbLTEyLCAtMjQsIC00OCwgLTk2XTtcbiAgICAgICAgbGV0IGNhc2NhZGluZ0NvdW50ID0gcG9zc2liaWxpdGllcy5pbmRleE9mKHJvbGxvZmZOdW0pO1xuICAgICAgICAvLyBjaGVjayB0aGUgcm9sbG9mZiBpcyB2YWxpZFxuICAgICAgICBhc3NlcnQoY2FzY2FkaW5nQ291bnQgIT09IC0xLCBgcm9sbG9mZiBjYW4gb25seSBiZSAke3Bvc3NpYmlsaXRpZXMuam9pbihcIiwgXCIpfWApO1xuICAgICAgICBjYXNjYWRpbmdDb3VudCArPSAxO1xuICAgICAgICB0aGlzLl9yb2xsb2ZmID0gcm9sbG9mZk51bTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4gZmlsdGVyLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMgPSBuZXcgQXJyYXkoY2FzY2FkaW5nQ291bnQpO1xuICAgICAgICBmb3IgKGxldCBjb3VudCA9IDA7IGNvdW50IDwgY2FzY2FkaW5nQ291bnQ7IGNvdW50KyspIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IG5ldyBCaXF1YWRGaWx0ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmlsdGVyLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdChmaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QoZmlsdGVyLmRldHVuZSk7XG4gICAgICAgICAgICB0aGlzLlEuY29ubmVjdChmaWx0ZXIuUSk7XG4gICAgICAgICAgICB0aGlzLmdhaW4uY29ubmVjdChmaWx0ZXIuZ2Fpbik7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXJzW2NvdW50XSA9IGZpbHRlcjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gdGhpcy5fZmlsdGVycztcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9pbnRlcm5hbENoYW5uZWxzLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlckNsb25lID0gbmV3IEJpcXVhZEZpbHRlcih7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IHRoaXMuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgZ2FpbjogdGhpcy5nYWluLnZhbHVlLFxuICAgICAgICAgICAgUTogdGhpcy5RLnZhbHVlLFxuICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgIGRldHVuZTogdGhpcy5kZXR1bmUudmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB3aXRoIGFsbCAxc1xuICAgICAgICBjb25zdCB0b3RhbFJlc3BvbnNlID0gbmV3IEZsb2F0MzJBcnJheShsZW4pLm1hcCgoKSA9PiAxKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZmlsdGVyQ2xvbmUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2goKHZhbCwgaSkgPT4gdG90YWxSZXNwb25zZVtpXSAqPSB2YWwpO1xuICAgICAgICB9KTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdG90YWxSZXNwb25zZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IHtcbiAgICAgICAgICAgIGZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBbXCJkZXR1bmVcIiwgXCJmcmVxdWVuY3lcIiwgXCJnYWluXCIsIFwiUVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFBvdyB9IGZyb20gXCIuLi8uLi9zaWduYWwvUG93XCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogRnJlcXVlbmN5RW52ZWxvcGUgaXMgYW4gW1tFbnZlbG9wZV1dIHdoaWNoIHJhbXBzIGJldHdlZW4gW1tiYXNlRnJlcXVlbmN5XV1cbiAqIGFuZCBbW29jdGF2ZXNdXS4gSXQgY2FuIGFsc28gaGF2ZSBhbiBvcHRpb25hbCBbW2V4cG9uZW50XV0gdG8gYWRqdXN0IHRoZSBjdXJ2ZVxuICogd2hpY2ggaXQgcmFtcHMuXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIGNvbnN0IGZyZXFFbnYgPSBuZXcgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZSh7XG4gKiBcdGF0dGFjazogMC4yLFxuICogXHRiYXNlRnJlcXVlbmN5OiBcIkMyXCIsXG4gKiBcdG9jdGF2ZXM6IDRcbiAqIH0pO1xuICogZnJlcUVudi5jb25uZWN0KG9zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAqIGZyZXFFbnYudHJpZ2dlckF0dGFjaygpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRnJlcXVlbmN5RW52ZWxvcGUgZXh0ZW5kcyBFbnZlbG9wZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeUVudmVsb3BlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IHRoaXMuaW5wdXQgPSBuZXcgUG93KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmV4cG9uZW50XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMub3V0cHV0ID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogdGhpcy5fYmFzZUZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1heDogdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIHRoaXMuX29jdGF2ZXMpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2lnLmNoYWluKHRoaXMuX2V4cG9uZW50LCB0aGlzLl9zY2FsZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgZXhwb25lbnQ6IDEsXG4gICAgICAgICAgICBvY3RhdmVzOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVudmVsb3BlJ3MgbWluaW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgaXMgdGhlIHZhbHVlIHdoaWNoIGl0XG4gICAgICogc3RhcnRzIGF0LlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3kobWluKSB7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KG1pbik7XG4gICAgICAgIGFzc2VydFJhbmdlKGZyZXEsIDApO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gZnJlcTtcbiAgICAgICAgdGhpcy5fc2NhbGUubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBtYXggdmFsdWUgd2hlbiB0aGUgbWluIGNoYW5nZXNcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5IHRoYXQgdGhlXG4gICAgICogZW52ZWxvcGUgd2lsbCBzY2FsZSB0by5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX3NjYWxlLm1heCA9IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVudmVsb3BlJ3MgZXhwb25lbnQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IGV4cG9uZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwb25lbnQudmFsdWU7XG4gICAgfVxuICAgIHNldCBleHBvbmVudChleHBvbmVudCkge1xuICAgICAgICB0aGlzLl9leHBvbmVudC52YWx1ZSA9IGV4cG9uZW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi4vaW5zdHJ1bWVudC9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9GcmVxdWVuY3lFbnZlbG9wZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBNb25vU3ludGggaXMgY29tcG9zZWQgb2Ygb25lIGBvc2NpbGxhdG9yYCwgb25lIGBmaWx0ZXJgLCBhbmQgdHdvIGBlbnZlbG9wZXNgLlxuICogVGhlIGFtcGxpdHVkZSBvZiB0aGUgT3NjaWxsYXRvciBhbmQgdGhlIGN1dG9mZiBmcmVxdWVuY3kgb2YgdGhlXG4gKiBGaWx0ZXIgYXJlIGNvbnRyb2xsZWQgYnkgRW52ZWxvcGVzLlxuICogPGltZyBzcmM9XCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kcmF3aW5ncy9kLzFnYVkxREY5X0h6a29kcWY4SkkxQ2cyVlpmd1NFbHBGUWZJOTRJUXdhZDM4L3B1Yj93PTkyNCZoPTI0MFwiPlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTW9ub1N5bnRoKHtcbiAqIFx0b3NjaWxsYXRvcjoge1xuICogXHRcdHR5cGU6IFwic3F1YXJlXCJcbiAqIFx0fSxcbiAqIFx0ZW52ZWxvcGU6IHtcbiAqIFx0XHRhdHRhY2s6IDAuMVxuICogXHR9XG4gKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTW9ub1N5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb25vU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBuZXcgT21uaU9zY2lsbGF0b3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm9zY2lsbGF0b3IsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zLmZpbHRlciwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlID0gbmV3IEZyZXF1ZW5jeUVudmVsb3BlKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXJFbnZlbG9wZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5lbnZlbG9wZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBvc2NpbGxhdG9ycyB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5jaGFpbih0aGlzLmZpbHRlciwgdGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBmaWx0ZXIgZW52ZWxvcGVcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5jb25uZWN0KHRoaXMuZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm9zY2lsbGF0b3JcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJmaWx0ZXJcIiwgXCJmaWx0ZXJFbnZlbG9wZVwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC45LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWx0ZXI6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRmlsdGVyLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgICAgICByb2xsb2ZmOiAtMTIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjYsXG4gICAgICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjIsXG4gICAgICAgICAgICAgICAgZXhwb25lbnQ6IDIsXG4gICAgICAgICAgICAgICAgb2N0YXZlczogMyxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAyLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuNSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIGF0dGFjayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlICgwLTEpXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkQXR0YWNrID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spO1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWREZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpO1xuICAgICAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIGNvbXB1dGVkQXR0YWNrICsgY29tcHV0ZWREZWNheSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgcmVsZWFzZSBzaG91bGQgc3RhcnRcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb25vU3ludGguanMubWFwIiwiaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IE1vbm9TeW50aCB9IGZyb20gXCIuL01vbm9TeW50aFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IEdhaW4sIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBEdW9TeW50aCBpcyBhIG1vbm9waG9uaWMgc3ludGggY29tcG9zZWQgb2YgdHdvIFtbTW9ub1N5bnRoc11dIHJ1biBpbiBwYXJhbGxlbCB3aXRoIGNvbnRyb2wgb3ZlciB0aGVcbiAqIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gdm9pY2VzIGFuZCB2aWJyYXRvIGVmZmVjdC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkdW9TeW50aCA9IG5ldyBUb25lLkR1b1N5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogZHVvU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjJuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIER1b1N5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKER1b1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkR1b1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEdW9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnZvaWNlMCA9IG5ldyBNb25vU3ludGgoT2JqZWN0LmFzc2lnbihvcHRpb25zLnZvaWNlMCwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb25zaWxlbmNlOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKVxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMudm9pY2UxID0gbmV3IE1vbm9TeW50aChPYmplY3QuYXNzaWduKG9wdGlvbnMudm9pY2UxLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl92aWJyYXRvID0gbmV3IExGTyh7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMudmlicmF0b1JhdGUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IC01MCxcbiAgICAgICAgICAgIG1heDogNTBcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSB2aWJyYXRvIGltbWVkaWF0ZWx5XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uc3RhcnQoKTtcbiAgICAgICAgdGhpcy52aWJyYXRvUmF0ZSA9IHRoaXMuX3ZpYnJhdG8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl92aWJyYXRvR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLnZpYnJhdG9BbW91bnRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlicmF0b0Ftb3VudCA9IHRoaXMuX3ZpYnJhdG9HYWluLmdhaW47XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiA0NDBcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMudm9pY2UwLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMudm9pY2UxLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uY29ubmVjdCh0aGlzLl92aWJyYXRvR2Fpbik7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmZhbih0aGlzLnZvaWNlMC5kZXR1bmUsIHRoaXMudm9pY2UxLmRldHVuZSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLnZvaWNlMC5kZXR1bmUsIHRoaXMudm9pY2UxLmRldHVuZSk7XG4gICAgICAgIHRoaXMudm9pY2UwLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLnZvaWNlMS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1widm9pY2UwXCIsIFwidm9pY2UxXCIsIFwiZnJlcXVlbmN5XCIsIFwidmlicmF0b0Ftb3VudFwiLCBcInZpYnJhdG9SYXRlXCJdKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnZvaWNlMC5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSArIHRoaXMudm9pY2UxLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2aWJyYXRvQW1vdW50OiAwLjUsXG4gICAgICAgICAgICB2aWJyYXRvUmF0ZTogNSxcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLjUsXG4gICAgICAgICAgICB2b2ljZTA6IGRlZXBNZXJnZShvbWl0RnJvbU9iamVjdChNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHZvaWNlMTogZGVlcE1lcmdlKG9taXRGcm9tT2JqZWN0KE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTAuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTEuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMC5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMS5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2ljZTAuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvaWNlMS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92aWJyYXRvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52aWJyYXRvUmF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUR1b1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBNb2R1bGF0aW9uU3ludGggfSBmcm9tIFwiLi9Nb2R1bGF0aW9uU3ludGhcIjtcbi8qKlxuICogRk1TeW50aCBpcyBjb21wb3NlZCBvZiB0d28gVG9uZS5TeW50aHMgd2hlcmUgb25lIFRvbmUuU3ludGggbW9kdWxhdGVzXG4gKiB0aGUgZnJlcXVlbmN5IG9mIGEgc2Vjb25kIFRvbmUuU3ludGguIEEgbG90IG9mIHNwZWN0cmFsIGNvbnRlbnRcbiAqIGNhbiBiZSBleHBsb3JlZCB1c2luZyB0aGUgbW9kdWxhdGlvbkluZGV4IHBhcmFtZXRlci4gUmVhZCBtb3JlIGFib3V0XG4gKiBmcmVxdWVuY3kgbW9kdWxhdGlvbiBzeW50aGVzaXMgb24gU291bmQgT24gU291bmQ6IFtQYXJ0IDFdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwMzEyMzcwNC9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb20vc29zL2FwcjAwL2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLCBbUGFydCAyXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDMxMTU4MzUvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9tYXkwMC9hcnRpY2xlcy9zeW50aC5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmbVN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNVwiLCBcIjRuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGTVN5bnRoIGV4dGVuZHMgTW9kdWxhdGlvblN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGTVN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5tb2R1bGF0aW9uSW5kZXgsIHRoaXMuX21vZHVsYXRpb25Ob2RlKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNvbm5lY3QodGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDEwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZNU3ludGguanMubWFwIiwiaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZNT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9GTU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG4vKipcbiAqIEluaGFybW9uaWMgcmF0aW8gb2YgZnJlcXVlbmNpZXMgYmFzZWQgb24gdGhlIFJvbGFuZCBUUi04MDhcbiAqIFRha2VuIGZyb20gaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvcGFwZXJzL3RyLTgwOC1jeW1iYWwtcGh5c2ljYWxseS1pbmZvcm1lZC1jaXJjdWl0LWJlbmRhYmxlLWRpZ2l0YWwtbW9kZWxcbiAqL1xuY29uc3QgaW5oYXJtUmF0aW9zID0gWzEuMCwgMS40ODMsIDEuOTMyLCAyLjU0NiwgMi42MzAsIDMuODk3XTtcbi8qKlxuICogQSBoaWdobHkgaW5oYXJtb25pYyBhbmQgc3BlY3RyYWxseSBjb21wbGV4IHNvdXJjZSB3aXRoIGEgaGlnaHBhc3MgZmlsdGVyXG4gKiBhbmQgYW1wbGl0dWRlIGVudmVsb3BlIHdoaWNoIGlzIGdvb2QgZm9yIG1ha2luZyBtZXRhbGxvcGhvbmUgc291bmRzLlxuICogQmFzZWQgb24gQ3ltYmFsU3ludGggYnkgW0Bwb2x5cmh5dGhtYXRpY10oaHR0cHM6Ly9naXRodWIuY29tL3BvbHlyaHl0aG1hdGljKS5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1NvdW5kIG9uIFNvdW5kXShodHRwczovL3Nob3J0dXJsLmF0L3JTWjEyKS5cbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRhbFN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGFsU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0YWxTeW50aFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFycmF5IG9mIEZNT3NjaWxsYXRvcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZnJlcXVlbmN5IG11bHRpcGxpZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9mcmVxTXVsdGlwbGllcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGFsU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5faGlnaHBhc3MgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIC8vIFE6IC0zLjAxMDI5OTk1NjYzOTgxMjUsXG4gICAgICAgICAgICBROiAwLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJoaWdocGFzc1wiLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5oYXJtUmF0aW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBvc2MgPSBuZXcgRk1Pc2NpbGxhdG9yKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgaGFybW9uaWNpdHk6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgICAgICAgICBvbnN0b3A6IGkgPT09IDAgPyAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSA6IG5vT3AsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgb3NjLmNvbm5lY3QodGhpcy5faGlnaHBhc3MpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0gPSBvc2M7XG4gICAgICAgICAgICBjb25zdCBtdWx0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGluaGFybVJhdGlvc1tpXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzW2ldID0gbXVsdDtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKG11bHQsIG9zYy5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdChvc2MuZGV0dW5lKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heDogNzAwMCxcbiAgICAgICAgICAgIG1pbjogdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLnJlc29uYW5jZSksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEVudmVsb3BlKHtcbiAgICAgICAgICAgIGF0dGFjazogb3B0aW9ucy5lbnZlbG9wZS5hdHRhY2ssXG4gICAgICAgICAgICBhdHRhY2tDdXJ2ZTogXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlY2F5OiBvcHRpb25zLmVudmVsb3BlLmRlY2F5LFxuICAgICAgICAgICAgcmVsZWFzZTogb3B0aW9ucy5lbnZlbG9wZS5yZWxlYXNlLFxuICAgICAgICAgICAgc3VzdGFpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuY2hhaW4odGhpcy5fZmlsdGVyRnJlcVNjYWxlciwgdGhpcy5faGlnaHBhc3MuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZS5nYWluKTtcbiAgICAgICAgLy8gc2V0IHRoZSBvY3RhdmVzXG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDAxLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAxLjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBoYXJtb25pY2l0eTogNS4xLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAzMixcbiAgICAgICAgICAgIG9jdGF2ZXM6IDEuNSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogNDAwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjay5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRoYXQgdGhlIGVudmVsb3BlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KHRpbWUpKTtcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4ge1xuICAgICAgICAgICAgICAgIG9zYy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgZW52ZWxvcGUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgcmVsZWFzZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb25JbmRleCBvZiB0aGUgb3NjaWxsYXRvcnMgd2hpY2ggbWFrZSB1cCB0aGUgc291cmNlLlxuICAgICAqIHNlZSBbW0ZNT3NjaWxsYXRvci5tb2R1bGF0aW9uSW5kZXhdXVxuICAgICAqIEBtaW4gMVxuICAgICAqIEBtYXggMTAwXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25JbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLm1vZHVsYXRpb25JbmRleC52YWx1ZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25JbmRleCh2YWwpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gKG9zYy5tb2R1bGF0aW9uSW5kZXgudmFsdWUgPSB2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGhhcm1vbmljaXR5IG9mIHRoZSBvc2NpbGxhdG9ycyB3aGljaCBtYWtlIHVwIHRoZSBzb3VyY2UuXG4gICAgICogc2VlIFRvbmUuRk1Pc2NpbGxhdG9yLmhhcm1vbmljaXR5XG4gICAgICogQG1pbiAwLjFcbiAgICAgKiBAbWF4IDEwXG4gICAgICovXG4gICAgZ2V0IGhhcm1vbmljaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0uaGFybW9uaWNpdHkudmFsdWU7XG4gICAgfVxuICAgIHNldCBoYXJtb25pY2l0eSh2YWwpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gKG9zYy5oYXJtb25pY2l0eS52YWx1ZSA9IHZhbCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG93ZXIgbGV2ZWwgb2YgdGhlIGhpZ2hwYXNzIGZpbHRlciB3aGljaCBpcyBhdHRhY2hlZCB0byB0aGUgZW52ZWxvcGUuXG4gICAgICogVGhpcyB2YWx1ZSBzaG91bGQgYmUgYmV0d2VlbiBbMCwgNzAwMF1cbiAgICAgKiBAbWluIDBcbiAgICAgKiBAbWF4IDcwMDBcbiAgICAgKi9cbiAgICBnZXQgcmVzb25hbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5taW47XG4gICAgfVxuICAgIHNldCByZXNvbmFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluID0gdGhpcy50b0ZyZXF1ZW5jeSh2YWwpO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgYWJvdmUgdGhlIFwicmVzb25hbmNlXCIgZnJlcXVlbmN5XG4gICAgICogdGhhdCB0aGUgZmlsdGVyIHJhbXBzIGR1cmluZyB0aGUgYXR0YWNrL2RlY2F5IGVudmVsb3BlXG4gICAgICogQG1pbiAwXG4gICAgICogQG1heCA4XG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyh2YWwpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IHZhbDtcbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5tYXggPSB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbiAqIE1hdGgucG93KDIsIHZhbCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVycy5mb3JFYWNoKGZyZXFNdWx0ID0+IGZyZXFNdWx0LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2hpZ2hwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0YWxTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IHJhbmdlLCB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBNZW1icmFuZVN5bnRoIG1ha2VzIGtpY2sgYW5kIHRvbSBzb3VuZHMgdXNpbmcgYSBzaW5nbGUgb3NjaWxsYXRvclxuICogd2l0aCBhbiBhbXBsaXR1ZGUgZW52ZWxvcGUgYW5kIGZyZXF1ZW5jeSByYW1wLiBBIFRvbmUuT21uaU9zY2lsbGF0b3JcbiAqIGlzIHJvdXRlZCB0aHJvdWdoIGEgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSB0byB0aGUgb3V0cHV0LiBUaGUgZHJ1bVxuICogcXVhbGl0eSBvZiB0aGUgc291bmQgY29tZXMgZnJvbSB0aGUgZnJlcXVlbmN5IGVudmVsb3BlIGFwcGxpZWRcbiAqIGR1cmluZyBNZW1icmFuZVN5bnRoLnRyaWdnZXJBdHRhY2sobm90ZSkuIFRoZSBmcmVxdWVuY3kgZW52ZWxvcGVcbiAqIHN0YXJ0cyBhdCA8Y29kZT5ub3RlICogLm9jdGF2ZXM8L2NvZGU+IGFuZCByYW1wcyB0byA8Y29kZT5ub3RlPC9jb2RlPlxuICogb3ZlciB0aGUgZHVyYXRpb24gb2YgPGNvZGU+LnBpdGNoRGVjYXk8L2NvZGU+LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZW1icmFuZVN5bnRoIGV4dGVuZHMgU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZW1icmFuZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1lbWJyYW5lU3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBvcnRhbWVudG8gaXMgaWdub3JlZCBpbiB0aGlzIHN5bnRoLiB1c2UgcGl0Y2ggZGVjYXkgaW5zdGVhZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucG9ydGFtZW50byA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZW1icmFuZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucGl0Y2hEZWNheSA9IG9wdGlvbnMucGl0Y2hEZWNheTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJvc2NpbGxhdG9yXCIsIFwiZW52ZWxvcGVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBTeW50aC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDEsXG4gICAgICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgICAgICBkZWNheTogMC40LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEuNCxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDEwLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBpdGNoRGVjYXk6IDAuMDUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzZXROb3RlKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBoZXJ0eiA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSBpbnN0YW5jZW9mIEZyZXF1ZW5jeUNsYXNzID8gbm90ZS50b0ZyZXF1ZW5jeSgpIDogbm90ZSk7XG4gICAgICAgIGNvbnN0IG1heE5vdGUgPSBoZXJ0eiAqIHRoaXMub2N0YXZlcztcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShtYXhOb3RlLCBzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKGhlcnR6LCBzZWNvbmRzICsgdGhpcy50b1NlY29uZHModGhpcy5waXRjaERlY2F5KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHJhbmdlKDApXG5dLCBNZW1icmFuZVN5bnRoLnByb3RvdHlwZSwgXCJvY3RhdmVzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIE1lbWJyYW5lU3ludGgucHJvdG90eXBlLCBcInBpdGNoRGVjYXlcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1lbWJyYW5lU3ludGguanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG4vKipcbiAqIFRvbmUuTm9pc2VTeW50aCBpcyBjb21wb3NlZCBvZiBbW05vaXNlXV0gdGhyb3VnaCBhbiBbW0FtcGxpdHVkZUVudmVsb3BlXV0uXG4gKiBgYGBcbiAqICstLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCBOb2lzZSArPi0tPiBBbXBsaXR1ZGVFbnZlbG9wZSArPi0tPiBPdXRwdXRcbiAqICstLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBub2lzZVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiOG5cIiwgMC4wNSk7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTm9pc2VTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk5vaXNlU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5ub2lzZSA9IG5ldyBOb2lzZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5ub2lzZSkpO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLmVudmVsb3BlKSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG5vaXNlIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5ub2lzZS5jaGFpbih0aGlzLmVudmVsb3BlLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4wLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBub2lzZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChOb2lzZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blcy4gVW5saWtlIG90aGVyXG4gICAgICogaW5zdHJ1bWVudHMsIFRvbmUuTm9pc2VTeW50aCBkb2Vzbid0IGhhdmUgYSBub3RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogbm9pc2VTeW50aC50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyB0aGUgZW52ZWxvcGVzXG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBub2lzZVxuICAgICAgICB0aGlzLm5vaXNlLnN0YXJ0KHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLm5vaXNlLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVzLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm5vaXNlLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAwKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKHRpbWUgKyBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubm9pc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Tm9pc2VTeW50aC5qcy5tYXAiLCIvKipcbiAqIEFsbCBvZiB0aGUgY2xhc3NlcyBvciBmdW5jdGlvbnMgd2hpY2ggYXJlIGxvYWRlZCBpbnRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5jb25zdCB3b3JrbGV0Q29udGV4dCA9IG5ldyBTZXQoKTtcbi8qKlxuICogQWRkIGEgY2xhc3MgdG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUb1dvcmtsZXQoY2xhc3NPckZ1bmN0aW9uKSB7XG4gICAgd29ya2xldENvbnRleHQuYWRkKGNsYXNzT3JGdW5jdGlvbik7XG59XG4vKipcbiAqIFJlZ2lzdGVyIGEgcHJvY2Vzc29yIGluIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSB3aXRoIHRoZSBnaXZlbiBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclByb2Nlc3NvcihuYW1lLCBjbGFzc0Rlc2MpIHtcbiAgICBjb25zdCBwcm9jZXNzb3IgPSAvKiBqYXZhc2NyaXB0ICovIGByZWdpc3RlclByb2Nlc3NvcihcIiR7bmFtZX1cIiwgJHtjbGFzc0Rlc2N9KWA7XG4gICAgd29ya2xldENvbnRleHQuYWRkKHByb2Nlc3Nvcik7XG59XG4vKipcbiAqIEdldCBhbGwgb2YgdGhlIG1vZHVsZXMgd2hpY2ggaGF2ZSBiZWVuIHJlZ2lzdGVyZWQgdG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3JrbGV0R2xvYmFsU2NvcGUoKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20od29ya2xldENvbnRleHQpLmpvaW4oXCJcXG5cIik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Xb3JrbGV0R2xvYmFsU2NvcGUuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGdldFdvcmtsZXRHbG9iYWxTY29wZSB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb1dvcmtsZXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb1dvcmtsZXRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb25zdHJ1Y3RvciBvcHRpb25zIGZvciB0aGUgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy53b3JrbGV0T3B0aW9ucyA9IHt9O1xuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCB3aGVuIHRoZXJlIGlzIGFuIGVycm9yIGluIHRoZSBwcm9jZXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9ucHJvY2Vzc29yZXJyb3IgPSBub09wO1xuICAgICAgICBjb25zdCBibG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbZ2V0V29ya2xldEdsb2JhbFNjb3BlKCldLCB7IHR5cGU6IFwidGV4dC9qYXZhc2NyaXB0XCIgfSkpO1xuICAgICAgICBjb25zdCBuYW1lID0gdGhpcy5fYXVkaW9Xb3JrbGV0TmFtZSgpO1xuICAgICAgICB0aGlzLl9kdW1teUdhaW4gPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICB0aGlzLl9kdW1teVBhcmFtID0gdGhpcy5fZHVtbXlHYWluLmdhaW47XG4gICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBwcm9jZXNzb3JcbiAgICAgICAgdGhpcy5jb250ZXh0LmFkZEF1ZGlvV29ya2xldE1vZHVsZShibG9iVXJsLCBuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgd29ya2xldCB3aGVuIGl0J3MgcmVhZFxuICAgICAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldCA9IHRoaXMuY29udGV4dC5jcmVhdGVBdWRpb1dvcmtsZXROb2RlKG5hbWUsIHRoaXMud29ya2xldE9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQub25wcm9jZXNzb3JlcnJvciA9IHRoaXMub25wcm9jZXNzb3JlcnJvci5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMub25SZWFkeSh0aGlzLl93b3JrbGV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlHYWluLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgaWYgKHRoaXMuX3dvcmtsZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQucG9ydC5wb3N0TWVzc2FnZShcImRpc3Bvc2VcIik7XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9Xb3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuY29uc3QgdG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHQvKipcblx0ICogVGhlIGJhc2UgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGZvciB1c2UgaW4gVG9uZS5qcy4gV29ya3Mgd2l0aCB0aGUgW1tUb25lQXVkaW9Xb3JrbGV0XV0uIFxuXHQgKi9cblx0Y2xhc3MgVG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRcblx0XHRcdHN1cGVyKG9wdGlvbnMpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiBJZiB0aGUgcHJvY2Vzc29yIHdhcyBkaXNwb3NlZCBvciBub3QuIEtlZXAgYWxpdmUgdW50aWwgaXQncyBkaXNwb3NlZC5cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5kaXNwb3NlZCA9IGZhbHNlO1xuXHRcdCAgIFx0LyoqIFxuXHRcdFx0ICogVGhlIG51bWJlciBvZiBzYW1wbGVzIGluIHRoZSBwcm9jZXNzaW5nIGJsb2NrXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuYmxvY2tTaXplID0gMTI4O1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0aGUgc2FtcGxlIHJhdGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcblxuXHRcdFx0dGhpcy5wb3J0Lm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuXHRcdFx0XHQvLyB3aGVuIGl0IHJlY2VpdmVzIGEgZGlzcG9zZSBcblx0XHRcdFx0aWYgKGV2ZW50LmRhdGEgPT09IFwiZGlzcG9zZVwiKSB7XG5cdFx0XHRcdFx0dGhpcy5kaXNwb3NlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHR9XG5gO1xuYWRkVG9Xb3JrbGV0KHRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCBcIi4vVG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCBzaW5nbGVJT1Byb2Nlc3MgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0LyoqXG5cdCAqIEFic3RyYWN0IGNsYXNzIGZvciBhIHNpbmdsZSBpbnB1dC9vdXRwdXQgcHJvY2Vzc29yLiBcblx0ICogaGFzIGEgJ2dlbmVyYXRlJyBmdW5jdGlvbiB3aGljaCBwcm9jZXNzZXMgb25lIHNhbXBsZSBhdCBhIHRpbWVcblx0ICovXG5cdGNsYXNzIFNpbmdsZUlPUHJvY2Vzc29yIGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnMsIHtcblx0XHRcdFx0bnVtYmVyT2ZJbnB1dHM6IDEsXG5cdFx0XHRcdG51bWJlck9mT3V0cHV0czogMVxuXHRcdFx0fSkpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiBIb2xkcyB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGFuZCBhIHNpbmdsZSB2YWx1ZSBvZiB0aGF0XG5cdFx0XHQgKiBwYXJhbWV0ZXIgYXQgdGhlIGN1cnJlbnQgc2FtcGxlXG5cdFx0XHQgKiBAdHlwZSB7IFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnBhcmFtcyA9IHt9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogR2VuZXJhdGUgYW4gb3V0cHV0IHNhbXBsZSBmcm9tIHRoZSBpbnB1dCBzYW1wbGUgYW5kIHBhcmFtZXRlcnNcblx0XHQgKiBAYWJzdHJhY3Rcblx0XHQgKiBAcGFyYW0gaW5wdXQgbnVtYmVyXG5cdFx0ICogQHBhcmFtIGNoYW5uZWwgbnVtYmVyXG5cdFx0ICogQHBhcmFtIHBhcmFtZXRlcnMgeyBbbmFtZTogc3RyaW5nXTogbnVtYmVyIH1cblx0XHQgKiBAcmV0dXJucyBudW1iZXJcblx0XHQgKi9cblx0XHRnZW5lcmF0ZSgpe31cblxuXHRcdC8qKlxuXHRcdCAqIFVwZGF0ZSB0aGUgcHJpdmF0ZSBwYXJhbXMgb2JqZWN0IHdpdGggdGhlIFxuXHRcdCAqIHZhbHVlcyBvZiB0aGUgcGFyYW1ldGVycyBhdCB0aGUgZ2l2ZW4gaW5kZXhcblx0XHQgKiBAcGFyYW0gcGFyYW1ldGVycyB7IFtuYW1lOiBzdHJpbmddOiBGbG9hdDMyQXJyYXkgfSxcblx0XHQgKiBAcGFyYW0gaW5kZXggbnVtYmVyXG5cdFx0ICovXG5cdFx0dXBkYXRlUGFyYW1zKHBhcmFtZXRlcnMsIGluZGV4KSB7XG5cdFx0XHRmb3IgKGNvbnN0IHBhcmFtTmFtZSBpbiBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRcdGNvbnN0IHBhcmFtID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdO1xuXHRcdFx0XHRpZiAocGFyYW0ubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdHRoaXMucGFyYW1zW3BhcmFtTmFtZV0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV1baW5kZXhdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMucGFyYW1zW3BhcmFtTmFtZV0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV1bMF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBQcm9jZXNzIGEgc2luZ2xlIGZyYW1lIG9mIHRoZSBhdWRpb1xuXHRcdCAqIEBwYXJhbSBpbnB1dHMgRmxvYXQzMkFycmF5W11bXVxuXHRcdCAqIEBwYXJhbSBvdXRwdXRzIEZsb2F0MzJBcnJheVtdW11cblx0XHQgKi9cblx0XHRwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykge1xuXHRcdFx0Y29uc3QgaW5wdXQgPSBpbnB1dHNbMF07XG5cdFx0XHRjb25zdCBvdXRwdXQgPSBvdXRwdXRzWzBdO1xuXHRcdFx0Ly8gZ2V0IHRoZSBwYXJhbWV0ZXIgdmFsdWVzXG5cdFx0XHRjb25zdCBjaGFubmVsQ291bnQgPSBNYXRoLm1heChpbnB1dCAmJiBpbnB1dC5sZW5ndGggfHwgMCwgb3V0cHV0Lmxlbmd0aCk7XG5cdFx0XHRmb3IgKGxldCBzYW1wbGUgPSAwOyBzYW1wbGUgPCB0aGlzLmJsb2NrU2l6ZTsgc2FtcGxlKyspIHtcblx0XHRcdFx0dGhpcy51cGRhdGVQYXJhbXMocGFyYW1ldGVycywgc2FtcGxlKTtcblx0XHRcdFx0Zm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBjaGFubmVsQ291bnQ7IGNoYW5uZWwrKykge1xuXHRcdFx0XHRcdGNvbnN0IGlucHV0U2FtcGxlID0gaW5wdXQgJiYgaW5wdXQubGVuZ3RoID8gaW5wdXRbY2hhbm5lbF1bc2FtcGxlXSA6IDA7XG5cdFx0XHRcdFx0b3V0cHV0W2NoYW5uZWxdW3NhbXBsZV0gPSB0aGlzLmdlbmVyYXRlKGlucHV0U2FtcGxlLCBjaGFubmVsLCB0aGlzLnBhcmFtcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiAhdGhpcy5kaXNwb3NlZDtcblx0XHR9XG5cdH07XG5gO1xuYWRkVG9Xb3JrbGV0KHNpbmdsZUlPUHJvY2Vzcyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuY29uc3QgZGVsYXlMaW5lID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdC8qKlxuXHQgKiBBIG11bHRpY2hhbm5lbCBidWZmZXIgZm9yIHVzZSB3aXRoaW4gYW4gQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGFzIGEgZGVsYXkgbGluZVxuXHQgKi9cblx0Y2xhc3MgRGVsYXlMaW5lIHtcblx0XHRcblx0XHRjb25zdHJ1Y3RvcihzaXplLCBjaGFubmVscykge1xuXHRcdFx0dGhpcy5idWZmZXIgPSBbXTtcblx0XHRcdHRoaXMud3JpdGVIZWFkID0gW11cblx0XHRcdHRoaXMuc2l6ZSA9IHNpemU7XG5cblx0XHRcdC8vIGNyZWF0ZSB0aGUgZW1wdHkgY2hhbm5lbHNcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbHM7IGkrKykge1xuXHRcdFx0XHR0aGlzLmJ1ZmZlcltpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaXplKTtcblx0XHRcdFx0dGhpcy53cml0ZUhlYWRbaV0gPSAwO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIFB1c2ggYSB2YWx1ZSBvbnRvIHRoZSBlbmRcblx0XHQgKiBAcGFyYW0gY2hhbm5lbCBudW1iZXJcblx0XHQgKiBAcGFyYW0gdmFsdWUgbnVtYmVyXG5cdFx0ICovXG5cdFx0cHVzaChjaGFubmVsLCB2YWx1ZSkge1xuXHRcdFx0dGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gKz0gMTtcblx0XHRcdGlmICh0aGlzLndyaXRlSGVhZFtjaGFubmVsXSA+IHRoaXMuc2l6ZSkge1xuXHRcdFx0XHR0aGlzLndyaXRlSGVhZFtjaGFubmVsXSA9IDA7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmJ1ZmZlcltjaGFubmVsXVt0aGlzLndyaXRlSGVhZFtjaGFubmVsXV0gPSB2YWx1ZTtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBHZXQgdGhlIHJlY29yZGVkIHZhbHVlIG9mIHRoZSBjaGFubmVsIGdpdmVuIHRoZSBkZWxheVxuXHRcdCAqIEBwYXJhbSBjaGFubmVsIG51bWJlclxuXHRcdCAqIEBwYXJhbSBkZWxheSBudW1iZXIgZGVsYXkgc2FtcGxlc1xuXHRcdCAqL1xuXHRcdGdldChjaGFubmVsLCBkZWxheSkge1xuXHRcdFx0bGV0IHJlYWRIZWFkID0gdGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gLSBNYXRoLmZsb29yKGRlbGF5KTtcblx0XHRcdGlmIChyZWFkSGVhZCA8IDApIHtcblx0XHRcdFx0cmVhZEhlYWQgKz0gdGhpcy5zaXplO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXMuYnVmZmVyW2NoYW5uZWxdW3JlYWRIZWFkXTtcblx0XHR9XG5cdH1cbmA7XG5hZGRUb1dvcmtsZXQoZGVsYXlMaW5lKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlbGF5TGluZS53b3JrbGV0LmpzLm1hcCIsImltcG9ydCBcIi4uLy4uL2NvcmUvd29ya2xldC9TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgXCIuLi8uLi9jb3JlL3dvcmtsZXQvRGVsYXlMaW5lLndvcmtsZXRcIjtcbmltcG9ydCB7IHJlZ2lzdGVyUHJvY2Vzc29yIH0gZnJvbSBcIi4uLy4uL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCB3b3JrbGV0TmFtZSA9IFwiZmVlZGJhY2stY29tYi1maWx0ZXJcIjtcbmNvbnN0IGZlZWRiYWNrQ29tYkZpbHRlciA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHRjbGFzcyBGZWVkYmFja0NvbWJGaWx0ZXJXb3JrbGV0IGV4dGVuZHMgU2luZ2xlSU9Qcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0c3VwZXIob3B0aW9ucyk7XG5cdFx0XHR0aGlzLmRlbGF5TGluZSA9IG5ldyBEZWxheUxpbmUodGhpcy5zYW1wbGVSYXRlLCBvcHRpb25zLmNoYW5uZWxDb3VudCB8fCAyKTtcblx0XHR9XG5cblx0XHRzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkge1xuXHRcdFx0cmV0dXJuIFt7XG5cdFx0XHRcdG5hbWU6IFwiZGVsYXlUaW1lXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMC4xLFxuXHRcdFx0XHRtaW5WYWx1ZTogMCxcblx0XHRcdFx0bWF4VmFsdWU6IDEsXG5cdFx0XHRcdGF1dG9tYXRpb25SYXRlOiBcImstcmF0ZVwiXG5cdFx0XHR9LCB7XG5cdFx0XHRcdG5hbWU6IFwiZmVlZGJhY2tcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAwLjUsXG5cdFx0XHRcdG1pblZhbHVlOiAwLFxuXHRcdFx0XHRtYXhWYWx1ZTogMC45OTk5LFxuXHRcdFx0XHRhdXRvbWF0aW9uUmF0ZTogXCJrLXJhdGVcIlxuXHRcdFx0fV07XG5cdFx0fVxuXG5cdFx0Z2VuZXJhdGUoaW5wdXQsIGNoYW5uZWwsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IGRlbGF5ZWRTYW1wbGUgPSB0aGlzLmRlbGF5TGluZS5nZXQoY2hhbm5lbCwgcGFyYW1ldGVycy5kZWxheVRpbWUgKiB0aGlzLnNhbXBsZVJhdGUpO1xuXHRcdFx0dGhpcy5kZWxheUxpbmUucHVzaChjaGFubmVsLCBpbnB1dCArIGRlbGF5ZWRTYW1wbGUgKiBwYXJhbWV0ZXJzLmZlZWRiYWNrKTtcblx0XHRcdHJldHVybiBkZWxheWVkU2FtcGxlO1xuXHRcdH1cblx0fVxuYDtcbnJlZ2lzdGVyUHJvY2Vzc29yKHdvcmtsZXROYW1lLCBmZWVkYmFja0NvbWJGaWx0ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb1dvcmtsZXQgfSBmcm9tIFwiLi4vLi4vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXRcIjtcbmltcG9ydCB7IHdvcmtsZXROYW1lIH0gZnJvbSBcIi4vRmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXRcIjtcbi8qKlxuICogQ29tYiBmaWx0ZXJzIGFyZSBiYXNpYyBidWlsZGluZyBibG9ja3MgZm9yIHBoeXNpY2FsIG1vZGVsaW5nLiBSZWFkIG1vcmVcbiAqIGFib3V0IGNvbWIgZmlsdGVycyBvbiBbQ0NSTUEncyB3ZWJzaXRlXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvRmVlZGJhY2tfQ29tYl9GaWx0ZXJzLmh0bWwpLlxuICpcbiAqIFRoaXMgY29tYiBmaWx0ZXIgaXMgaW1wbGVtZW50ZWQgd2l0aCB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBhbGxvd3MgaXQgdG8gaGF2ZSBmZWVkYmFjayBkZWxheXMgbGVzcyB0aGFuIHRoZVxuICogV2ViIEF1ZGlvIHByb2Nlc3NpbmcgYmxvY2sgb2YgMTI4IHNhbXBsZXMuIFRoZXJlIGlzIGEgcG9seWZpbGwgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3QgeWV0IHN1cHBvcnQgdGhlXG4gKiBBdWRpb1dvcmtsZXROb2RlLCBidXQgaXQgd2lsbCBhZGQgc29tZSBsYXRlbmN5IGFuZCBoYXZlIHNsb3dlciBwZXJmb3JtYW5jZSB0aGFuIHRoZSBBdWRpb1dvcmtsZXROb2RlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tDb21iRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZlZWRiYWNrQ29tYkZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICBtaW5WYWx1ZTogMCxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlc29uYW5jZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yZXNvbmFuY2UsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyZXNvbmFuY2VcIiwgXCJkZWxheVRpbWVcIl0pO1xuICAgIH1cbiAgICBfYXVkaW9Xb3JrbGV0TmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHdvcmtsZXROYW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG4gICAgICovXG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMC4xLFxuICAgICAgICAgICAgcmVzb25hbmNlOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBvblJlYWR5KG5vZGUpIHtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCBub2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbnN0IGRlbGF5VGltZSA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJkZWxheVRpbWVcIik7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuc2V0UGFyYW0oZGVsYXlUaW1lKTtcbiAgICAgICAgY29uc3QgZmVlZGJhY2sgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiZmVlZGJhY2tcIik7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2Uuc2V0UGFyYW0oZmVlZGJhY2spO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0NvbWJGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIEEgb25lIHBvbGUgZmlsdGVyIHdpdGggNmRiLXBlci1vY3RhdmUgcm9sbG9mZi4gRWl0aGVyIFwiaGlnaHBhc3NcIiBvciBcImxvd3Bhc3NcIi5cbiAqIE5vdGUgdGhhdCBjaGFuZ2luZyB0aGUgdHlwZSBvciBmcmVxdWVuY3kgbWF5IHJlc3VsdCBpbiBhIGRpc2NvbnRpbnVpdHkgd2hpY2hcbiAqIGNhbiBzb3VuZCBsaWtlIGEgY2xpY2sgb3IgcG9wLlxuICogUmVmZXJlbmNlczpcbiAqICogaHR0cDovL3d3dy5lYXJsZXZlbC5jb20vbWFpbi8yMDEyLzEyLzE1L2Etb25lLXBvbGUtZmlsdGVyL1xuICogKiBodHRwOi8vd3d3LmRzcGd1aWRlLmNvbS9jaDE5LzIuaHRtXG4gKiAqIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRhbGl5LWJvYnJvdi9qcy1yb2Nrcy9ibG9iL21hc3Rlci9zcmMvYXBwL2F1ZGlvL2VmZmVjdHMvb25lLXBvbGUtZmlsdGVycy50c1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgT25lUG9sZUZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPbmVQb2xlRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9uZVBvbGVGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9uZVBvbGVGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gb3B0aW9ucy5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDg4MCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBmaWx0ZXIgYW5kIGRpc3Bvc2UgdGhlIG9sZCBvbmVcbiAgICAgKi9cbiAgICBfY3JlYXRlRmlsdGVyKCkge1xuICAgICAgICBjb25zdCBvbGRGaWx0ZXIgPSB0aGlzLl9maWx0ZXI7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KHRoaXMuX2ZyZXF1ZW5jeSk7XG4gICAgICAgIGNvbnN0IHQgPSAxIC8gKDIgKiBNYXRoLlBJICogZnJlcSk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImxvd3Bhc3NcIikge1xuICAgICAgICAgICAgY29uc3QgYTAgPSAxIC8gKHQgKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBiMSA9IGEwIC0gMTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoW2EwLCAwXSwgWzEsIGIxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBiMSA9IDEgLyAodCAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKSAtIDE7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFsxLCAtMV0sIFsxLCBiMV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fZmlsdGVyLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGlmIChvbGRGaWx0ZXIpIHtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2UgaXQgb24gdGhlIG5leHQgYmxvY2tcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KG9sZEZpbHRlcik7XG4gICAgICAgICAgICAgICAgICAgIG9sZEZpbHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgdGhpcy5ibG9ja1RpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IGZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGZyZXF1ZW5jeShmcSkge1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBmcTtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBPbmVQb2xlIEZpbHRlciB0eXBlLCBlaXRoZXIgXCJoaWdocGFzc1wiIG9yIFwibG93cGFzc1wiXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0KSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0O1xuICAgICAgICB0aGlzLl9jcmVhdGVGaWx0ZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgY29uc3QgZnJlcVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybSA9IE1hdGgucG93KGkgLyBsZW4sIDIpO1xuICAgICAgICAgICAgY29uc3QgZnJlcSA9IG5vcm0gKiAoMjAwMDAgLSAyMCkgKyAyMDtcbiAgICAgICAgICAgIGZyZXFWYWx1ZXNbaV0gPSBmcmVxO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hZ1ZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgY29uc3QgcGhhc2VWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIHRoaXMuX2ZpbHRlci5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxVmFsdWVzLCBtYWdWYWx1ZXMsIHBoYXNlVmFsdWVzKTtcbiAgICAgICAgcmV0dXJuIG1hZ1ZhbHVlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbmVQb2xlRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRmVlZGJhY2tDb21iRmlsdGVyIH0gZnJvbSBcIi4vRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5pbXBvcnQgeyBPbmVQb2xlRmlsdGVyIH0gZnJvbSBcIi4vT25lUG9sZUZpbHRlclwiO1xuLyoqXG4gKiBBIGxvd3Bhc3MgZmVlZGJhY2sgY29tYiBmaWx0ZXIuIEl0IGlzIHNpbWlsYXIgdG9cbiAqIFtbRmVlZGJhY2tDb21iRmlsdGVyXV0sIGJ1dCBpbmNsdWRlcyBhIGxvd3Bhc3MgZmlsdGVyLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTG93cGFzc0NvbWJGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTG93cGFzc0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIiwgXCJkYW1wZW5pbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMb3dwYXNzQ29tYkZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTG93cGFzc0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIiwgXCJkYW1wZW5pbmdcIl0pO1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVyID0gdGhpcy5vdXRwdXQgPSBuZXcgRmVlZGJhY2tDb21iRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICByZXNvbmFuY2U6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9jb21iRmlsdGVyLmRlbGF5VGltZTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSB0aGlzLl9jb21iRmlsdGVyLnJlc29uYW5jZTtcbiAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMuaW5wdXQgPSBuZXcgT25lUG9sZUZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmNvbm5lY3QodGhpcy5fY29tYkZpbHRlcik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkYW1wZW5pbmc6IDMwMDAsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRhbXBlbmluZyBjb250cm9sIG9mIHRoZSBmZWVkYmFja1xuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhmcSkge1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeSA9IGZxO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TG93cGFzc0NvbWJGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgTG93cGFzc0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG4vKipcbiAqIEthcnBsdXMtU3RyaW5nIHN0cmluZyBzeW50aGVzaXMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGx1Y2t5ID0gbmV3IFRvbmUuUGx1Y2tTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzRcIiwgXCIrMC41XCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDM1wiLCBcIisxXCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDMlwiLCBcIisxLjVcIik7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkMxXCIsIFwiKzJcIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgUGx1Y2tTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQbHVja1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsdWNrU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsdWNrU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fbm9pc2UgPSBuZXcgTm9pc2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJwaW5rXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXR0YWNrTm9pc2UgPSBvcHRpb25zLmF0dGFja05vaXNlO1xuICAgICAgICB0aGlzLl9sZmNmID0gbmV3IExvd3Bhc3NDb21iRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRhbXBlbmluZzogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICByZXNvbmFuY2U6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSBvcHRpb25zLnJlc29uYW5jZTtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLl9ub2lzZS5jb25uZWN0KHRoaXMuX2xmY2YpO1xuICAgICAgICB0aGlzLl9sZmNmLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2tOb2lzZTogMSxcbiAgICAgICAgICAgIGRhbXBlbmluZzogNDAwMCxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC43LFxuICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkYW1wZW5pbmcgY29udHJvbC4gaS5lLiB0aGUgbG93cGFzcyBmaWx0ZXIgZnJlcXVlbmN5IG9mIHRoZSBjb21iIGZpbHRlclxuICAgICAqIEBtaW4gMFxuICAgICAqIEBtYXggNzAwMFxuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZmNmLmRhbXBlbmluZztcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhmcSkge1xuICAgICAgICB0aGlzLl9sZmNmLmRhbXBlbmluZyA9IGZxO1xuICAgIH1cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgZGVsYXlBbW91bnQgPSAxIC8gZnJlcTtcbiAgICAgICAgdGhpcy5fbGZjZi5kZWxheVRpbWUuc2V0VmFsdWVBdFRpbWUoZGVsYXlBbW91bnQsIHRpbWUpO1xuICAgICAgICB0aGlzLl9ub2lzZS5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbm9pc2Uuc3RvcCh0aW1lICsgZGVsYXlBbW91bnQgKiB0aGlzLmF0dGFja05vaXNlKTtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2UuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl9sZmNmLnJlc29uYW5jZS5zZXRWYWx1ZUF0VGltZSh0aGlzLnJlc29uYW5jZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSYW1wIGRvd24gdGhlIFtbcmVzb25hbmNlXV0gdG8gMCBvdmVyIHRoZSBkdXJhdGlvbiBvZiB0aGUgcmVsZWFzZSB0aW1lLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2UubGluZWFyUmFtcFRvKDAsIHRoaXMucmVsZWFzZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vaXNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZjZi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsdWNrU3ludGguanMubWFwIiwiaW1wb3J0IHsgTWlkaUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9NaWRpXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyBhc3NlcnQsIHdhcm4gfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBvbHlTeW50aCBoYW5kbGVzIHZvaWNlIGNyZWF0aW9uIGFuZCBhbGxvY2F0aW9uIGZvciBhbnlcbiAqIGluc3RydW1lbnRzIHBhc3NlZCBpbiBhcyB0aGUgc2Vjb25kIHBhcmFtdGVyLiBQb2x5U3ludGggaXNcbiAqIG5vdCBhIHN5bnRoZXNpemVyIGJ5IGl0c2VsZiwgaXQgbWVyZWx5IG1hbmFnZXMgdm9pY2VzIG9mXG4gKiBvbmUgb2YgdGhlIG90aGVyIHR5cGVzIG9mIHN5bnRocywgYWxsb3dpbmcgYW55IG9mIHRoZVxuICogbW9ub3Bob25pYyBzeW50aGVzaXplcnMgdG8gYmUgcG9seXBob25pYy5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBzZXQgdGhlIGF0dHJpYnV0ZXMgYWNyb3NzIGFsbCB0aGUgdm9pY2VzIHVzaW5nICdzZXQnXG4gKiBzeW50aC5zZXQoeyBkZXR1bmU6IC0xMjAwIH0pO1xuICogLy8gcGxheSBhIGNob3JkXG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDNFwiLCBcIkU0XCIsIFwiQTRcIl0sIDEpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBvbHlTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQb2x5U3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2ljZVwiLCBcIm9wdGlvbnNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQb2x5U3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2b2ljZXMgd2hpY2ggYXJlIG5vdCBjdXJyZW50bHkgaW4gdXNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIHZvaWNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGFsbG9jYXRlZCB2b2ljZXMgZm9yIHRoaXMgc3ludGguXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl92b2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBHQyB0aW1lb3V0LiBIZWxkIHNvIHRoYXQgaXQgY291bGQgYmUgY2FuY2VsbGVkIHdoZW4gdGhlIG5vZGUgaXMgZGlzcG9zZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nY1RpbWVvdXQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgbW92aW5nIGF2ZXJhZ2Ugb2YgdGhlIG51bWJlciBvZiBhY3RpdmUgdm9pY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvbHlTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvaWNlXCIsIFwib3B0aW9uc1wiXSk7XG4gICAgICAgIC8vIGNoZWNrIGFnYWluc3QgdGhlIG9sZCBBUEkgKHByZSAxNC4zLjApXG4gICAgICAgIGFzc2VydCghaXNOdW1iZXIob3B0aW9ucy52b2ljZSksIFwiREVQUkVDQVRFRDogVGhlIHBvbHlwaG9ueSBjb3VudCBpcyBubyBsb25nZXIgdGhlIGZpcnN0IGFyZ3VtZW50LlwiKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSBvcHRpb25zLnZvaWNlLmdldERlZmF1bHRzKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdHMsIG9wdGlvbnMub3B0aW9ucyk7XG4gICAgICAgIHRoaXMudm9pY2UgPSBvcHRpb25zLnZvaWNlO1xuICAgICAgICB0aGlzLm1heFBvbHlwaG9ueSA9IG9wdGlvbnMubWF4UG9seXBob255O1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGZpcnN0IHZvaWNlXG4gICAgICAgIHRoaXMuX2R1bW15Vm9pY2UgPSB0aGlzLl9nZXROZXh0QXZhaWxhYmxlVm9pY2UoKTtcbiAgICAgICAgLy8gcmVtb3ZlIGl0IGZyb20gdGhlIHZvaWNlcyBsaXN0XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdm9pY2VzLmluZGV4T2YodGhpcy5fZHVtbXlWb2ljZSk7XG4gICAgICAgIHRoaXMuX3ZvaWNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAvLyBraWNrIG9mZiB0aGUgR0MgaW50ZXJ2YWxcbiAgICAgICAgdGhpcy5fZ2NUaW1lb3V0ID0gdGhpcy5jb250ZXh0LnNldEludGVydmFsKHRoaXMuX2NvbGxlY3RHYXJiYWdlLmJpbmQodGhpcyksIDEpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4UG9seXBob255OiAzMixcbiAgICAgICAgICAgIG9wdGlvbnM6IHt9LFxuICAgICAgICAgICAgdm9pY2U6IFN5bnRoLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBhY3RpdmUgdm9pY2VzLlxuICAgICAqL1xuICAgIGdldCBhY3RpdmVWb2ljZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmVWb2ljZXMubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gdGhlIHNvdXJjZSBpcyBkb25lIG1ha2luZyBzb3VuZCwgc28gdGhhdCBpdCBjYW4gYmVcbiAgICAgKiByZWFkZGVkIHRvIHRoZSBwb29sIG9mIGF2YWlsYWJsZSB2b2ljZXNcbiAgICAgKi9cbiAgICBfbWFrZVZvaWNlQXZhaWxhYmxlKHZvaWNlKSB7XG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5wdXNoKHZvaWNlKTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBtaWRpIG5vdGUgZnJvbSAnYWN0aXZlIHZvaWNlcydcbiAgICAgICAgY29uc3QgYWN0aXZlVm9pY2VJbmRleCA9IHRoaXMuX2FjdGl2ZVZvaWNlcy5maW5kSW5kZXgoKGUpID0+IGUudm9pY2UgPT09IHZvaWNlKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzLnNwbGljZShhY3RpdmVWb2ljZUluZGV4LCAxKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFuIGF2YWlsYWJsZSB2b2ljZSBmcm9tIHRoZSBwb29sIG9mIGF2YWlsYWJsZSB2b2ljZXMuXG4gICAgICogSWYgb25lIGlzIG5vdCBhdmFpbGFibGUgYW5kIHRoZSBtYXhQb2x5cGhvbnkgbGltaXQgaXMgcmVhY2hlZCxcbiAgICAgKiBzdGVhbCBhIHZvaWNlLCBvdGhlcndpc2UgcmV0dXJuIG51bGwuXG4gICAgICovXG4gICAgX2dldE5leHRBdmFpbGFibGVWb2ljZSgpIHtcbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGF2YWlsYWJsZSB2b2ljZXMsIHJldHVybiB0aGUgZmlyc3Qgb25lXG4gICAgICAgIGlmICh0aGlzLl9hdmFpbGFibGVWb2ljZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlVm9pY2VzLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdm9pY2VzLmxlbmd0aCA8IHRoaXMubWF4UG9seXBob255KSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgdGhlcmUgaXMgc3RpbGwgbW9yZSBtYXhQb2x5cGhvbnksIG1ha2UgYSBuZXcgdm9pY2VcbiAgICAgICAgICAgIGNvbnN0IHZvaWNlID0gbmV3IHRoaXMudm9pY2UoT2JqZWN0LmFzc2lnbih0aGlzLm9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgb25zaWxlbmNlOiB0aGlzLl9tYWtlVm9pY2VBdmFpbGFibGUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHZvaWNlLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fdm9pY2VzLnB1c2godm9pY2UpO1xuICAgICAgICAgICAgcmV0dXJuIHZvaWNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgd2FybihcIk1heCBwb2x5cGhvbnkgZXhjZWVkZWQuIE5vdGUgZHJvcHBlZC5cIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogT2NjYXNpb25hbGx5IGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgYWxsb2NhdGVkIHZvaWNlcyB3aGljaCBjYW4gYmUgY2xlYW5lZCB1cC5cbiAgICAgKi9cbiAgICBfY29sbGVjdEdhcmJhZ2UoKSB7XG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgPSBNYXRoLm1heCh0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzICogMC45NSwgdGhpcy5hY3RpdmVWb2ljZXMpO1xuICAgICAgICBpZiAodGhpcy5fYXZhaWxhYmxlVm9pY2VzLmxlbmd0aCAmJiB0aGlzLl92b2ljZXMubGVuZ3RoID4gTWF0aC5jZWlsKHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgKyAxKSkge1xuICAgICAgICAgICAgLy8gdGFrZSBvZmYgYW4gYXZhaWxhYmxlIG5vdGVcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0QXZhaWwgPSB0aGlzLl9hdmFpbGFibGVWb2ljZXMuc2hpZnQoKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdm9pY2VzLmluZGV4T2YoZmlyc3RBdmFpbCk7XG4gICAgICAgICAgICB0aGlzLl92b2ljZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGZpcnN0QXZhaWwuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB3aGljaCB0cmlnZ2VycyB0aGUgYXR0YWNrXG4gICAgICovXG4gICAgX3RyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpTm90ZSA9IG5ldyBNaWRpQ2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIGNvbnN0IHZvaWNlID0gdGhpcy5fZ2V0TmV4dEF2YWlsYWJsZVZvaWNlKCk7XG4gICAgICAgICAgICBpZiAodm9pY2UpIHtcbiAgICAgICAgICAgICAgICB2b2ljZS50cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIG1pZGk6IG1pZGlOb3RlLCB2b2ljZSwgcmVsZWFzZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB3aGljaCB0cmlnZ2VycyB0aGUgcmVsZWFzZVxuICAgICAqL1xuICAgIF90cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaU5vdGUgPSBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2FjdGl2ZVZvaWNlcy5maW5kKCh7IG1pZGksIHJlbGVhc2VkIH0pID0+IG1pZGkgPT09IG1pZGlOb3RlICYmICFyZWxlYXNlZCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIHJlbGVhc2Ugb24gdGhhdCBub3RlXG4gICAgICAgICAgICAgICAgZXZlbnQudm9pY2UudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgICAgICAgICAgLy8gbWFyayBpdCBhcyByZWxlYXNlZFxuICAgICAgICAgICAgICAgIGV2ZW50LnJlbGVhc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIG5vdGUsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgdGhlIGF0dGFjay9yZWxlYXNlIGV2ZW50cy4gSWYgdGhlIHRpbWUgaXMgaW4gdGhlIGZ1dHVyZSwgdGhlbiBpdCBzaG91bGQgc2V0IGEgdGltZW91dFxuICAgICAqIHRvIHdhaXQgZm9yIGp1c3QtaW4tdGltZSBzY2hlZHVsaW5nXG4gICAgICovXG4gICAgX3NjaGVkdWxlRXZlbnQodHlwZSwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5kaXNwb3NlZCwgXCJTeW50aCB3YXMgYWxyZWFkeSBkaXNwb3NlZFwiKTtcbiAgICAgICAgLy8gaWYgdGhlIG5vdGVzIGFyZSBncmVhdGVyIHRoYW4gdGhpcyBhbW91bnQgb2YgdGltZSBpbiB0aGUgZnV0dXJlLCB0aGV5IHNob3VsZCBiZSBzY2hlZHVsZWQgd2l0aCBzZXRUaW1lb3V0XG4gICAgICAgIGlmICh0aW1lIDw9IHRoaXMubm93KCkpIHtcbiAgICAgICAgICAgIC8vIGRvIGl0IGltbWVkaWF0ZWx5XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gXCJhdHRhY2tcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNjaGVkdWxlIGl0IHRvIHN0YXJ0IGluIHRoZSBmdXR1cmVcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KHR5cGUsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICB9LCB0aW1lIC0gdGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSBzdGFydCB0aW1lIG9mIHRoZSBub3RlLlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aChUb25lLkZNU3ludGgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIGEgY2hvcmQgaW1tZWRpYXRlbHkgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soW1wiQWIzXCIsIFwiQzRcIiwgXCJGNVwiXSwgVG9uZS5ub3coKSwgMC4yKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG4gICAgICAgICAgICBub3RlcyA9IFtub3Rlc107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlRXZlbnQoXCJhdHRhY2tcIiwgbm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgbm90ZS4gVW5saWtlIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMsXG4gICAgICogYSBub3RlIChvciBhcnJheSBvZiBub3RlcykgbmVlZHMgdG8gYmUgcGFzc2VkIGluIGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdGhlIHJlbGVhc2Ugd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoVG9uZS5BTVN5bnRoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrKFtcIkFiM1wiLCBcIkM0XCIsIFwiRjVcIl0pO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIGdpdmVuIG5vdGVzLlxuICAgICAqIHBvbHkudHJpZ2dlclJlbGVhc2UoW1wiQWIzXCIsIFwiQzRcIl0sIFwiKzFcIik7XG4gICAgICogcG9seS50cmlnZ2VyUmVsZWFzZShcIkY1XCIsIFwiKzNcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KFwicmVsZWFzZVwiLCBub3RlcywgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSBhZnRlciB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSAgRnJlcXVlbmN5IG9yIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gdGhlIGR1cmF0aW9uIG9mIHRoZSBub3RlXG4gICAgICogQHBhcmFtICB0aW1lICBpZiBubyB0aW1lIGlzIGdpdmVuLCBkZWZhdWx0cyB0byBub3dcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrICgwLTEpXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKFRvbmUuQU1TeW50aCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIGNhbiBwYXNzIGluIGFuIGFycmF5IG9mIGR1cmF0aW9ucyBhcyB3ZWxsXG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJFYjNcIiwgXCJHNFwiLCBcIkJiNFwiLCBcIkQ1XCJdLCBbNCwgMywgMiwgMV0pO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGVzLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmIChpc0FycmF5KGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkobm90ZXMpLCBcIklmIHRoZSBkdXJhdGlvbiBpcyBhbiBhcnJheSwgdGhlIG5vdGVzIG11c3QgYWxzbyBiZSBhbiBhcnJheVwiKTtcbiAgICAgICAgICAgIG5vdGVzID0gbm90ZXM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vdGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGR1cmF0aW9uW01hdGgubWluKGksIGR1cmF0aW9uLmxlbmd0aCAtIDEpXTtcbiAgICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvblNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyhkKTtcbiAgICAgICAgICAgICAgICBhc3NlcnQoZHVyYXRpb25TZWNvbmRzID4gMCwgXCJUaGUgZHVyYXRpb24gbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzW2ldLCBjb21wdXRlZFRpbWUgKyBkdXJhdGlvblNlY29uZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAgICAgYXNzZXJ0KGR1cmF0aW9uU2Vjb25kcyA+IDAsIFwiVGhlIGR1cmF0aW9uIG11c3QgYmUgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzLCBjb21wdXRlZFRpbWUgKyBkdXJhdGlvblNlY29uZHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgYSBtZW1iZXIvYXR0cmlidXRlIG9mIHRoZSB2b2ljZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc2V0IGFsbCBvZiB0aGUgdm9pY2VzIHVzaW5nIGFuIG9wdGlvbnMgb2JqZWN0IGZvciB0aGUgc3ludGggdHlwZVxuICAgICAqIHBvbHkuc2V0KHtcbiAgICAgKiBcdGVudmVsb3BlOiB7XG4gICAgICogXHRcdGF0dGFjazogMC4yNVxuICAgICAqIFx0fVxuICAgICAqIH0pO1xuICAgICAqIHBvbHkudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJCYjNcIiwgMC4yKTtcbiAgICAgKi9cbiAgICBzZXQob3B0aW9ucykge1xuICAgICAgICAvLyByZW1vdmUgb3B0aW9ucyB3aGljaCBhcmUgY29udHJvbGxlZCBieSB0aGUgUG9seVN5bnRoXG4gICAgICAgIGNvbnN0IHNhbml0aXplZE9wdGlvbnMgPSBvbWl0RnJvbU9iamVjdChvcHRpb25zLCBbXCJvbnNpbGVuY2VcIiwgXCJjb250ZXh0XCJdKTtcbiAgICAgICAgLy8gc3RvcmUgYWxsIG9mIHRoZSBvcHRpb25zXG4gICAgICAgIHRoaXMub3B0aW9ucyA9IGRlZXBNZXJnZSh0aGlzLm9wdGlvbnMsIHNhbml0aXplZE9wdGlvbnMpO1xuICAgICAgICB0aGlzLl92b2ljZXMuZm9yRWFjaCh2b2ljZSA9PiB2b2ljZS5zZXQoc2FuaXRpemVkT3B0aW9ucykpO1xuICAgICAgICB0aGlzLl9kdW1teVZvaWNlLnNldChzYW5pdGl6ZWRPcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2R1bW15Vm9pY2UuZ2V0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiBhbGwgdGhlIGN1cnJlbnRseSBhY3RpdmUgdm9pY2VzIGltbWVkaWF0ZWx5LlxuICAgICAqIFVzZWZ1bCBmb3Igc2lsZW5jaW5nIHRoZSBzeW50aC5cbiAgICAgKi9cbiAgICByZWxlYXNlQWxsKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcy5mb3JFYWNoKCh7IHZvaWNlIH0pID0+IHtcbiAgICAgICAgICAgIHZvaWNlLnRyaWdnZXJSZWxlYXNlKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kdW1teVZvaWNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9pY2VzLmZvckVhY2godiA9PiB2LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcyA9IFtdO1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFySW50ZXJ2YWwodGhpcy5fZ2NUaW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UG9seVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmltcG9ydCB7IGZ0b21mLCBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8gfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNOb3RlLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4uL2luc3RydW1lbnQvSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBhc3MgaW4gYW4gb2JqZWN0IHdoaWNoIG1hcHMgdGhlIG5vdGUncyBwaXRjaCBvciBtaWRpIHZhbHVlIHRvIHRoZSB1cmwsXG4gKiB0aGVuIHlvdSBjYW4gdHJpZ2dlciB0aGUgYXR0YWNrIGFuZCByZWxlYXNlIG9mIHRoYXQgbm90ZSBsaWtlIG90aGVyIGluc3RydW1lbnRzLlxuICogQnkgYXV0b21hdGljYWxseSByZXBpdGNoaW5nIHRoZSBzYW1wbGVzLCBpdCBpcyBwb3NzaWJsZSB0byBwbGF5IHBpdGNoZXMgd2hpY2hcbiAqIHdlcmUgbm90IGV4cGxpY2l0bHkgaW5jbHVkZWQgd2hpY2ggY2FuIHNhdmUgbG9hZGluZyB0aW1lLlxuICpcbiAqIEZvciBzYW1wbGUgb3IgYnVmZmVyIHBsYXliYWNrIHdoZXJlIHJlcGl0Y2hpbmcgaXMgbm90IG5lY2Vzc2FyeSxcbiAqIHVzZSBbW1BsYXllcl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNhbXBsZXIgPSBuZXcgVG9uZS5TYW1wbGVyKHtcbiAqIFx0dXJsczoge1xuICogXHRcdEExOiBcIkExLm1wM1wiLFxuICogXHRcdEEyOiBcIkEyLm1wM1wiLFxuICogXHR9LFxuICogXHRiYXNlVXJsOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9cIixcbiAqIFx0b25sb2FkOiAoKSA9PiB7XG4gKiBcdFx0c2FtcGxlci50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDMVwiLCBcIkUxXCIsIFwiRzFcIiwgXCJCMVwiXSwgMC41KTtcbiAqIFx0fVxuICogfSkudG9EZXN0aW5hdGlvbigpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNhbXBsZXIgZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2FtcGxlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIikpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNhbXBsZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvYmplY3Qgb2YgYWxsIGN1cnJlbnRseSBwbGF5aW5nIEJ1ZmZlclNvdXJjZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTYW1wbGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgY29uc3QgdXJsTWFwID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMudXJscykuZm9yRWFjaCgobm90ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm90ZU51bWJlciA9IHBhcnNlSW50KG5vdGUsIDEwKTtcbiAgICAgICAgICAgIGFzc2VydChpc05vdGUobm90ZSlcbiAgICAgICAgICAgICAgICB8fCAoaXNOdW1iZXIobm90ZU51bWJlcikgJiYgaXNGaW5pdGUobm90ZU51bWJlcikpLCBgdXJsIGtleSBpcyBuZWl0aGVyIGEgbm90ZSBvciBtaWRpIHBpdGNoOiAke25vdGV9YCk7XG4gICAgICAgICAgICBpZiAoaXNOb3RlKG5vdGUpKSB7XG4gICAgICAgICAgICAgICAgLy8gY29udmVydCB0aGUgbm90ZSBuYW1lIHRvIE1JRElcbiAgICAgICAgICAgICAgICBjb25zdCBtaWQgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgICAgICB1cmxNYXBbbWlkXSA9IG9wdGlvbnMudXJsc1tub3RlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzTnVtYmVyKG5vdGVOdW1iZXIpICYmIGlzRmluaXRlKG5vdGVOdW1iZXIpKSB7XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG4gICAgICAgICAgICAgICAgdXJsTWFwW25vdGVOdW1iZXJdID0gb3B0aW9ucy51cmxzW25vdGVOdW1iZXJdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBUb25lQXVkaW9CdWZmZXJzKHtcbiAgICAgICAgICAgIHVybHM6IHVybE1hcCxcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG9wdGlvbnMuYXR0YWNrO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBvcHRpb25zLnJlbGVhc2U7XG4gICAgICAgIHRoaXMuY3VydmUgPSBvcHRpb25zLmN1cnZlO1xuICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrIGlmIGl0J3MgYWxyZWFkeSBsb2FkZWRcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMubG9hZGVkKSB7XG4gICAgICAgICAgICAvLyBpbnZva2Ugb25sb2FkIGRlZmVycmVkXG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKG9wdGlvbnMub25sb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLFxuICAgICAgICAgICAgYmFzZVVybDogXCJcIixcbiAgICAgICAgICAgIGN1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4xLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGluIHN0ZXBzIGJldHdlZW4gdGhlIGdpdmVuIG1pZGkgbm90ZSBhdCB0aGUgY2xvc2V0cyBzYW1wbGUuXG4gICAgICovXG4gICAgX2ZpbmRDbG9zZXN0KG1pZGkpIHtcbiAgICAgICAgLy8gc2VhcmNoZXMgd2l0aGluIDggb2N0YXZlcyBvZiB0aGUgZ2l2ZW4gbWlkaSBub3RlXG4gICAgICAgIGNvbnN0IE1BWF9JTlRFUlZBTCA9IDk2O1xuICAgICAgICBsZXQgaW50ZXJ2YWwgPSAwO1xuICAgICAgICB3aGlsZSAoaW50ZXJ2YWwgPCBNQVhfSU5URVJWQUwpIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGFib3ZlIGFuZCBiZWxvd1xuICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMuaGFzKG1pZGkgKyBpbnRlcnZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gLWludGVydmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fYnVmZmVycy5oYXMobWlkaSAtIGludGVydmFsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcnZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGludGVydmFsKys7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBhdmFpbGFibGUgYnVmZmVycyBmb3Igbm90ZTogJHttaWRpfWApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byBwbGF5LCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgIFdoZW4gdG8gcGxheSB0aGUgbm90ZVxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRvIHBsYXkgdGhlIHNhbXBsZSBiYWNrLlxuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpRmxvYXQgPSBmdG9tZihuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b0ZyZXF1ZW5jeSgpKTtcbiAgICAgICAgICAgIGNvbnN0IG1pZGkgPSBNYXRoLnJvdW5kKG1pZGlGbG9hdCk7XG4gICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBtaWRpRmxvYXQgLSBtaWRpO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgY2xvc2VzdCBub3RlIHBpdGNoXG4gICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gdGhpcy5fZmluZENsb3Nlc3QobWlkaSk7XG4gICAgICAgICAgICBjb25zdCBjbG9zZXN0Tm90ZSA9IG1pZGkgLSBkaWZmZXJlbmNlO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fYnVmZmVycy5nZXQoY2xvc2VzdE5vdGUpO1xuICAgICAgICAgICAgY29uc3QgcGxheWJhY2tSYXRlID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGRpZmZlcmVuY2UgKyByZW1haW5kZXIpO1xuICAgICAgICAgICAgLy8gcGxheSB0aGF0IG5vdGVcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgICAgICB1cmw6IGJ1ZmZlcixcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgY3VydmU6IHRoaXMuY3VydmUsXG4gICAgICAgICAgICAgICAgZmFkZUluOiB0aGlzLmF0dGFjayxcbiAgICAgICAgICAgICAgICBmYWRlT3V0OiB0aGlzLnJlbGVhc2UsXG4gICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQodGltZSwgMCwgYnVmZmVyLmR1cmF0aW9uIC8gcGxheWJhY2tSYXRlLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGFjdGl2ZSBzb3VyY2VzXG4gICAgICAgICAgICBpZiAoIWlzQXJyYXkodGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zZXQobWlkaSwgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG4gICAgICAgICAgICBzb3VyY2Uub25lbmRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcyAmJiB0aGlzLl9hY3RpdmVTb3VyY2VzLmhhcyhtaWRpKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc291cmNlcy5pbmRleE9mKHNvdXJjZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcmVsZWFzZSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBcdFdoZW4gdG8gcmVsZWFzZSB0aGUgbm90ZS5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIG5vdGVzLCB0aW1lKTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBub3RlXG4gICAgICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcy5oYXMobWlkaSkgJiYgdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlcyA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpO1xuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zZXQobWlkaSwgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2UgYWxsIGN1cnJlbnRseSBhY3RpdmUgbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBcdFdoZW4gdG8gcmVsZWFzZSB0aGUgbm90ZXMuXG4gICAgICovXG4gICAgcmVsZWFzZUFsbCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlcyA9PiB7XG4gICAgICAgICAgICB3aGlsZSAoc291cmNlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgc291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGF0dGFjayBwaGFzZSwgdGhlbiBhZnRlciB0aGUgZHVyYXRpb24sIGludm9rZSB0aGUgcmVsZWFzZS5cbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byBwbGF5IGFuZCByZWxlYXNlLCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIFRoZSB0aW1lIHRoZSBub3RlIHNob3VsZCBiZSBoZWxkXG4gICAgICogQHBhcmFtICB0aW1lICAgICBXaGVuIHRvIHN0YXJ0IHRoZSBhdHRhY2tcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrXG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZXMsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmIChpc0FycmF5KGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkobm90ZXMpLCBcIm5vdGVzIG11c3QgYmUgYW4gYXJyYXkgd2hlbiBkdXJhdGlvbiBpcyBhcnJheVwiKTtcbiAgICAgICAgICAgIG5vdGVzLmZvckVhY2goKG5vdGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGR1cmF0aW9uW01hdGgubWluKGluZGV4LCBkdXJhdGlvbi5sZW5ndGggLSAxKV07XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3RlLCBjb21wdXRlZFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZXMsIGNvbXB1dGVkVGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIG5vdGUgdG8gdGhlIHNhbXBsZXIuXG4gICAgICogQHBhcmFtICBub3RlICAgICAgVGhlIGJ1ZmZlcidzIHBpdGNoLlxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZmVyLCBvciBhIGJ1ZmZlciB3aGljaCB3aWxsIGJlIGFkZGVkIHdpdGggdGhlIGdpdmVuIG5hbWUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGFkZChub3RlLCB1cmwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydChpc05vdGUobm90ZSkgfHwgaXNGaW5pdGUobm90ZSksIGBub3RlIG11c3QgYmUgYSBwaXRjaCBvciBtaWRpOiAke25vdGV9YCk7XG4gICAgICAgIGlmIChpc05vdGUobm90ZSkpIHtcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIG5vdGUgbmFtZSB0byBNSURJXG4gICAgICAgICAgICBjb25zdCBtaWQgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG1pZCwgdXJsLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgaXQncyBudW1iZXJzIGFzc3VtZSBpdCdzIG1pZGlcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5vdGUsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmxvYWRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlcyA9PiB7XG4gICAgICAgICAgICBzb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFNhbXBsZXIucHJvdG90eXBlLCBcImF0dGFja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBTYW1wbGVyLnByb3RvdHlwZSwgXCJyZWxlYXNlXCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TYW1wbGVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0FNU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0R1b1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GTVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NZXRhbFN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NZW1icmFuZVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Nb25vU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL05vaXNlU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BsdWNrU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BvbHlTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2FtcGxlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3ludGhcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCBcIi4uL2NvcmUvY2xvY2svVHJhbnNwb3J0XCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0Jvb2xlYW4sIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVG9uZUV2ZW50IGFic3RyYWN0cyBhd2F5IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUgYW5kIHByb3ZpZGVzIGEgc2NoZWR1bGFibGVcbiAqIGNhbGxiYWNrIGZvciBhIHNpbmdsZSBvciByZXBlYXRhYmxlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgY2hvcmRFdmVudCA9IG5ldyBUb25lLlRvbmVFdmVudCgoKHRpbWUsIGNob3JkKSA9PiB7XG4gKiBcdC8vIHRoZSBjaG9yZCBhcyB3ZWxsIGFzIHRoZSBleGFjdCB0aW1lIG9mIHRoZSBldmVudFxuICogXHQvLyBhcmUgcGFzc2VkIGluIGFzIGFyZ3VtZW50cyB0byB0aGUgY2FsbGJhY2sgZnVuY3Rpb25cbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoY2hvcmQsIDAuNSwgdGltZSk7XG4gKiB9KSwgW1wiRDRcIiwgXCJFNFwiLCBcIkY0XCJdKTtcbiAqIC8vIHN0YXJ0IHRoZSBjaG9yZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0cmFuc3BvcnQgdGltZWxpbmVcbiAqIGNob3JkRXZlbnQuc3RhcnQoKTtcbiAqIC8vIGxvb3AgaXQgZXZlcnkgbWVhc3VyZSBmb3IgOCBtZWFzdXJlc1xuICogY2hvcmRFdmVudC5sb29wID0gODtcbiAqIGNob3JkRXZlbnQubG9vcEVuZCA9IFwiMW1cIjtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgVG9uZUV2ZW50IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVFdmVudFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVHJhY2tzIHRoZSBzY2hlZHVsZWQgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgZGVsYXkgdGltZSBmcm9tIHdoZW4gdGhlIGV2ZW50IGlzIHNjaGVkdWxlZCB0byBzdGFydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLnZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKG9wdGlvbnMubG9vcFN0YXJ0KTtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhvcHRpb25zLmxvb3BFbmQpO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBvcHRpb25zLnByb2JhYmlsaXR5O1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IG9wdGlvbnMuaHVtYW5pemU7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX3N0YXRlLmluY3JlYXNpbmcgPSB0cnVlO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgZXZlbnRzIGZvciB0aGUgZmlyc3QgdGltZVxuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgaHVtYW5pemU6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiBcIjFtXCIsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiAxLFxuICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNjaGVkdWxlIGFsbCBvZiB0aGUgZXZlbnRzIGFsb25nIHRoZSB0aW1lbGluZVxuICAgICAqIHdpdGggdGhlIHVwZGF0ZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSBhZnRlciBPbmx5IHJlc2NoZWR1bGVzIGV2ZW50cyBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBfcmVzY2hlZHVsZUV2ZW50cyhhZnRlciA9IC0xKSB7XG4gICAgICAgIC8vIGlmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCBzY2hlZHVsZXMgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEZyb20oYWZ0ZXIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbjtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuaWQgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoZXZlbnQuaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydFRpY2sgPSBldmVudC50aW1lICsgTWF0aC5yb3VuZCh0aGlzLnN0YXJ0T2Zmc2V0IC8gdGhpcy5fcGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbG9vcCA9PT0gdHJ1ZSB8fCBpc051bWJlcih0aGlzLl9sb29wKSAmJiB0aGlzLl9sb29wID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IEluZmluaXR5O1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOdW1iZXIodGhpcy5fbG9vcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gKHRoaXMuX2xvb3ApICogdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QWZ0ZXIoc3RhcnRUaWNrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBNYXRoLm1pbihkdXJhdGlvbiwgbmV4dEV2ZW50LnRpbWUgLSBzdGFydFRpY2spO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNjaGVkdWxlIGEgc3RvcCBzaW5jZSBpdCdzIGZpbml0ZSBkdXJhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHN0YXJ0VGljayArIGR1cmF0aW9uICsgMSwgeyBpZDogLTEgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9nZXRMb29wRHVyYXRpb24oKSk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aGlzLl90aWNrLmJpbmQodGhpcyksIGludGVydmFsLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGljayksIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSh0aGlzLl90aWNrLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaWNrKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIG5vdGUsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXJ0IGZyb20gdGhlIHNjaGVkdWxlZCBzdGFydCB0aW1lLlxuICAgICAqL1xuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gb2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvYmFiaWxpdHkgb2YgdGhlIG5vdGVzIGJlaW5nIHRyaWdnZXJlZC5cbiAgICAgKi9cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBzZXQgdG8gdHJ1ZSwgd2lsbCBhcHBseSBzbWFsbCByYW5kb20gdmFyaWF0aW9uXG4gICAgICogdG8gdGhlIGNhbGxiYWNrIHRpbWUuIElmIHRoZSB2YWx1ZSBpcyBnaXZlbiBhcyBhIHRpbWUsIGl0IHdpbGwgcmFuZG9taXplXG4gICAgICogYnkgdGhhdCBhbW91bnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBldmVudCA9IG5ldyBUb25lLlRvbmVFdmVudCgpO1xuICAgICAqIGV2ZW50Lmh1bWFuaXplID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIG5vdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRoZSBldmVudCBzaG91bGQgc3RhcnQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh7XG4gICAgICAgICAgICAgICAgaWQ6IC0xLFxuICAgICAgICAgICAgICAgIHN0YXRlOiBcInN0YXJ0ZWRcIixcbiAgICAgICAgICAgICAgICB0aW1lOiB0aWNrcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cyh0aWNrcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIEV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0aGUgZXZlbnQgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsKHRpbWUpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aWNrcywgeyBpZDogLTEgfSk7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QmVmb3JlKHRpY2tzKTtcbiAgICAgICAgICAgIGxldCByZXNjaGVkdWxUaW1lID0gdGlja3M7XG4gICAgICAgICAgICBpZiAocHJldmlvdXNFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc2NoZWR1bFRpbWUgPSBwcmV2aW91c0V2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKHJlc2NoZWR1bFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBhZnRlciB3aGljaCBldmVudHMgd2lsbCBiZSBjYW5jZWwuXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IGRlZmF1bHRBcmcodGltZSwgLUluZmluaXR5KTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hGcm9tKHRpY2tzLCBldmVudCA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlci4gQWxzb1xuICAgICAqIGNoZWNrcyBpZiB0aGUgRXZlbnQgaXMgZG9uZSBwbGF5aW5nXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBvZiB0aGUgZXZlbnQgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoIXRoaXMubXV0ZSAmJiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9iYWJpbGl0eSA8IDEgJiYgTWF0aC5yYW5kb20oKSA+IHRoaXMucHJvYmFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5odW1hbml6ZSkge1xuICAgICAgICAgICAgICAgIGxldCB2YXJpYXRpb24gPSAwLjAyO1xuICAgICAgICAgICAgICAgIGlmICghaXNCb29sZWFuKHRoaXMuaHVtYW5pemUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuaHVtYW5pemUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aW1lICs9IChNYXRoLnJhbmRvbSgpICogMiAtIDEpICogdmFyaWF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGR1cmF0aW9uIG9mIHRoZSBsb29wLlxuICAgICAqL1xuICAgIF9nZXRMb29wRHVyYXRpb24oKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKCh0aGlzLl9sb29wRW5kIC0gdGhpcy5fbG9vcFN0YXJ0KSAvIHRoaXMuX3BsYXliYWNrUmF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBub3RlIHNob3VsZCBsb29wIG9yIG5vdFxuICAgICAqIGJldHdlZW4gVG9uZUV2ZW50Lmxvb3BTdGFydCBhbmRcbiAgICAgKiBUb25lRXZlbnQubG9vcEVuZC4gSWYgc2V0IHRvIHRydWUsXG4gICAgICogdGhlIGV2ZW50IHdpbGwgbG9vcCBpbmRlZmluaXRlbHksXG4gICAgICogaWYgc2V0IHRvIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAxXG4gICAgICogaXQgd2lsbCBwbGF5IGEgc3BlY2lmaWMgbnVtYmVyIG9mXG4gICAgICogdGltZXMsIGlmIHNldCB0byBmYWxzZSwgMCBvciAxLCB0aGVcbiAgICAgKiBwYXJ0IHdpbGwgb25seSBwbGF5IG9uY2UuXG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub3RlLiBEZWZhdWx0cyB0byAxLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm90ZSA9IG5ldyBUb25lLlRvbmVFdmVudCgpO1xuICAgICAqIG5vdGUubG9vcCA9IHRydWU7XG4gICAgICogLy8gcmVwZWF0IHRoZSBub3RlIHR3aWNlIGFzIGZhc3RcbiAgICAgKiBub3RlLnBsYXliYWNrUmF0ZSA9IDI7XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3BFbmQgcG9pbnQgaXMgdGhlIHRpbWUgdGhlIGV2ZW50IHdpbGwgbG9vcFxuICAgICAqIGlmIFRvbmVFdmVudC5sb29wIGlzIHRydWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BFbmQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MobG9vcEVuZCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgd2hlbiB0aGUgbG9vcCBzaG91bGQgc3RhcnQuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcFN0YXJ0KS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKGxvb3BTdGFydCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgaW50ZXJ2YWwuXG4gICAgICogUmV0dXJucyAwIGlmIHRoZSBldmVudCBpcyBub3Qgc3RhcnRlZCB5ZXQgb3JcbiAgICAgKiBpdCBpcyBub3Qgc2V0IHRvIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzO1xuICAgICAgICAgICAgY29uc3QgbGFzdEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHRpY2tzKTtcbiAgICAgICAgICAgIGlmIChsYXN0RXZlbnQgIT09IG51bGwgJiYgbGFzdEV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvb3BEdXJhdGlvbiA9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gKHRpY2tzIC0gbGFzdEV2ZW50LnRpbWUpICUgbG9vcER1cmF0aW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9ncmVzcyAvIGxvb3BEdXJhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNhbmNlbCgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVFdmVudC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBMb29wIGNyZWF0ZXMgYSBsb29wZWQgY2FsbGJhY2sgYXQgdGhlXG4gKiBzcGVjaWZpZWQgaW50ZXJ2YWwuIFRoZSBjYWxsYmFjayBjYW4gYmVcbiAqIHN0YXJ0ZWQsIHN0b3BwZWQgYW5kIHNjaGVkdWxlZCBhbG9uZ1xuICogdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGxvb3AgPSBuZXcgVG9uZS5Mb29wKCh0aW1lKSA9PiB7XG4gKiBcdC8vIHRyaWdnZXJlZCBldmVyeSBlaWdodGggbm90ZS5cbiAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gKiB9LCBcIjhuXCIpLnN0YXJ0KDApO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgTG9vcCBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKExvb3AuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImludGVydmFsXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTG9vcFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTG9vcC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiaW50ZXJ2YWxcIl0pO1xuICAgICAgICB0aGlzLl9ldmVudCA9IG5ldyBUb25lRXZlbnQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBsb29wRW5kOiBvcHRpb25zLmludGVydmFsLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiBvcHRpb25zLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiBvcHRpb25zLnByb2JhYmlsaXR5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgLy8gc2V0IHRoZSBpdGVyYXRpb25zXG4gICAgICAgIHRoaXMuaXRlcmF0aW9ucyA9IG9wdGlvbnMuaXRlcmF0aW9ucztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaW50ZXJ2YWw6IFwiNG5cIixcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgaXRlcmF0aW9uczogSW5maW5pdHksXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogMSxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgaHVtYW5pemU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgbG9vcCBhdCB0aGUgc3BlY2lmaWVkIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdGFydCB0aGUgTG9vcC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbG9vcCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgTG9vcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBhbGwgc2NoZWR1bGVkIGV2ZW50cyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIGFmdGVyIHdoaWNoIGV2ZW50cyB3aWxsIGJlIGNhbmNlbC5cbiAgICAgKi9cbiAgICBjYW5jZWwodGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5jYW5jZWwodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgbm90ZXMgc2hvdWxkIGJlIGNhbGxlZFxuICAgICAqIEBwYXJhbSB0aW1lICBUaGUgdGltZSB0aGUgZXZlbnQgb2NjdXJzXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3RhdGUgb2YgdGhlIExvb3AsIGVpdGhlciBzdGFydGVkIG9yIHN0b3BwZWQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9ncmVzcyBvZiB0aGUgbG9vcCBhcyBhIHZhbHVlIGJldHdlZW4gMC0xLiAwLCB3aGVuIHRoZSBsb29wIGlzIHN0b3BwZWQgb3IgZG9uZSBpdGVyYXRpbmcuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvZ3Jlc3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBjYWxsYmFja3MuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsb29wID0gbmV3IFRvbmUuTG9vcCgpO1xuICAgICAqIGxvb3AuaW50ZXJ2YWwgPSBcIjhuXCI7IC8vIGxvb3AgZXZlcnkgOG5cbiAgICAgKi9cbiAgICBnZXQgaW50ZXJ2YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgaW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQubG9vcEVuZCA9IGludGVydmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbG9vcC4gVGhlIG5vcm1hbCBwbGF5YmFjayByYXRlIGlzIDEgKG5vIGNoYW5nZSkuXG4gICAgICogQSBgcGxheWJhY2tSYXRlYCBvZiAyIHdvdWxkIGJlIHR3aWNlIGFzIGZhc3QuXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnBsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnBsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJhbmRvbSB2YXJpYXRpb24gKy8tMC4wMXMgdG8gdGhlIHNjaGVkdWxlZCB0aW1lLlxuICAgICAqIE9yIGdpdmUgaXQgYSB0aW1lIHZhbHVlIHdoaWNoIGl0IHdpbGwgcmFuZG9taXplIGJ5LlxuICAgICAqL1xuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmh1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50Lmh1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvYmFibHkgb2YgdGhlIGNhbGxiYWNrIGJlaW5nIGludm9rZWQuXG4gICAgICovXG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnByb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0aW5nIHRoZSBMb29wIG1lYW5zIHRoYXQgbm8gY2FsbGJhY2tzIGFyZSBpbnZva2VkLlxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpdGVyYXRpb25zIG9mIHRoZSBsb29wLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgSW5maW5pdHlgIChsb29wIGZvcmV2ZXIpLlxuICAgICAqL1xuICAgIGdldCBpdGVyYXRpb25zKCkge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnQubG9vcCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmxvb3A7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGl0ZXJhdGlvbnMoaXRlcnMpIHtcbiAgICAgICAgaWYgKGl0ZXJzID09PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnQubG9vcCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudC5sb29wID0gaXRlcnM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxvb3AuanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1VuZGVmIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLyoqXG4gKiBQYXJ0IGlzIGEgY29sbGVjdGlvbiBUb25lRXZlbnRzIHdoaWNoIGNhbiBiZSBzdGFydGVkL3N0b3BwZWQgYW5kIGxvb3BlZCBhcyBhIHNpbmdsZSB1bml0LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdC8vIHRoZSBub3RlcyBnaXZlbiBhcyB0aGUgc2Vjb25kIGVsZW1lbnQgaW4gdGhlIGFycmF5XG4gKiBcdC8vIHdpbGwgYmUgcGFzc2VkIGluIGFzIHRoZSBzZWNvbmQgYXJndW1lbnRcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgXCI4blwiLCB0aW1lKTtcbiAqIH0pLCBbWzAsIFwiQzJcIl0sIFtcIjA6MlwiLCBcIkMzXCJdLCBbXCIwOjM6MlwiLCBcIkcyXCJdXSk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyB1c2UgYW4gYXJyYXkgb2Ygb2JqZWN0cyBhcyBsb25nIGFzIHRoZSBvYmplY3QgaGFzIGEgXCJ0aW1lXCIgYXR0cmlidXRlXG4gKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgoKHRpbWUsIHZhbHVlKSA9PiB7XG4gKiBcdC8vIHRoZSB2YWx1ZSBpcyBhbiBvYmplY3Qgd2hpY2ggY29udGFpbnMgYm90aCB0aGUgbm90ZSBhbmQgdGhlIHZlbG9jaXR5XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKHZhbHVlLm5vdGUsIFwiOG5cIiwgdGltZSwgdmFsdWUudmVsb2NpdHkpO1xuICogfSksIFt7IHRpbWU6IDAsIG5vdGU6IFwiQzNcIiwgdmVsb2NpdHk6IDAuOSB9LFxuICogXHR7IHRpbWU6IFwiMDoyXCIsIG5vdGU6IFwiQzRcIiwgdmVsb2NpdHk6IDAuNSB9XG4gKiBdKS5zdGFydCgwKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhcnQgZXh0ZW5kcyBUb25lRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXJ0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUcmFja3MgdGhlIHNjaGVkdWxlZCBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGV2ZW50cyB0aGF0IGJlbG9uZyB0byB0aGlzIHBhcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiXSk7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGluZ3MgYXJlIGFzc2lnbmVkIGluIHRoZSByaWdodCBvcmRlclxuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gYWRkIHRoZSBldmVudHNcbiAgICAgICAgb3B0aW9ucy5ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBcnJheShldmVudCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZChldmVudFswXSwgZXZlbnRbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lRXZlbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZXZlbnRzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBXaGVuIHRvIHN0YXJ0IHRoZSBwYXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBwYXJ0IHRvIGJlZ2luIHBsYXlpbmcgYXQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3AgPyB0aGlzLl9sb29wU3RhcnQgOiAwKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZE9mZnNldCA9IHRoaXMudG9UaWNrcyhvZmZzZXQpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHtcbiAgICAgICAgICAgICAgICBpZDogLTEsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiBjb21wdXRlZE9mZnNldCxcbiAgICAgICAgICAgICAgICBzdGF0ZTogXCJzdGFydGVkXCIsXG4gICAgICAgICAgICAgICAgdGltZTogdGlja3MsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgZXZlbnQgaW4gdGhlIGdpdmVuIGV2ZW50IGF0IHRoZSBjb3JyZWN0IHRpbWUgZ2l2ZW5cbiAgICAgKiB0aGUgdGlja3MgYW5kIG9mZnNldCBhbmQgbG9vcGluZy5cbiAgICAgKiBAcGFyYW0gIGV2ZW50XG4gICAgICogQHBhcmFtICB0aWNrc1xuICAgICAqIEBwYXJhbSAgb2Zmc2V0XG4gICAgICovXG4gICAgX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIG9mZnNldCkge1xuICAgICAgICB0aWNrcyAtPSBvZmZzZXQ7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPj0gdGhpcy5fbG9vcFN0YXJ0ICYmIGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcEVuZCkge1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA8IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBpdCBvbiB0aGUgbmV4dCBsb29wXG4gICAgICAgICAgICAgICAgICAgIHRpY2tzICs9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBldmVudC5zdGFydChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCAmJiBldmVudC5zdGFydE9mZnNldCA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICBldmVudC5sb29wID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID49IG9mZnNldCkge1xuICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50LnN0YXJ0T2Zmc2V0ICs9IHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aWNrcyk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RvcCh0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQvU2V0IGFuIEV2ZW50J3MgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW4gYW5kIG5vIGV2ZW50IGV4aXN0cyBhdFxuICAgICAqIHRoZSBnaXZlbiB0aW1lLCBvbmUgd2lsbCBiZSBjcmVhdGVkIHdpdGggdGhhdCB2YWx1ZS5cbiAgICAgKiBJZiB0d28gZXZlbnRzIGFyZSBhdCB0aGUgc2FtZSB0aW1lLCB0aGUgZmlyc3Qgb25lIHdpbGxcbiAgICAgKiBiZSByZXR1cm5lZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCk7XG4gICAgICogcGFydC5hdChcIjFtXCIpOyAvLyByZXR1cm5zIHRoZSBwYXJ0IGF0IHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogcGFydC5hdChcIjJtXCIsIFwiQzJcIik7IC8vIHNldCB0aGUgdmFsdWUgYXQgXCIybVwiIHRvIEMyLlxuICAgICAqIC8vIGlmIGFuIGV2ZW50IGRpZG4ndCBleGlzdCBhdCB0aGF0IHRpbWUsIGl0IHdpbGwgYmUgY3JlYXRlZC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnQgdG8gZ2V0IG9yIHNldC5cbiAgICAgKiBAcGFyYW0gdmFsdWUgSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW4sIHRoZSB2YWx1ZSBvZiB0aGUgZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUgd2lsbCBiZSBzZXQgdG8gaXQuXG4gICAgICovXG4gICAgYXQodGltZSwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgdGltZUluVGlja3MgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpO1xuICAgICAgICBjb25zdCB0aWNrVGltZSA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgMSkudG9TZWNvbmRzKCk7XG4gICAgICAgIGNvbnN0IGl0ZXJhdG9yID0gdGhpcy5fZXZlbnRzLnZhbHVlcygpO1xuICAgICAgICBsZXQgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICB3aGlsZSAoIXJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyh0aW1lSW5UaWNrcyAtIGV2ZW50LnN0YXJ0T2Zmc2V0KSA8IHRpY2tUaW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHRoZXJlIHdhcyBubyBldmVudCBhdCB0aGF0IHRpbWUsIGNyZWF0ZSBvbmVcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIC8vIHJldHVybiB0aGUgbmV3IGV2ZW50XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdCh0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZCh0aW1lLCB2YWx1ZSkge1xuICAgICAgICAvLyBleHRyYWN0IHRoZSBwYXJhbWV0ZXJzXG4gICAgICAgIGlmICh0aW1lIGluc3RhbmNlb2YgT2JqZWN0ICYmIFJlZmxlY3QuaGFzKHRpbWUsIFwidGltZVwiKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aW1lO1xuICAgICAgICAgICAgdGltZSA9IHZhbHVlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGxldCBldmVudDtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVG9uZUV2ZW50KSB7XG4gICAgICAgICAgICBldmVudCA9IHZhbHVlO1xuICAgICAgICAgICAgZXZlbnQuY2FsbGJhY2sgPSB0aGlzLl90aWNrLmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBldmVudCA9IG5ldyBUb25lRXZlbnQoe1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlIHN0YXJ0IG9mZnNldFxuICAgICAgICBldmVudC5zdGFydE9mZnNldCA9IHRpY2tzO1xuICAgICAgICAvLyBpbml0aWFsaXplIHRoZSB2YWx1ZXNcbiAgICAgICAgZXZlbnQuc2V0KHtcbiAgICAgICAgICAgIGh1bWFuaXplOiB0aGlzLmh1bWFuaXplLFxuICAgICAgICAgICAgbG9vcDogdGhpcy5sb29wLFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5sb29wRW5kLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLmxvb3BTdGFydCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogdGhpcy5wcm9iYWJpbGl0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoZXZlbnQpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbm90ZSBpZiBpdCBzaG91bGQgYmUgcGxheWVkIHJpZ2h0IG5vd1xuICAgICAgICB0aGlzLl9yZXN0YXJ0RXZlbnQoZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzdGFydCB0aGUgZ2l2ZW4gZXZlbnRcbiAgICAgKi9cbiAgICBfcmVzdGFydEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2goKHN0YXRlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgc3RhdGVFdmVudC50aW1lLCBzdGF0ZUV2ZW50Lm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzdG9wIHRoZSBub3RlXG4gICAgICAgICAgICAgICAgZXZlbnQuc3RvcChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXRlRXZlbnQudGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIC8vIGV4dHJhY3QgdGhlIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKGlzT2JqZWN0KHRpbWUpICYmIHRpbWUuaGFzT3duUHJvcGVydHkoXCJ0aW1lXCIpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRpbWU7XG4gICAgICAgICAgICB0aW1lID0gdmFsdWUudGltZTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPT09IHRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNVbmRlZih2YWx1ZSkgfHwgKGlzRGVmaW5lZCh2YWx1ZSkgJiYgZXZlbnQudmFsdWUgPT09IHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuZGVsZXRlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYWxsIG9mIHRoZSBub3RlcyBmcm9tIHRoZSBncm91cC5cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiBldmVudC5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9ldmVudHMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBzY2hlZHVsZWQgc3RhdGUgY2hhbmdlIGV2ZW50czogaS5lLiBcInN0YXJ0XCIgYW5kIFwic3RvcFwiLlxuICAgICAqIEBwYXJhbSBhZnRlciBUaGUgdGltZSBhZnRlciB3aGljaCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBldmVudHMuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4gZXZlbnQuY2FuY2VsKGFmdGVyKSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aGlzLnRvVGlja3MoYWZ0ZXIpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIF9mb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBQYXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBhdHRyaWJ1dGUgb2YgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKiBAcGFyYW0gIGF0dHIgIHRoZSBhdHRyaWJ1dGUgdG8gc2V0XG4gICAgICogQHBhcmFtICB2YWx1ZSAgICAgIFRoZSB2YWx1ZSB0byBzZXQgaXQgdG9cbiAgICAgKi9cbiAgICBfc2V0QWxsKGF0dHIsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnRbYXR0cl0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHRpY2sgbWV0aG9kXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBvZiB0aGUgZXZlbnQgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5tdXRlKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGV2ZW50IHNob3VsZCBiZSBjdXJyZW50bHkgbG9vcGluZ1xuICAgICAqIGdpdmVuIHRoZSBsb29wIGJvdW5kcmllcyBvZiB0aGlzIFBhcnQuXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIHRlc3RcbiAgICAgKi9cbiAgICBfdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgJiYgKGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcFN0YXJ0IHx8IGV2ZW50LnN0YXJ0T2Zmc2V0ID49IHRoaXMuX2xvb3BFbmQpKSB7XG4gICAgICAgICAgICBldmVudC5jYW5jZWwoMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXZlbnQuc3RhdGUgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICAvLyByZXNjaGVkdWxlIGl0IGlmIGl0J3Mgc3RvcHBlZFxuICAgICAgICAgICAgdGhpcy5fcmVzdGFydEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgICAgICB0aGlzLl9zZXRBbGwoXCJwcm9iYWJpbGl0eVwiLCBwcm9iKTtcbiAgICB9XG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgICAgIHRoaXMuX3NldEFsbChcImh1bWFuaXplXCIsIHZhcmlhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBwYXJ0IHNob3VsZCBsb29wIG9yIG5vdFxuICAgICAqIGJldHdlZW4gUGFydC5sb29wU3RhcnQgYW5kXG4gICAgICogUGFydC5sb29wRW5kLiBJZiBzZXQgdG8gdHJ1ZSxcbiAgICAgKiB0aGUgcGFydCB3aWxsIGxvb3AgaW5kZWZpbml0ZWx5LFxuICAgICAqIGlmIHNldCB0byBhIG51bWJlciBncmVhdGVyIHRoYW4gMVxuICAgICAqIGl0IHdpbGwgcGxheSBhIHNwZWNpZmljIG51bWJlciBvZlxuICAgICAqIHRpbWVzLCBpZiBzZXQgdG8gZmFsc2UsIDAgb3IgMSwgdGhlXG4gICAgICogcGFydCB3aWxsIG9ubHkgcGxheSBvbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKTtcbiAgICAgKiAvLyBsb29wIHRoZSBwYXJ0IDggdGltZXNcbiAgICAgKiBwYXJ0Lmxvb3AgPSA4O1xuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudC5sb29wU3RhcnQgPSB0aGlzLmxvb3BTdGFydDtcbiAgICAgICAgICAgIGV2ZW50Lmxvb3BFbmQgPSB0aGlzLmxvb3BFbmQ7XG4gICAgICAgICAgICBldmVudC5sb29wID0gbG9vcDtcbiAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wRW5kIHBvaW50IGRldGVybWluZXMgd2hlbiBpdCB3aWxsXG4gICAgICogbG9vcCBpZiBQYXJ0Lmxvb3AgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcEVuZCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhsb29wRW5kKTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wU3RhcnQgcG9pbnQgZGV0ZXJtaW5lcyB3aGVuIGl0IHdpbGxcbiAgICAgKiBsb29wIGlmIFBhcnQubG9vcCBpcyB0cnVlLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhsb29wU3RhcnQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQubG9vcFN0YXJ0ID0gdGhpcy5sb29wU3RhcnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIHBhcnRcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgdGhpcy5fc2V0QWxsKFwicGxheWJhY2tSYXRlXCIsIHJhdGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBub3RlcyBpbiB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzLnNpemU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXJ0LmpzLm1hcCIsImltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIFN0YXJ0IGF0IHRoZSBmaXJzdCB2YWx1ZSBhbmQgZ28gdXAgdG8gdGhlIGxhc3RcbiAqL1xuZnVuY3Rpb24qIHVwUGF0dGVybkdlbih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpbmRleCsrO1xuICAgIH1cbn1cbi8qKlxuICogU3RhcnQgYXQgdGhlIGxhc3QgdmFsdWUgYW5kIGdvIGRvd24gdG8gMFxuICovXG5mdW5jdGlvbiogZG93blBhdHRlcm5HZW4odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKGluZGV4ID49IDApIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpbmRleC0tO1xuICAgIH1cbn1cbi8qKlxuICogSW5maW5pdGVseSB5aWVsZCB0aGUgZ2VuZXJhdG9yXG4gKi9cbmZ1bmN0aW9uKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGdlbikge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHlpZWxkKiBnZW4odmFsdWVzKTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBpbmRleCBpcyBpbiB0aGUgZ2l2ZW4gcmFuZ2VcbiAqL1xuZnVuY3Rpb24gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKSB7XG4gICAgcmV0dXJuIGNsYW1wKGluZGV4LCAwLCB2YWx1ZXMubGVuZ3RoIC0gMSk7XG59XG4vKipcbiAqIEFsdGVybmF0ZSBiZXR3ZWVuIHR3byBnZW5lcmF0b3JzXG4gKi9cbmZ1bmN0aW9uKiBhbHRlcm5hdGluZ0dlbmVyYXRvcih2YWx1ZXMsIGRpcmVjdGlvblVwKSB7XG4gICAgbGV0IGluZGV4ID0gZGlyZWN0aW9uVXAgPyAwIDogdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpZiAoZGlyZWN0aW9uVXApIHtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICBpZiAoaW5kZXggPj0gdmFsdWVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb25VcCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgtLTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uVXAgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBTdGFydGluZyBmcm9tIHRoZSBib3R0b20gbW92ZSB1cCAyLCBkb3duIDFcbiAqL1xuZnVuY3Rpb24qIGp1bXBVcCh2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGxldCBzdGVwSW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBzdGVwSW5kZXgrKztcbiAgICAgICAgaW5kZXggKz0gKHN0ZXBJbmRleCAlIDIgPyAyIDogLTEpO1xuICAgIH1cbn1cbi8qKlxuICogU3RhcnRpbmcgZnJvbSB0aGUgdG9wIG1vdmUgZG93biAyLCB1cCAxXG4gKi9cbmZ1bmN0aW9uKiBqdW1wRG93bih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSB2YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICBsZXQgc3RlcEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPj0gMCkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIHN0ZXBJbmRleCsrO1xuICAgICAgICBpbmRleCArPSAoc3RlcEluZGV4ICUgMiA/IC0yIDogMSk7XG4gICAgfVxufVxuLyoqXG4gKiBDaG9vc2UgYSByYW5kb20gaW5kZXggZWFjaCB0aW1lXG4gKi9cbmZ1bmN0aW9uKiByYW5kb21HZW4odmFsdWVzKSB7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgY29uc3QgcmFuZG9tSW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB2YWx1ZXMubGVuZ3RoKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW3JhbmRvbUluZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFJhbmRvbWx5IGdvIHRocm91Z2ggYWxsIG9mIHRoZSB2YWx1ZXMgb25jZSBiZWZvcmUgY2hvb3NpbmcgYSBuZXcgcmFuZG9tIG9yZGVyXG4gKi9cbmZ1bmN0aW9uKiByYW5kb21PbmNlKHZhbHVlcykge1xuICAgIC8vIGNyZWF0ZSBhbiBhcnJheSBvZiBpbmRpY2VzXG4gICAgY29uc3QgY29weSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvcHkucHVzaChpKTtcbiAgICB9XG4gICAgd2hpbGUgKGNvcHkubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyByYW5kb20gY2hvb3NlIGFuIGluZGV4LCBhbmQgdGhlbiByZW1vdmUgaXQgc28gaXQncyBub3QgY2hvc2VuIGFnYWluXG4gICAgICAgIGNvbnN0IHJhbmRWYWwgPSBjb3B5LnNwbGljZShNYXRoLmZsb29yKGNvcHkubGVuZ3RoICogTWF0aC5yYW5kb20oKSksIDEpO1xuICAgICAgICBjb25zdCBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUocmFuZFZhbFswXSwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFJhbmRvbWx5IGNob29zZSB0byB3YWxrIHVwIG9yIGRvd24gMSBpbmRleCBpbiB0aGUgdmFsdWVzIGFycmF5XG4gKi9cbmZ1bmN0aW9uKiByYW5kb21XYWxrKHZhbHVlcykge1xuICAgIC8vIHJhbmRvbWx5IGNob29zZSBhIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB2YWx1ZXMgYXJyYXlcbiAgICBsZXQgaW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB2YWx1ZXMubGVuZ3RoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIGluZGV4Kys7IC8vIGF0IGJvdHRvbSBvZiBhcnJheSwgc28gZm9yY2UgdXB3YXJkIHN0ZXBcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PT0gdmFsdWVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGluZGV4LS07IC8vIGF0IHRvcCBvZiBhcnJheSwgc28gZm9yY2UgZG93bndhcmQgc3RlcFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKE1hdGgucmFuZG9tKCkgPCAwLjUpIHsgLy8gZWxzZSBjaG9vc2UgcmFuZG9tIGRvd253YXJkIG9yIHVwd2FyZCBzdGVwXG4gICAgICAgICAgICBpbmRleC0tO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgIH1cbn1cbi8qKlxuICogUGF0dGVybkdlbmVyYXRvciByZXR1cm5zIGEgZ2VuZXJhdG9yIHdoaWNoIHdpbGwgaXRlcmF0ZSBvdmVyIHRoZSBnaXZlbiBhcnJheVxuICogb2YgdmFsdWVzIGFuZCB5aWVsZCB0aGUgaXRlbXMgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgaW4gcGF0dGVyblxuICogQHBhcmFtIHZhbHVlcyBBbiBhcnJheSBvZiB2YWx1ZXMgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gcGF0dGVybiBUaGUgbmFtZSBvZiB0aGUgcGF0dGVybiB1c2Ugd2hlbiBpdGVyYXRpbmcgb3ZlclxuICogQHBhcmFtIGluZGV4IFdoZXJlIHRvIHN0YXJ0IGluIHRoZSBvZmZzZXQgb2YgdGhlIHZhbHVlcyBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24qIFBhdHRlcm5HZW5lcmF0b3IodmFsdWVzLCBwYXR0ZXJuID0gXCJ1cFwiLCBpbmRleCA9IDApIHtcbiAgICAvLyBzYWZlZ3VhcmRzXG4gICAgYXNzZXJ0KHZhbHVlcy5sZW5ndGggPiAwLCBcIlRoZSBhcnJheSBtdXN0IGhhdmUgbW9yZSB0aGFuIG9uZSB2YWx1ZSBpbiBpdFwiKTtcbiAgICBzd2l0Y2ggKHBhdHRlcm4pIHtcbiAgICAgICAgY2FzZSBcInVwXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCB1cFBhdHRlcm5HZW4pO1xuICAgICAgICBjYXNlIFwiZG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywgZG93blBhdHRlcm5HZW4pO1xuICAgICAgICBjYXNlIFwidXBEb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogYWx0ZXJuYXRpbmdHZW5lcmF0b3IodmFsdWVzLCB0cnVlKTtcbiAgICAgICAgY2FzZSBcImRvd25VcFwiOlxuICAgICAgICAgICAgeWllbGQqIGFsdGVybmF0aW5nR2VuZXJhdG9yKHZhbHVlcywgZmFsc2UpO1xuICAgICAgICBjYXNlIFwiYWx0ZXJuYXRlVXBcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGp1bXBVcCk7XG4gICAgICAgIGNhc2UgXCJhbHRlcm5hdGVEb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCBqdW1wRG93bik7XG4gICAgICAgIGNhc2UgXCJyYW5kb21cIjpcbiAgICAgICAgICAgIHlpZWxkKiByYW5kb21HZW4odmFsdWVzKTtcbiAgICAgICAgY2FzZSBcInJhbmRvbU9uY2VcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIHJhbmRvbU9uY2UpO1xuICAgICAgICBjYXNlIFwicmFuZG9tV2Fsa1wiOlxuICAgICAgICAgICAgeWllbGQqIHJhbmRvbVdhbGsodmFsdWVzKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXR0ZXJuR2VuZXJhdG9yLmpzLm1hcCIsImltcG9ydCB7IExvb3AgfSBmcm9tIFwiLi9Mb29wXCI7XG5pbXBvcnQgeyBQYXR0ZXJuR2VuZXJhdG9yIH0gZnJvbSBcIi4vUGF0dGVybkdlbmVyYXRvclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogUGF0dGVybiBhcnBlZ2dpYXRlcyBiZXR3ZWVuIHRoZSBnaXZlbiBub3Rlc1xuICogaW4gYSBudW1iZXIgb2YgcGF0dGVybnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGF0dGVybiA9IG5ldyBUb25lLlBhdHRlcm4oKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0Ly8gdGhlIG9yZGVyIG9mIHRoZSBub3RlcyBwYXNzZWQgaW4gZGVwZW5kcyBvbiB0aGUgcGF0dGVyblxuICogfSwgW1wiQzJcIiwgXCJENFwiLCBcIkU1XCIsIFwiQTZcIl0sIFwidXBEb3duXCIpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYXR0ZXJuIGV4dGVuZHMgTG9vcCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhdHRlcm4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcInZhbHVlc1wiLCBcInBhdHRlcm5cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXR0ZXJuXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXR0ZXJuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZXNcIiwgXCJwYXR0ZXJuXCJdKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3ZhbHVlcyA9IG9wdGlvbnMudmFsdWVzO1xuICAgICAgICB0aGlzLl9wYXR0ZXJuID0gUGF0dGVybkdlbmVyYXRvcihvcHRpb25zLnZhbHVlcywgb3B0aW9ucy5wYXR0ZXJuKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMucGF0dGVybjtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMb29wLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhdHRlcm46IFwidXBcIixcbiAgICAgICAgICAgIHZhbHVlczogW10sXG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIHRoZSBub3RlcyBzaG91bGQgYmUgY2FsbGVkXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3BhdHRlcm4ubmV4dCgpO1xuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlLnZhbHVlO1xuICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRoaXMuX3ZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IG9mIGV2ZW50cy5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWVzO1xuICAgIH1cbiAgICBzZXQgdmFsdWVzKHZhbCkge1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSB2YWw7XG4gICAgICAgIC8vIHJlc2V0IHRoZSBwYXR0ZXJuXG4gICAgICAgIHRoaXMucGF0dGVybiA9IHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwYXR0ZXJuLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0dGVybiB0eXBlLiBTZWUgVG9uZS5DdHJsUGF0dGVybiBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBwYXR0ZXJucy5cbiAgICAgKi9cbiAgICBnZXQgcGF0dGVybigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCBwYXR0ZXJuKHBhdHRlcm4pIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHBhdHRlcm47XG4gICAgICAgIHRoaXMuX3BhdHRlcm4gPSBQYXR0ZXJuR2VuZXJhdG9yKHRoaXMuX3ZhbHVlcywgdGhpcy5fdHlwZSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGF0dGVybi5qcy5tYXAiLCJpbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgUGFydCB9IGZyb20gXCIuL1BhcnRcIjtcbmltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLyoqXG4gKiBBIHNlcXVlbmNlIGlzIGFuIGFsdGVybmF0ZSBub3RhdGlvbiBvZiBhIHBhcnQuIEluc3RlYWRcbiAqIG9mIHBhc3NpbmcgaW4gYW4gYXJyYXkgb2YgW3RpbWUsIGV2ZW50XSBwYWlycywgcGFzc1xuICogaW4gYW4gYXJyYXkgb2YgZXZlbnRzIHdoaWNoIHdpbGwgYmUgc3BhY2VkIGF0IHRoZVxuICogZ2l2ZW4gc3ViZGl2aXNpb24uIFN1Yi1hcnJheXMgd2lsbCBzdWJkaXZpZGUgdGhhdCBiZWF0XG4gKiBieSB0aGUgbnVtYmVyIG9mIGl0ZW1zIGFyZSBpbiB0aGUgYXJyYXkuXG4gKiBTZXF1ZW5jZSBub3RhdGlvbiBpbnNwaXJhdGlvbiBmcm9tIFtUaWRhbF0oaHR0cDovL3lheHUub3JnL3RpZGFsLylcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgc2VxID0gbmV3IFRvbmUuU2VxdWVuY2UoKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgMC4xLCB0aW1lKTtcbiAqIFx0Ly8gc3ViZGl2aXNpb25zIGFyZSBnaXZlbiBhcyBzdWJhcnJheXNcbiAqIH0sIFtcIkM0XCIsIFtcIkU0XCIsIFwiRDRcIiwgXCJFNFwiXSwgXCJHNFwiLCBbXCJBNFwiLCBcIkc0XCJdXSkuc3RhcnQoMCk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXF1ZW5jZSBleHRlbmRzIFRvbmVFdmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNlcXVlbmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIiwgXCJzdWJkaXZpc2lvblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNlcXVlbmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2JqZWN0IHJlc3BvbnNpYmxlIGZvciBzY2hlZHVsaW5nIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wYXJ0ID0gbmV3IFBhcnQoe1xuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3NlcUNhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogcHJpdmF0ZSByZWZlcmVuY2UgdG8gYWxsIG9mIHRoZSBzZXF1ZW5jZSBwcm94aWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwcm94aWVkIGFycmF5XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHNBcnJheSA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2VxdWVuY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiLCBcInN1YmRpdmlzaW9uXCJdKTtcbiAgICAgICAgdGhpcy5fc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5zdWJkaXZpc2lvbik7XG4gICAgICAgIHRoaXMuZXZlbnRzID0gb3B0aW9ucy5ldmVudHM7XG4gICAgICAgIC8vIHNldCBhbGwgb2YgdGhlIHZhbHVlc1xuICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5wcm9iYWJpbGl0eSA9IG9wdGlvbnMucHJvYmFiaWxpdHk7XG4gICAgICAgIHRoaXMuaHVtYW5pemUgPSBvcHRpb25zLmh1bWFuaXplO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIFtcInZhbHVlXCJdKSwge1xuICAgICAgICAgICAgZXZlbnRzOiBbXSxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgc3ViZGl2aXNpb246IFwiOG5cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlcm5hbCBjYWxsYmFjayBmb3Igd2hlbiBhbiBldmVudCBpcyBpbnZva2VkXG4gICAgICovXG4gICAgX3NlcUNhbGxiYWNrKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNlcXVlbmNlXG4gICAgICovXG4gICAgZ2V0IGV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cztcbiAgICB9XG4gICAgc2V0IGV2ZW50cyhzKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQXJyYXkgPSBzO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB0aGlzLl9jcmVhdGVTZXF1ZW5jZSh0aGlzLl9ldmVudHNBcnJheSk7XG4gICAgICAgIHRoaXMuX2V2ZW50c1VwZGF0ZWQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgIFdoZW4gdG8gc3RhcnQgdGhlIHBhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgIFRoZSBvZmZzZXQgaW5kZXggdG8gc3RhcnQgYXRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdGFydCh0aW1lLCBvZmZzZXQgPyB0aGlzLl9pbmRleFRpbWUob2Zmc2V0KSA6IG9mZnNldCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdG9wIHRoZSBwYXJ0LlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJ0LnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3ViZGl2aXNpb24gb2YgdGhlIHNlcXVlbmNlLiBUaGlzIGNhbiBvbmx5IGJlXG4gICAgICogc2V0IGluIHRoZSBjb25zdHJ1Y3Rvci4gVGhlIHN1YmRpdmlzaW9uIGlzIHRoZVxuICAgICAqIGludGVydmFsIGJldHdlZW4gc3VjY2Vzc2l2ZSBzdGVwcy5cbiAgICAgKi9cbiAgICBnZXQgc3ViZGl2aXNpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N1YmRpdmlzaW9uKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgc2VxdWVuY2UgcHJveHkgd2hpY2ggY2FuIGJlIG1vbml0b3JlZCB0byBjcmVhdGUgc3Vic2VxdWVuY2VzXG4gICAgICovXG4gICAgX2NyZWF0ZVNlcXVlbmNlKGFycmF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoYXJyYXksIHtcbiAgICAgICAgICAgIGdldDogKHRhcmdldCwgcHJvcGVydHkpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBwcm9wZXJ0eSBpcyBpbmRleCBpbiB0aGlzIGNhc2VcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0W3Byb3BlcnR5XTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6ICh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1N0cmluZyhwcm9wZXJ0eSkgJiYgaXNGaW5pdGUocGFyc2VJbnQocHJvcGVydHksIDEwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdGhpcy5fY3JlYXRlU2VxdWVuY2UodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1VwZGF0ZWQoKTtcbiAgICAgICAgICAgICAgICAvLyByZXR1cm4gdHJ1ZSB0byBhY2NlcHQgdGhlIGNoYW5nZXNcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBzZXF1ZW5jZSBoYXMgY2hhbmdlZCwgYWxsIG9mIHRoZSBldmVudHMgbmVlZCB0byBiZSByZWNyZWF0ZWRcbiAgICAgKi9cbiAgICBfZXZlbnRzVXBkYXRlZCgpIHtcbiAgICAgICAgdGhpcy5fcGFydC5jbGVhcigpO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlU2VxdWVuY2UodGhpcy5fZXZlbnRzQXJyYXksIHRoaXMuX3N1YmRpdmlzaW9uLCB0aGlzLnN0YXJ0T2Zmc2V0KTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBsb29wRW5kXG4gICAgICAgIHRoaXMubG9vcEVuZCA9IHRoaXMubG9vcEVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogcmVzY2hlZHVsZSBhbGwgb2YgdGhlIGV2ZW50cyB0aGF0IG5lZWQgdG8gYmUgcmVzY2hlZHVsZWRcbiAgICAgKi9cbiAgICBfcmVzY2hlZHVsZVNlcXVlbmNlKHNlcXVlbmNlLCBzdWJkaXZpc2lvbiwgc3RhcnRPZmZzZXQpIHtcbiAgICAgICAgc2VxdWVuY2UuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudE9mZnNldCA9IGluZGV4ICogKHN1YmRpdmlzaW9uKSArIHN0YXJ0T2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZVNlcXVlbmNlKHZhbHVlLCBzdWJkaXZpc2lvbiAvIHZhbHVlLmxlbmd0aCwgZXZlbnRPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBldmVudE9mZnNldCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnQuYWRkKHN0YXJ0VGltZSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBpbmRleCBnaXZlbiB0aGUgU2VxdWVuY2UncyBzdWJkaXZpc2lvblxuICAgICAqIEBwYXJhbSAgaW5kZXhcbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIG9mIHRoYXQgaW5kZXhcbiAgICAgKi9cbiAgICBfaW5kZXhUaW1lKGluZGV4KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIGluZGV4ICogKHRoaXMuX3N1YmRpdmlzaW9uKSArIHRoaXMuc3RhcnRPZmZzZXQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhciBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9wYXJ0LmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcnQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gUFJPWFkgQ0FMTFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQubG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobCkge1xuICAgICAgICB0aGlzLl9wYXJ0Lmxvb3AgPSBsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIHNlcXVlbmNlIHNob3VsZCBzdGFydCBsb29waW5nXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChpbmRleCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBpbmRleDtcbiAgICAgICAgdGhpcy5fcGFydC5sb29wU3RhcnQgPSB0aGlzLl9pbmRleFRpbWUoaW5kZXgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIHNlcXVlbmNlIHNob3VsZCBlbmQgbG9vcGluZ1xuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnQubG9vcEVuZCA9IHRoaXMuX2luZGV4VGltZSh0aGlzLl9ldmVudHNBcnJheS5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcGFydC5sb29wRW5kID0gdGhpcy5faW5kZXhUaW1lKGluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnN0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQoc3RhcnQpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdGFydE9mZnNldCA9IHN0YXJ0O1xuICAgIH1cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wYXJ0LnBsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgfVxuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQucHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3BhcnQucHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnByb2dyZXNzO1xuICAgIH1cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmh1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuaHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2NoZWR1bGVkIGV2ZW50c1xuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmxlbmd0aDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TZXF1ZW5jZS5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9Mb29wXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QYXJ0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QYXR0ZXJuXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TZXF1ZW5jZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEdhaW5Ub0F1ZGlvIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9HYWluVG9BdWRpb1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbi8qKlxuICogVG9uZS5Dcm9zc2ZhZGUgcHJvdmlkZXMgZXF1YWwgcG93ZXIgZmFkaW5nIGJldHdlZW4gdHdvIGlucHV0cy5cbiAqIE1vcmUgb24gY3Jvc3NmYWRpbmcgdGVjaG5pcXVlIFtoZXJlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GYWRlXyhhdWRpb19lbmdpbmVlcmluZykjQ3Jvc3NmYWRpbmcpLlxuICogYGBgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKz4gaW5wdXQgYSArPi0tK1xuICogKy0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0rICAgICB8ICAgICAgICAgfCAgIHxcbiAqIHwgMXMgc2lnbmFsICs+LS0+IHN0ZXJlb1Bhbm5lck5vZGUgIEwgKz4tLS0tPiBnYWluICAgIHwgICB8XG4gKiArLS0tLS0tLS0tLS0rICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICstLS0tLS0tLS0rICAgfFxuICogICAgICAgICAgICAgICArLT4gcGFuICAgICAgICAgICAgICAgUiArPi0rICAgICAgICAgICAgICAgIHwgICArLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgIHwgICAgICAgICAgICAgICAgKy0tLT4gb3V0cHV0ICs+XG4gKiAgKy0tLS0tLSsgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICstLS0tLS0tLS0rICAgfCAgICstLS0tLS0tLStcbiAqICB8IGZhZGUgKz4tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgfCArPiBpbnB1dCBiICs+LS0rXG4gKiAgKy0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLT4gZ2FpbiAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjcm9zc0ZhZGUgPSBuZXcgVG9uZS5Dcm9zc0ZhZGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBjb25uZWN0IHR3byBpbnB1dHMgVG9uZS50byBhL2JcbiAqIGNvbnN0IGlucHV0QSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNxdWFyZVwiKS5jb25uZWN0KGNyb3NzRmFkZS5hKS5zdGFydCgpO1xuICogY29uc3QgaW5wdXRCID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS5jb25uZWN0KGNyb3NzRmFkZS5iKS5zdGFydCgpO1xuICogLy8gdXNlIHRoZSBmYWRlIHRvIGNvbnRyb2wgdGhlIG1peCBiZXR3ZWVuIHRoZSB0d29cbiAqIGNyb3NzRmFkZS5mYWRlLnZhbHVlID0gMC41O1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ3Jvc3NGYWRlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ3Jvc3NGYWRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZmFkZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDcm9zc0ZhZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjcm9zc2ZhZGluZyBpcyBkb25lIGJ5IGEgU3RlcmVvUGFubmVyTm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogU3BsaXQgdGhlIG91dHB1dCBvZiB0aGUgcGFubmVyIG5vZGUgaW50byB0d28gdmFsdWVzIHVzZWQgdG8gY29udHJvbCB0aGUgZ2FpbnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zcGxpdCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIoMik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0IHRoZSBmYWRlIHZhbHVlIGludG8gYW4gYXVkaW8gcmFuZ2UgdmFsdWUgc28gaXQgY2FuIGJlIGNvbm5lY3RlZFxuICAgICAgICAgKiB0byB0aGUgcGFubmVyLnBhbiBBdWRpb1BhcmFtXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nMmEgPSBuZXcgR2FpblRvQXVkaW8oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgd2hpY2ggaXMgYXQgZnVsbCBsZXZlbCB3aGVuIGZhZGUgPSAwXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmEgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCB3aGljaCBpcyBhdCBmdWxsIGxldmVsIHdoZW4gZmFkZSA9IDFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBpcyBhIG1peCBiZXR3ZWVuIGBhYCBhbmQgYGJgIGF0IHRoZSByYXRpbyBvZiBgZmFkZWBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5hLCB0aGlzLmJdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ3Jvc3NGYWRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZmFkZVwiXSk7XG4gICAgICAgIHRoaXMuZmFkZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZhZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZhZGVcIik7XG4gICAgICAgIHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgxKS5jb25uZWN0KHRoaXMuX3Bhbm5lcik7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIHN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XG4gICAgICAgIC8vIGRvZXNuJ3QgbWFrZSBhbnkgZGlmZmVyZW5jZSBmb3IgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2lzc3Vlcy82NDdcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NwbGl0LCB0aGlzLmEuZ2FpbiwgMCk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc3BsaXQsIHRoaXMuYi5nYWluLCAxKTtcbiAgICAgICAgdGhpcy5mYWRlLmNoYWluKHRoaXMuX2cyYSwgdGhpcy5fcGFubmVyLnBhbik7XG4gICAgICAgIHRoaXMuYS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5iLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmFkZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmFkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2cyYS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q3Jvc3NGYWRlLmpzLm1hcCIsImltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogRWZmZWN0IGlzIHRoZSBiYXNlIGNsYXNzIGZvciBlZmZlY3RzLiBDb25uZWN0IHRoZSBlZmZlY3QgYmV0d2VlblxuICogdGhlIGVmZmVjdFNlbmQgYW5kIGVmZmVjdFJldHVybiBHYWluTm9kZXMsIHRoZW4gY29udHJvbCB0aGUgYW1vdW50IG9mXG4gKiBlZmZlY3Qgd2hpY2ggZ29lcyB0byB0aGUgb3V0cHV0IHVzaW5nIHRoZSB3ZXQgY29udHJvbC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVmZmVjdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRWZmZWN0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgZHJ5d2V0IGtub2IgdG8gY29udHJvbCB0aGUgYW1vdW50IG9mIGVmZmVjdFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZHJ5V2V0ID0gbmV3IENyb3NzRmFkZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB3ZXQgY29udHJvbCBpcyBob3cgbXVjaCBvZiB0aGUgZWZmZWN0ZWRcbiAgICAgICAgICogd2lsbCBwYXNzIHRocm91Z2ggdG8gdGhlIG91dHB1dC4gMSA9IDEwMCUgZWZmZWN0ZWRcbiAgICAgICAgICogc2lnbmFsLCAwID0gMTAwJSBkcnkgc2lnbmFsLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy53ZXQgPSB0aGlzLl9kcnlXZXQuZmFkZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbm5lY3QgdGhlIGVmZmVjdFNlbmQgdG8gdGhlIGlucHV0IG9mIGh0ZSBlZmZlY3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoZSBlZmZlY3QgdG8gdGhlIGVmZmVjdFJldHVyblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlZmZlY3QgaW5wdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVmZmVjdCBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZHJ5V2V0O1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmZhbih0aGlzLl9kcnlXZXQuYSwgdGhpcy5lZmZlY3RTZW5kKTtcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY29ubmVjdCh0aGlzLl9kcnlXZXQuYik7XG4gICAgICAgIHRoaXMud2V0LnNldFZhbHVlQXRUaW1lKG9wdGlvbnMud2V0LCAwKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmVmZmVjdFJldHVybiwgdGhpcy5lZmZlY3RTZW5kXTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ3ZXRcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3ZXQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFpbnMgdGhlIGVmZmVjdCBpbiBiZXR3ZWVuIHRoZSBlZmZlY3RTZW5kIGFuZCBlZmZlY3RSZXR1cm5cbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0KGVmZmVjdCkge1xuICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGludGVybmFsIGNoYW5uZWxzXG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMucHVzaChlZmZlY3QpO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4oZWZmZWN0LCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RyeVdldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53ZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgTEZPLWJhc2VkIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBMRk9FZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTEZPRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuX2xmbyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGFtcGxpdHVkZTogb3B0aW9ucy5kZXB0aCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9sZm8uYW1wbGl0dWRlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmby5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIGRlcHRoOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGVmZmVjdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmby5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxmb1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm8uc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGZpbHRlciB0byB0aGUgdHJhbnNwb3J0LiBTZWUgW1tMRk8uc3luY11dXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvLnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmby51bnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBMRk8ncyBvc2NpbGxhdG9yOiBTZWUgW1tPc2NpbGxhdG9yLnR5cGVdXVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKCkuc3RhcnQoKS5jb25uZWN0KGF1dG9GaWx0ZXIpO1xuICAgICAqIGF1dG9GaWx0ZXIudHlwZSA9IFwic3F1YXJlXCI7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8udHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm8udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TEZPRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZpbHRlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk9FZmZlY3QgfSBmcm9tIFwiLi9MRk9FZmZlY3RcIjtcbi8qKlxuICogQXV0b0ZpbHRlciBpcyBhIFRvbmUuRmlsdGVyIHdpdGggYSBUb25lLkxGTyBjb25uZWN0ZWQgdG8gdGhlIGZpbHRlciBjdXRvZmYgZnJlcXVlbmN5LlxuICogU2V0dGluZyB0aGUgTEZPIHJhdGUgYW5kIGRlcHRoIGFsbG93cyBmb3IgY29udHJvbCBvdmVyIHRoZSBmaWx0ZXIgbW9kdWxhdGlvbiByYXRlXG4gKiBhbmQgZGVwdGguXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhbiBhdXRvZmlsdGVyIGFuZCBzdGFydCBpdCdzIExGT1xuICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoXCI0blwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgZmlsdGVyIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGF1dG9GaWx0ZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvRmlsdGVyIGV4dGVuZHMgTEZPRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b0ZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b0ZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b0ZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCJdKTtcbiAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXIsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSkpO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5maWx0ZXIpO1xuICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLmZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMRk9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgb2N0YXZlczogMi42LFxuICAgICAgICAgICAgZmlsdGVyOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICAgICAgcm9sbG9mZjogLTEyLFxuICAgICAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby5taW47XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KGZyZXEpIHtcbiAgICAgICAgdGhpcy5fbGZvLm1pbiA9IHRoaXMudG9GcmVxdWVuY3koZnJlcSk7XG4gICAgICAgIC8vIGFuZCBzZXQgdGhlIG1heFxuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdCkge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0O1xuICAgICAgICB0aGlzLl9sZm8ubWF4ID0gdGhpcy5fbGZvLm1pbiAqIE1hdGgucG93KDIsIG9jdCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdXRvRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBhbm5lciBpcyBhbiBlcXVhbCBwb3dlciBMZWZ0L1JpZ2h0IFBhbm5lci4gSXQgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgU3RlcmVvUGFubmVyTm9kZS5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIC8vIG1vdmUgdGhlIGlucHV0IHNpZ25hbCBmcm9tIHJpZ2h0IHRvIGxlZnRcbiAqIFx0Y29uc3QgcGFubmVyID0gbmV3IFRvbmUuUGFubmVyKDEpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0cGFubmVyLnBhbi5yYW1wVG8oLTEsIDAuNSk7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMTAwKS5jb25uZWN0KHBhbm5lcikuc3RhcnQoKTtcbiAqIH0sIDAuNSwgMik7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5uZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFubmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgcGFubmVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3Bhbm5lcjtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9wYW5uZXI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIl0pO1xuICAgICAgICB0aGlzLnBhbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBhbixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBhbixcbiAgICAgICAgICAgIG1pblZhbHVlOiAtMSxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIHN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XG4gICAgICAgIC8vIGRvZXNuJ3QgbWFrZSBhbnkgZGlmZmVyZW5jZSBmb3IgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2lzc3Vlcy82NDdcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudCA9IG9wdGlvbnMuY2hhbm5lbENvdW50O1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgLy8gaW5pdGlhbCB2YWx1ZVxuICAgICAgICByZWFkT25seSh0aGlzLCBcInBhblwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5uZXIuanMubWFwIiwiaW1wb3J0IHsgUGFubmVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1Bhbm5lclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk9FZmZlY3QgfSBmcm9tIFwiLi9MRk9FZmZlY3RcIjtcbi8qKlxuICogQXV0b1Bhbm5lciBpcyBhIFtbUGFubmVyXV0gd2l0aCBhbiBbW0xGT11dIGNvbm5lY3RlZCB0byB0aGUgcGFuIGFtb3VudC5cbiAqIFtSZWxhdGVkIFJlYWRpbmddKGh0dHBzOi8vd3d3LmFibGV0b24uY29tL2VuL2Jsb2cvYXV0b3Bhbi1jaG9wcGVyLWVmZmVjdC1hbmQtbW9yZS1saXZlc2Nob29sLykuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhbiBhdXRvcGFubmVyIGFuZCBzdGFydCBpdFxuICogY29uc3QgYXV0b1Bhbm5lciA9IG5ldyBUb25lLkF1dG9QYW5uZXIoXCI0blwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgcGFubmVyIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGF1dG9QYW5uZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvUGFubmVyIGV4dGVuZHMgTEZPRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1Bhbm5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9QYW5uZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9QYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSBuZXcgUGFubmVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9wYW5uZXIpO1xuICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLl9wYW5uZXIucGFuKTtcbiAgICAgICAgdGhpcy5fbGZvLm1pbiA9IC0xO1xuICAgICAgICB0aGlzLl9sZm8ubWF4ID0gMTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMRk9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1dG9QYW5uZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVQb2xlRmlsdGVyIH0gZnJvbSBcIi4uL2ZpbHRlci9PbmVQb2xlRmlsdGVyXCI7XG5pbXBvcnQgeyBBYnMgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0Fic1wiO1xuLyoqXG4gKiBGb2xsb3dlciBpcyBhIHNpbXBsZSBlbnZlbG9wZSBmb2xsb3dlci5cbiAqIEl0J3MgaW1wbGVtZW50ZWQgYnkgYXBwbHlpbmcgYSBsb3dwYXNzIGZpbHRlciB0byB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIGBgYFxuICogICAgICAgICAgKy0tLS0tKyAgICArLS0tLS0tLS0tLS0tLS0tK1xuICogSW5wdXQgKy0tPiBBYnMgKy0tLS0+IE9uZVBvbGVGaWx0ZXIgKy0tPiBPdXRwdXRcbiAqICAgICAgICAgICstLS0tLSsgICAgKy0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRm9sbG93ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRm9sbG93ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGb2xsb3dlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRm9sbG93ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLl9hYnMgPSB0aGlzLmlucHV0ID0gbmV3IEFicyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMub3V0cHV0ID0gbmV3IE9uZVBvbGVGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAxIC8gdGhpcy50b1NlY29uZHMob3B0aW9ucy5zbW9vdGhpbmcpLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Ficy5jb25uZWN0KHRoaXMuX2xvd3Bhc3MpO1xuICAgICAgICB0aGlzLl9zbW9vdGhpbmcgPSBvcHRpb25zLnNtb290aGluZztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC4wNVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGl0IHRha2VzIGEgdmFsdWUgY2hhbmdlIHRvIGFycml2ZSBhdCB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHNtb290aGluZykge1xuICAgICAgICB0aGlzLl9zbW9vdGhpbmcgPSBzbW9vdGhpbmc7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuZnJlcXVlbmN5ID0gMSAvIHRoaXMudG9TZWNvbmRzKHRoaXMuc21vb3RoaW5nKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hYnMuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Rm9sbG93ZXIuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IEZvbGxvd2VyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9hbmFseXNpcy9Gb2xsb3dlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBTY2FsZUV4cCB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVFeHBcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQXV0b1dhaCBjb25uZWN0cyBhIFtbRm9sbG93ZXJdXSB0byBhIFtbRmlsdGVyXV0uXG4gKiBUaGUgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXIsIGZvbGxvd3MgdGhlIGlucHV0IGFtcGxpdHVkZSBjdXJ2ZS5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgYXV0b1dhaCA9IG5ldyBUb25lLkF1dG9XYWgoNTAsIDYsIC0zMCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gaW5pdGlhbGl6ZSB0aGUgc3ludGggYW5kIGNvbm5lY3QgdG8gYXV0b3dhaFxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLmNvbm5lY3QoYXV0b1dhaCk7XG4gKiAvLyBRIHZhbHVlIGluZmx1ZW5jZXMgdGhlIGVmZmVjdCBvZiB0aGUgd2FoIC0gZGVmYXVsdCBpcyAyXG4gKiBhdXRvV2FoLlEudmFsdWUgPSA2O1xuICogLy8gbW9yZSBhdWRpYmxlIG9uIGhpZ2hlciBub3Rlc1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b1dhaCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9XYWguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcInNlbnNpdGl2aXR5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b1dhaFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1dhaC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwic2Vuc2l0aXZpdHlcIl0pO1xuICAgICAgICB0aGlzLl9mb2xsb3dlciA9IG5ldyBGb2xsb3dlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IG9wdGlvbnMuZm9sbG93ZXIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlID0gbmV3IFNjYWxlRXhwKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIGV4cG9uZW50OiAwLjUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2JhbmRwYXNzID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICByb2xsb2ZmOiAtNDgsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICBROiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wZWFraW5nID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInBlYWtpbmdcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGVha2luZy5nYWluLnZhbHVlID0gb3B0aW9ucy5nYWluO1xuICAgICAgICB0aGlzLmdhaW4gPSB0aGlzLl9wZWFraW5nLmdhaW47XG4gICAgICAgIHRoaXMuUSA9IHRoaXMuX2JhbmRwYXNzLlE7XG4gICAgICAgIC8vIHRoZSBjb250cm9sIHNpZ25hbCBwYXRoXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9pbnB1dEJvb3N0LCB0aGlzLl9mb2xsb3dlciwgdGhpcy5fc3dlZXBSYW5nZSk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuY29ubmVjdCh0aGlzLl9iYW5kcGFzcy5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmNvbm5lY3QodGhpcy5fcGVha2luZy5mcmVxdWVuY3kpO1xuICAgICAgICAvLyB0aGUgZmlsdGVyZWQgcGF0aFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5fYmFuZHBhc3MsIHRoaXMuX3BlYWtpbmcsIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlXG4gICAgICAgIHRoaXMuX3NldFN3ZWVwUmFuZ2UoKTtcbiAgICAgICAgdGhpcy5zZW5zaXRpdml0eSA9IG9wdGlvbnMuc2Vuc2l0aXZpdHk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImdhaW5cIiwgXCJRXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMTAwLFxuICAgICAgICAgICAgb2N0YXZlczogNixcbiAgICAgICAgICAgIHNlbnNpdGl2aXR5OiAwLFxuICAgICAgICAgICAgUTogMixcbiAgICAgICAgICAgIGdhaW46IDIsXG4gICAgICAgICAgICBmb2xsb3dlcjogMC4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIHRoYXQgdGhlIGZpbHRlciB3aWxsIHN3ZWVwIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5LlxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgdGhpcy5fc2V0U3dlZXBSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZm9sbG93ZXIncyBzbW9vdGhpbmcgdGltZVxuICAgICAqL1xuICAgIGdldCBmb2xsb3dlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IGZvbGxvd2VyKGZvbGxvd2VyKSB7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZyA9IGZvbGxvd2VyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBmcmVxdWVuY3kgZnJvbSB3aGljaCB0aGUgc3dlZXAgd2lsbCBzdGFydCBmcm9tLlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3koYmFzZUZyZXEpIHtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3koYmFzZUZyZXEpO1xuICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzZW5zaXRpdml0eSB0byBjb250cm9sIGhvdyByZXNwb25zaXZlIHRvIHRoZSBpbnB1dCBzaWduYWwgdGhlIGZpbHRlciBpcy5cbiAgICAgKi9cbiAgICBnZXQgc2Vuc2l0aXZpdHkoKSB7XG4gICAgICAgIHJldHVybiBnYWluVG9EYigxIC8gdGhpcy5faW5wdXRCb29zdC5nYWluLnZhbHVlKTtcbiAgICB9XG4gICAgc2V0IHNlbnNpdGl2aXR5KHNlbnNpdGl2aXR5KSB7XG4gICAgICAgIHRoaXMuX2lucHV0Qm9vc3QuZ2Fpbi52YWx1ZSA9IDEgLyBkYlRvR2FpbihzZW5zaXRpdml0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHNldHMgdGhlIHN3ZWVwIHJhbmdlIG9mIHRoZSBzY2FsZXJcbiAgICAgKi9cbiAgICBfc2V0U3dlZXBSYW5nZSgpIHtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLm1heCA9IE1hdGgubWluKHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCB0aGlzLl9vY3RhdmVzKSwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAyKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iYW5kcGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BlYWtpbmcuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXV0b1dhaC5qcy5tYXAiLCJpbXBvcnQgXCIuLi9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJQcm9jZXNzb3IgfSBmcm9tIFwiLi4vY29yZS93b3JrbGV0L1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNvbnN0IHdvcmtsZXROYW1lID0gXCJiaXQtY3J1c2hlclwiO1xuZXhwb3J0IGNvbnN0IGJpdENydXNoZXJXb3JrbGV0ID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdGNsYXNzIEJpdENydXNoZXJXb3JrbGV0IGV4dGVuZHMgU2luZ2xlSU9Qcm9jZXNzb3Ige1xuXG5cdFx0c3RhdGljIGdldCBwYXJhbWV0ZXJEZXNjcmlwdG9ycygpIHtcblx0XHRcdHJldHVybiBbe1xuXHRcdFx0XHRuYW1lOiBcImJpdHNcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAxMixcblx0XHRcdFx0bWluVmFsdWU6IDEsXG5cdFx0XHRcdG1heFZhbHVlOiAxNixcblx0XHRcdFx0YXV0b21hdGlvblJhdGU6ICdrLXJhdGUnXG5cdFx0XHR9XTtcblx0XHR9XG5cblx0XHRnZW5lcmF0ZShpbnB1dCwgX2NoYW5uZWwsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IHN0ZXAgPSBNYXRoLnBvdygwLjUsIHBhcmFtZXRlcnMuYml0cyAtIDEpO1xuXHRcdFx0Y29uc3QgdmFsID0gc3RlcCAqIE1hdGguZmxvb3IoaW5wdXQgLyBzdGVwICsgMC41KTtcblx0XHRcdHJldHVybiB2YWw7XG5cdFx0fVxuXHR9XG5gO1xucmVnaXN0ZXJQcm9jZXNzb3Iod29ya2xldE5hbWUsIGJpdENydXNoZXJXb3JrbGV0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpdENydXNoZXIud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Xb3JrbGV0IH0gZnJvbSBcIi4uL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0XCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyB3b3JrbGV0TmFtZSB9IGZyb20gXCIuL0JpdENydXNoZXIud29ya2xldFwiO1xuLyoqXG4gKiBCaXRDcnVzaGVyIGRvd24tc2FtcGxlcyB0aGUgaW5jb21pbmcgc2lnbmFsIHRvIGEgZGlmZmVyZW50IGJpdCBkZXB0aC5cbiAqIExvd2VyaW5nIHRoZSBiaXQgZGVwdGggb2YgdGhlIHNpZ25hbCBjcmVhdGVzIGRpc3RvcnRpb24uIFJlYWQgbW9yZSBhYm91dCBCaXRDcnVzaGluZ1xuICogb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQml0Y3J1c2hlcikuXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6ZSBjcnVzaGVyIGFuZCByb3V0ZSBhIHN5bnRoIHRocm91Z2ggaXRcbiAqIGNvbnN0IGNydXNoZXIgPSBuZXcgVG9uZS5CaXRDcnVzaGVyKDQpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS5jb25uZWN0KGNydXNoZXIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCAyKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBCaXRDcnVzaGVyIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJpdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJCaXRDcnVzaGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYml0c1wiXSk7XG4gICAgICAgIHRoaXMuX2JpdENydXNoZXJXb3JrbGV0ID0gbmV3IEJpdENydXNoZXJXb3JrbGV0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGJpdHM6IG9wdGlvbnMuYml0cyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX2JpdENydXNoZXJXb3JrbGV0KTtcbiAgICAgICAgdGhpcy5iaXRzID0gdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQuYml0cztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYml0czogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEludGVybmFsIGNsYXNzIHdoaWNoIGNyZWF0ZXMgYW4gQXVkaW9Xb3JrbGV0IHRvIGRvIHRoZSBiaXQgY3J1c2hpbmdcbiAqL1xuY2xhc3MgQml0Q3J1c2hlcldvcmtsZXQgZXh0ZW5kcyBUb25lQXVkaW9Xb3JrbGV0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlcldvcmtsZXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQml0Q3J1c2hlcldvcmtsZXRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXJXb3JrbGV0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5iaXRzID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmJpdHMsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgbWluVmFsdWU6IDEsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMTYsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZHVtbXlQYXJhbSxcbiAgICAgICAgICAgIHN3YXBwYWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvV29ya2xldC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiaXRzOiAxMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9hdWRpb1dvcmtsZXROYW1lKCkge1xuICAgICAgICByZXR1cm4gd29ya2xldE5hbWU7XG4gICAgfVxuICAgIG9uUmVhZHkobm9kZSkge1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIG5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29uc3QgYml0cyA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJiaXRzXCIpO1xuICAgICAgICB0aGlzLmJpdHMuc2V0UGFyYW0oYml0cyk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5iaXRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Qml0Q3J1c2hlci5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuLi9zaWduYWwvV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBDaGVieXNoZXYgaXMgYSB3YXZlc2hhcGVyIHdoaWNoIGlzIGdvb2RcbiAqIGZvciBtYWtpbmcgZGlmZmVyZW50IHR5cGVzIG9mIGRpc3RvcnRpb24gc291bmRzLlxuICogTm90ZSB0aGF0IG9kZCBvcmRlcnMgc291bmQgdmVyeSBkaWZmZXJlbnQgZnJvbSBldmVuIG9uZXMsXG4gKiBhbmQgb3JkZXIgPSAxIGlzIG5vIGNoYW5nZS5cbiAqIFJlYWQgbW9yZSBhdCBbbXVzaWMuY29sdW1iaWEuZWR1XShodHRwOi8vbXVzaWMuY29sdW1iaWEuZWR1L2NtYy9tdXNpY2FuZGNvbXB1dGVycy9jaGFwdGVyNC8wNF8wNi5waHApLlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhIG5ldyBjaGVieVxuICogY29uc3QgY2hlYnkgPSBuZXcgVG9uZS5DaGVieXNoZXYoNTApLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIGNyZWF0ZSBhIG1vbm9zeW50aCBjb25uZWN0ZWQgdG8gb3VyIGNoZWJ5XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1vbm9TeW50aCgpLmNvbm5lY3QoY2hlYnkpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCAwLjQpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQ2hlYnlzaGV2IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hlYnlzaGV2LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib3JkZXJcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDaGVieXNoZXZcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENoZWJ5c2hldi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9yZGVyXCJdKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbGVuZ3RoOiA0MDk2XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9vcmRlciA9IG9wdGlvbnMub3JkZXI7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9zaGFwZXIpO1xuICAgICAgICB0aGlzLm9yZGVyID0gb3B0aW9ucy5vcmRlcjtcbiAgICAgICAgdGhpcy5vdmVyc2FtcGxlID0gb3B0aW9ucy5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBvcmRlcjogMSxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6IFwibm9uZVwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIGNvZWZmaWNpZW50IGZvciB0aGF0IGRlZ3JlZVxuICAgICAqIEBwYXJhbSAgeCB0aGUgeCB2YWx1ZVxuICAgICAqIEBwYXJhbSAgZGVncmVlXG4gICAgICogQHBhcmFtICBtZW1vIG1lbW9pemUgdGhlIGNvbXB1dGVkIHZhbHVlLiB0aGlzIHNwZWVkcyB1cCBjb21wdXRhdGlvbiBncmVhdGx5LlxuICAgICAqL1xuICAgIF9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUsIG1lbW8pIHtcbiAgICAgICAgaWYgKG1lbW8uaGFzKGRlZ3JlZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBtZW1vLmdldChkZWdyZWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRlZ3JlZSA9PT0gMCkge1xuICAgICAgICAgICAgbWVtby5zZXQoZGVncmVlLCAwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZWdyZWUgPT09IDEpIHtcbiAgICAgICAgICAgIG1lbW8uc2V0KGRlZ3JlZSwgeCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtZW1vLnNldChkZWdyZWUsIDIgKiB4ICogdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlIC0gMSwgbWVtbykgLSB0aGlzLl9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUgLSAyLCBtZW1vKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW8uZ2V0KGRlZ3JlZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvcmRlciBvZiB0aGUgQ2hlYnlzaGV2IHBvbHlub21pYWwgd2hpY2ggY3JlYXRlcyB0aGUgZXF1YXRpb24gd2hpY2ggaXMgYXBwbGllZCB0byB0aGUgaW5jb21pbmdcbiAgICAgKiBzaWduYWwgdGhyb3VnaCBhIFRvbmUuV2F2ZVNoYXBlci4gVGhlIGVxdWF0aW9ucyBhcmUgaW4gdGhlIGZvcm06XG4gICAgICogYGBgXG4gICAgICogb3JkZXIgMjogMnheMiArIDFcbiAgICAgKiBvcmRlciAzOiA0eF4zICsgM3hcbiAgICAgKiBgYGBcbiAgICAgKiBAbWluIDFcbiAgICAgKiBAbWF4IDEwMFxuICAgICAqL1xuICAgIGdldCBvcmRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29yZGVyO1xuICAgIH1cbiAgICBzZXQgb3JkZXIob3JkZXIpIHtcbiAgICAgICAgdGhpcy5fb3JkZXIgPSBvcmRlcjtcbiAgICAgICAgdGhpcy5fc2hhcGVyLnNldE1hcCgoeCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgb3JkZXIsIG5ldyBNYXAoKSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG92ZXJzYW1wbGluZyBvZiB0aGUgZWZmZWN0LiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaGVieXNoZXYuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIFNwbGl0IHNwbGl0cyBhbiBpbmNvbWluZyBzaWduYWwgaW50byB0aGUgbnVtYmVyIG9mIGdpdmVuIGNoYW5uZWxzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzcGxpdCA9IG5ldyBUb25lLlNwbGl0KCk7XG4gKiAvLyBzdGVyZW9TaWduYWwuY29ubmVjdChzcGxpdCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3BsaXRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pO1xuICAgICAgICB0aGlzLl9zcGxpdHRlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIob3B0aW9ucy5jaGFubmVscyk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fc3BsaXR0ZXJdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1lcmdlIGJyaW5ncyBtdWx0aXBsZSBtb25vIGlucHV0IGNoYW5uZWxzIGludG8gYSBzaW5nbGUgbXVsdGljaGFubmVsIG91dHB1dCBjaGFubmVsLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXJnZSA9IG5ldyBUb25lLk1lcmdlKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcm91dGluZyBhIHNpbmUgdG9uZSBpbiB0aGUgbGVmdCBjaGFubmVsXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChtZXJnZSwgMCwgMCkuc3RhcnQoKTtcbiAqIC8vIGFuZCBub2lzZSBpbiB0aGUgcmlnaHQgY2hhbm5lbFxuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLmNvbm5lY3QobWVyZ2UsIDAsIDEpLnN0YXJ0KCk7O1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWVyZ2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1lcmdlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXJnZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKTtcbiAgICAgICAgdGhpcy5fbWVyZ2VyID0gdGhpcy5vdXRwdXQgPSB0aGlzLmlucHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIob3B0aW9ucy5jaGFubmVscyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2VyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWVyZ2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCwgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIFN0ZXJlbyBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvRWZmZWN0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGVyZW9FZmZlY3RcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBmb3JjZSBtb25vIHNvdXJjZXMgdG8gYmUgc3RlcmVvXG4gICAgICAgIHRoaXMuaW5wdXQuY2hhbm5lbENvdW50ID0gMjtcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICB0aGlzLl9kcnlXZXQgPSB0aGlzLm91dHB1dCA9IG5ldyBDcm9zc0ZhZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZmFkZTogb3B0aW9ucy53ZXRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gbmV3IFNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICAvLyBkcnkgd2V0IGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9kcnlXZXQuYSk7XG4gICAgICAgIHRoaXMuX21lcmdlLmNvbm5lY3QodGhpcy5fZHJ5V2V0LmIpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3ZXRcIl0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBsZWZ0IHBhcnQgb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RMZWZ0KC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3Qobm9kZXNbMF0sIDAsIDApO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLm5vZGVzKTtcbiAgICAgICAgY29ubmVjdChub2Rlc1tub2Rlcy5sZW5ndGggLSAxXSwgdGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSByaWdodCBwYXJ0IG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0UmlnaHQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdChub2Rlc1swXSwgMSwgMCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXMoLi4ubm9kZXMpO1xuICAgICAgICBjb25uZWN0KG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdLCB0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3ZXQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RyeVdldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHN0ZXJlbyBmZWVkYmFjayBlZmZlY3RzIHdoZXJlIHRoZSBlZmZlY3RSZXR1cm4gaXMgZmVkIGJhY2sgaW50byB0aGUgc2FtZSBjaGFubmVsLlxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZlZWRiYWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0ID0gbmV3IFNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tTcGxpdCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIGxlZnQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTCwgMCwgMCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDApO1xuICAgICAgICAvLyB0aGUgcmlnaHQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrUiwgMSwgMCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDEpO1xuICAgICAgICAvLyB0aGUgZmVlZGJhY2sgY29udHJvbFxuICAgICAgICB0aGlzLmZlZWRiYWNrLmZhbih0aGlzLl9mZWVkYmFja0wuZ2FpbiwgdGhpcy5fZmVlZGJhY2tSLmdhaW4pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmZWVkYmFja1wiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb0ZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9TdGVyZW9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ2hvcnVzIGlzIGEgc3RlcmVvIGNob3J1cyBlZmZlY3QgY29tcG9zZWQgb2YgYSBsZWZ0IGFuZCByaWdodCBkZWxheSB3aXRoIGFuIFtbTEZPXV0gYXBwbGllZCB0byB0aGUgZGVsYXlUaW1lIG9mIGVhY2ggY2hhbm5lbC5cbiAqIFdoZW4gW1tmZWVkYmFja11dIGlzIHNldCB0byBhIHZhbHVlIGxhcmdlciB0aGFuIDAsIHlvdSBhbHNvIGdldCBGbGFuZ2VyLXR5cGUgZWZmZWN0cy5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hL2Jsb2IvbWFzdGVyL3R1bmEuanMpLlxuICogUmVhZCBtb3JlIG9uIHRoZSBjaG9ydXMgZWZmZWN0IG9uIFtTb3VuZE9uU291bmRdKGh0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvanVuMDQvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNob3J1cyA9IG5ldyBUb25lLkNob3J1cyg0LCAyLjUsIDAuNSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCgpLmNvbm5lY3QoY2hvcnVzKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkMzXCIsIFwiRTNcIiwgXCJHM1wiXSwgXCI4blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDaG9ydXMgZXh0ZW5kcyBTdGVyZW9GZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENob3J1cy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlbGF5VGltZVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hvcnVzXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDaG9ydXMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZWxheVRpbWVcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuX2RlcHRoID0gb3B0aW9ucy5kZXB0aDtcbiAgICAgICAgdGhpcy5fZGVsYXlUaW1lID0gb3B0aW9ucy5kZWxheVRpbWUgLyAxMDAwO1xuICAgICAgICB0aGlzLl9sZm9MID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIHBoYXNlOiAxODBcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwgPSBuZXcgRGVsYXkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZVIgPSBuZXcgRGVsYXkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvTC5mcmVxdWVuY3k7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIC8vIGhhdmUgb25lIExGTyBmcmVxdWVuY3kgY29udHJvbCB0aGUgb3RoZXJcbiAgICAgICAgdGhpcy5fbGZvTC5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fZGVsYXlOb2RlTCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KHRoaXMuX2RlbGF5Tm9kZVIpO1xuICAgICAgICAvLyBsZm8gc2V0dXBcbiAgICAgICAgdGhpcy5fbGZvTC5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZUwuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZVIuZGVsYXlUaW1lKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlc1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fZGVwdGg7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9GZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEuNSxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMy41LFxuICAgICAgICAgICAgZGVwdGg6IDAuNyxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgc3ByZWFkOiAxODAsXG4gICAgICAgICAgICBmZWVkYmFjazogMCxcbiAgICAgICAgICAgIHdldDogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRlcHRoIG9mIHRoZSBlZmZlY3QuIEEgZGVwdGggb2YgMSBtYWtlcyB0aGUgZGVsYXlUaW1lXG4gICAgICogbW9kdWxhdGUgYmV0d2VlbiAwIGFuZCAyKmRlbGF5VGltZSAoY2VudGVyZWQgYXJvdW5kIHRoZSBkZWxheVRpbWUpLlxuICAgICAqL1xuICAgIGdldCBkZXB0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlcHRoO1xuICAgIH1cbiAgICBzZXQgZGVwdGgoZGVwdGgpIHtcbiAgICAgICAgdGhpcy5fZGVwdGggPSBkZXB0aDtcbiAgICAgICAgY29uc3QgZGV2aWF0aW9uID0gdGhpcy5fZGVsYXlUaW1lICogZGVwdGg7XG4gICAgICAgIHRoaXMuX2xmb0wubWluID0gTWF0aC5tYXgodGhpcy5fZGVsYXlUaW1lIC0gZGV2aWF0aW9uLCAwKTtcbiAgICAgICAgdGhpcy5fbGZvTC5tYXggPSB0aGlzLl9kZWxheVRpbWUgKyBkZXZpYXRpb247XG4gICAgICAgIHRoaXMuX2xmb1IubWluID0gTWF0aC5tYXgodGhpcy5fZGVsYXlUaW1lIC0gZGV2aWF0aW9uLCAwKTtcbiAgICAgICAgdGhpcy5fbGZvUi5tYXggPSB0aGlzLl9kZWxheVRpbWUgKyBkZXZpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZWxheVRpbWUgaW4gbWlsbGlzZWNvbmRzIG9mIHRoZSBjaG9ydXMuIEEgbGFyZ2VyIGRlbGF5VGltZVxuICAgICAqIHdpbGwgZ2l2ZSBhIG1vcmUgcHJvbm91bmNlZCBlZmZlY3QuIE5vbWluYWwgcmFuZ2UgYSBkZWxheVRpbWVcbiAgICAgKiBpcyBiZXR3ZWVuIDIgYW5kIDIwbXMuXG4gICAgICovXG4gICAgZ2V0IGRlbGF5VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlbGF5VGltZSAqIDEwMDA7XG4gICAgfVxuICAgIHNldCBkZWxheVRpbWUoZGVsYXlUaW1lKSB7XG4gICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IGRlbGF5VGltZSAvIDEwMDA7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9kZXB0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZSBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvTC50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cbiAgICAgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTtcbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5waGFzZSA9IDkwIC0gKHNwcmVhZCAvIDIpO1xuICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gKHNwcmVhZCAvIDIpICsgOTA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBlZmZlY3QuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbGZvXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZmlsdGVyIHRvIHRoZSB0cmFuc3BvcnQuIFNlZSBbW0xGTy5zeW5jXV1cbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnVuc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaG9ydXMuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4uL3NpZ25hbC9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbi8qKlxuICogQSBzaW1wbGUgZGlzdG9ydGlvbiBlZmZlY3QgdXNpbmcgVG9uZS5XYXZlU2hhcGVyLlxuICogQWxnb3JpdGhtIGZyb20gW3RoaXMgc3RhY2tvdmVyZmxvdyBhbnN3ZXJdKGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyMzEzNDA4KS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZGlzdCA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC44KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBmbSA9IG5ldyBUb25lLkZNU3ludGgoKS5jb25uZWN0KGRpc3QpO1xuICogZm0udHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBMVwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRGlzdG9ydGlvbiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKERpc3RvcnRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkaXN0b3J0aW9uXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGlzdG9ydGlvblwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGlzdG9ydGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRpc3RvcnRpb25cIl0pO1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsZW5ndGg6IDQwOTYsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gb3B0aW9ucy5kaXN0b3J0aW9uO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fc2hhcGVyKTtcbiAgICAgICAgdGhpcy5kaXN0b3J0aW9uID0gb3B0aW9ucy5kaXN0b3J0aW9uO1xuICAgICAgICB0aGlzLm92ZXJzYW1wbGUgPSBvcHRpb25zLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRpc3RvcnRpb246IDAuNCxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6IFwibm9uZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiBkaXN0b3J0aW9uLiBOb21pbmFsIHJhbmdlIGlzIGJldHdlZW4gMCBhbmQgMS5cbiAgICAgKi9cbiAgICBnZXQgZGlzdG9ydGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3RvcnRpb247XG4gICAgfVxuICAgIHNldCBkaXN0b3J0aW9uKGFtb3VudCkge1xuICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gYW1vdW50O1xuICAgICAgICBjb25zdCBrID0gYW1vdW50ICogMTAwO1xuICAgICAgICBjb25zdCBkZWcgPSBNYXRoLlBJIC8gMTgwO1xuICAgICAgICB0aGlzLl9zaGFwZXIuc2V0TWFwKCh4KSA9PiB7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoeCkgPCAwLjAwMSkge1xuICAgICAgICAgICAgICAgIC8vIHNob3VsZCBvdXRwdXQgMCB3aGVuIGlucHV0IGlzIDBcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAoMyArIGspICogeCAqIDIwICogZGVnIC8gKE1hdGguUEkgKyBrICogTWF0aC5hYnMoeCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG92ZXJzYW1wbGluZyBvZiB0aGUgZWZmZWN0LiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EaXN0b3J0aW9uLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuLyoqXG4gKiBGZWVkYmFja0VmZmVjdCBwcm92aWRlcyBhIGxvb3AgYmV0d2VlbiBhbiBhdWRpbyBzb3VyY2UgYW5kIGl0cyBvd24gb3V0cHV0LlxuICogVGhpcyBpcyBhIGJhc2UtY2xhc3MgZm9yIGZlZWRiYWNrIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0VmZmVjdCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0VmZmVjdFwiO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0dhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmZlZWRiYWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSB0aGlzLl9mZWVkYmFja0dhaW4uZ2FpbjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmZWVkYmFja1wiKTtcbiAgICAgICAgLy8gdGhlIGZlZWRiYWNrIGxvb3BcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY2hhaW4odGhpcy5fZmVlZGJhY2tHYWluLCB0aGlzLmVmZmVjdFNlbmQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmZWVkYmFjazogMC4xMjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9GZWVkYmFja0VmZmVjdFwiO1xuLyoqXG4gKiBGZWVkYmFja0RlbGF5IGlzIGEgRGVsYXlOb2RlIGluIHdoaWNoIHBhcnQgb2Ygb3V0cHV0IHNpZ25hbCBpcyBmZWQgYmFjayBpbnRvIHRoZSBkZWxheS5cbiAqXG4gKiBAcGFyYW0gZGVsYXlUaW1lIFRoZSBkZWxheSBhcHBsaWVkIHRvIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBAcGFyYW0gZmVlZGJhY2sgVGhlIGFtb3VudCBvZiB0aGUgZWZmZWN0ZWQgc2lnbmFsIHdoaWNoIGlzIGZlZCBiYWNrIHRocm91Z2ggdGhlIGRlbGF5LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZlZWRiYWNrRGVsYXkgPSBuZXcgVG9uZS5GZWVkYmFja0RlbGF5KFwiOG5cIiwgMC41KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCB0b20gPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKHtcbiAqIFx0b2N0YXZlczogNCxcbiAqIFx0cGl0Y2hEZWNheTogMC4xXG4gKiB9KS5jb25uZWN0KGZlZWRiYWNrRGVsYXkpO1xuICogdG9tLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTJcIiwgXCIzMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0RlbGF5IGV4dGVuZHMgRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0RlbGF5XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9kZWxheU5vZGUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMjUsXG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0RlbGF5LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogUGhhc2VTaGlmdEFsbHBhc3MgaXMgYW4gdmVyeSBlZmZpY2llbnQgaW1wbGVtZW50YXRpb24gb2YgYSBIaWxiZXJ0IFRyYW5zZm9ybVxuICogdXNpbmcgdHdvIEFsbHBhc3MgZmlsdGVyIGJhbmtzIHdob3NlIG91dHB1dHMgaGF2ZSBhIHBoYXNlIGRpZmZlcmVuY2Ugb2YgOTDCsC5cbiAqIEhlcmUgdGhlIGBvZmZzZXQ5MGAgcGhhc2UgaXMgb2Zmc2V0IGJ5ICs5MMKwIGluIHJlbGF0aW9uIHRvIGBvdXRwdXRgLlxuICogQ29lZmZpY2llbnRzIGFuZCBzdHJ1Y3R1cmUgd2FzIGRldmVsb3BlZCBieSBPbGxpIE5pZW1pdGFsby5cbiAqIEZvciBtb3JlIGRldGFpbHMgc2VlOiBodHRwOi8veWVoYXIuY29tL2Jsb2cvP3A9MzY4XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQaGFzZVNoaWZ0QWxscGFzcyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGhhc2VTaGlmdEFsbHBhc3NcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBoYXNlIHNoaWZ0ZWQgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIFBoYXNlU2hpZnRlZCBhbGxwYXNzIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vZmZzZXQ5MCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICBjb25zdCBhbGxwYXNzQmFuazFWYWx1ZXMgPSBbMC42OTIzODc4LCAwLjkzNjA2NTQzMjI5NTksIDAuOTg4MjI5NTIyNjg2MCwgMC45OTg3NDg4NDUyNzM3XTtcbiAgICAgICAgY29uc3QgYWxscGFzc0JhbmsyVmFsdWVzID0gWzAuNDAyMTkyMTE2MjQyNiwgMC44NTYxNzEwODgyNDIwLCAwLjk3MjI5MDk1NDU2NTEsIDAuOTk1Mjg4NDc5MTI3OF07XG4gICAgICAgIHRoaXMuX2JhbmswID0gdGhpcy5fY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYWxscGFzc0JhbmsxVmFsdWVzKTtcbiAgICAgICAgdGhpcy5fYmFuazEgPSB0aGlzLl9jcmVhdGVBbGxQYXNzRmlsdGVyQmFuayhhbGxwYXNzQmFuazJWYWx1ZXMpO1xuICAgICAgICB0aGlzLl9vbmVTYW1wbGVEZWxheSA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoWzAuMCwgMS4wXSwgWzEuMCwgMC4wXSk7XG4gICAgICAgIC8vIGNvbm5lY3QgQWxscGFzcyBmaWx0ZXIgYmFua3NcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9iYW5rMCwgdGhpcy5fb25lU2FtcGxlRGVsYXksIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9iYW5rMSwgdGhpcy5vZmZzZXQ5MCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbGwgb2YgdGhlIElJUiBmaWx0ZXJzIGZyb20gYW4gYXJyYXkgb2YgdmFsdWVzIHVzaW5nIHRoZSBjb2VmZmljaWVudCBjYWxjdWxhdGlvbi5cbiAgICAgKi9cbiAgICBfY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYmFua1ZhbHVlcykge1xuICAgICAgICBjb25zdCBub2RlcyA9IGJhbmtWYWx1ZXMubWFwKHZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvZWZmaWNpZW50cyA9IFtbdmFsdWUgKiB2YWx1ZSwgMCwgLTFdLCBbMSwgMCwgLSh2YWx1ZSAqIHZhbHVlKV1dO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoY29lZmZpY2llbnRzWzBdLCBjb2VmZmljaWVudHNbMV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub2Zmc2V0OTAuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iYW5rMC5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9iYW5rMS5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9vbmVTYW1wbGVEZWxheS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBoYXNlU2hpZnRBbGxwYXNzLmpzLm1hcCIsImltcG9ydCB7IFBoYXNlU2hpZnRBbGxwYXNzIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvUGhhc2VTaGlmdEFsbHBhc3NcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IE5lZ2F0ZSB9IGZyb20gXCIuLi9zaWduYWwvTmVnYXRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBUb25lT3NjaWxsYXRvck5vZGUgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG4vKipcbiAqIEZyZXF1ZW5jeVNoaWZ0ZXIgY2FuIGJlIHVzZWQgdG8gc2hpZnQgYWxsIGZyZXF1ZW5jaWVzIG9mIGEgc2lnbmFsIGJ5IGEgZml4ZWQgYW1vdW50LlxuICogVGhlIGFtb3VudCBjYW4gYmUgY2hhbmdlZCBhdCBhdWRpbyByYXRlIGFuZCB0aGUgZWZmZWN0IGlzIGFwcGxpZWQgaW4gcmVhbCB0aW1lLlxuICogVGhlIGZyZXF1ZW5jeSBzaGlmdGluZyBpcyBpbXBsZW1lbnRlZCB3aXRoIGEgdGVjaG5pcXVlIGNhbGxlZCBzaW5nbGUgc2lkZSBiYW5kIG1vZHVsYXRpb24gdXNpbmcgYSByaW5nIG1vZHVsYXRvci5cbiAqIE5vdGU6IENvbnRyYXJ5IHRvIHBpdGNoIHNoaWZ0aW5nLCBhbGwgZnJlcXVlbmNpZXMgYXJlIHNoaWZ0ZWQgYnkgdGhlIHNhbWUgYW1vdW50LFxuICogZGVzdHJveWluZyB0aGUgaGFybW9uaWMgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlbS4gVGhpcyBsZWFkcyB0byB0aGUgY2xhc3NpYyByaW5nIG1vZHVsYXRvciB0aW1icmUgZGlzdG9ydGlvbi5cbiAqIFRoZSBhbGdvcml0aG0gd2lsbCBwcm9kdWNlcyBzb21lIGFsaWFzaW5nIHRvd2FyZHMgdGhlIGhpZ2ggZW5kLCBlc3BlY2lhbGx5IGlmIHlvdXIgc291cmNlIG1hdGVyaWFsXG4gKiBjb250YWlucyBhIGxvdCBvZiBoaWdoIGZyZXF1ZW5jaWVzLiBVbmZvcnR1bmF0ZWxseSB0aGUgd2ViYXVkaW8gQVBJIGRvZXMgbm90IHN1cHBvcnQgcmVzYW1wbGluZ1xuICogYnVmZmVycyBpbiByZWFsIHRpbWUsIHNvIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBmaXggaXQgcHJvcGVybHkuIERlcGVuZGluZyBvbiB0aGUgdXNlIGNhc2UgaXQgbWlnaHRcbiAqIGJlIGFuIG9wdGlvbiB0byBsb3cgcGFzcyBmaWx0ZXIgeW91ciBpbnB1dCBiZWZvcmUgZnJlcXVlbmN5IHNoaWZ0aW5nIGl0IHRvIGdldCByaWRlIG9mIHRoZSBhbGlhc2luZy5cbiAqIFlvdSBjYW4gZmluZCBhIHZlcnkgZGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhlIGFsZ29yaXRobSBoZXJlOiBodHRwczovL2xhcnplaXRsaW4uZ2l0aHViLmlvL1JNRlMvXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGlucHV0ID0gbmV3IFRvbmUuT3NjaWxsYXRvcigyMzAsIFwic2F3dG9vdGhcIikuc3RhcnQoKTtcbiAqIGNvbnN0IHNoaWZ0ID0gbmV3IFRvbmUuRnJlcXVlbmN5U2hpZnRlcig0MikudG9EZXN0aW5hdGlvbigpO1xuICogaW5wdXQuY29ubmVjdChzaGlmdCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVxdWVuY3lTaGlmdGVyIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5U2hpZnRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeVNoaWZ0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeVNoaWZ0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW5WYWx1ZTogLXRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMixcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaW5lID0gbmV3IFRvbmVPc2NpbGxhdG9yTm9kZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZSA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBoYXNlOiAtOTAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseSA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY29zaW5lTXVsdGlwbHkgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZSA9IG5ldyBOZWdhdGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2FkZCA9IG5ldyBBZGQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlciA9IG5ldyBQaGFzZVNoaWZ0QWxscGFzcyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNvbm5lY3QodGhpcy5fcGhhc2VTaGlmdGVyKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgY2FycmllciBmcmVxdWVuY3kgc2lnbmFsIHRvIHRoZSB0d28gb3NjaWxsYXRvcnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZmFuKHRoaXMuX3NpbmUuZnJlcXVlbmN5LCB0aGlzLl9jb3NpbmUuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLm9mZnNldDkwLmNvbm5lY3QodGhpcy5fY29zaW5lTXVsdGlwbHkpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuY29ubmVjdCh0aGlzLl9jb3NpbmVNdWx0aXBseS5mYWN0b3IpO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIuY29ubmVjdCh0aGlzLl9zaW5lTXVsdGlwbHkpO1xuICAgICAgICB0aGlzLl9zaW5lLmNvbm5lY3QodGhpcy5fc2luZU11bHRpcGx5LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseS5jb25uZWN0KHRoaXMuX25lZ2F0ZSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5LmNvbm5lY3QodGhpcy5fYWRkKTtcbiAgICAgICAgdGhpcy5fbmVnYXRlLmNvbm5lY3QodGhpcy5fYWRkLmFkZGVuZCk7XG4gICAgICAgIHRoaXMuX2FkZC5jb25uZWN0KHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG9zY2lsbGF0b3JzIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5pbW1lZGlhdGUoKTtcbiAgICAgICAgdGhpcy5fc2luZS5zdGFydChub3cpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuc3RhcnQobm93KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nvc2luZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbmVnYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2luZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeVNoaWZ0ZXIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBMb3dwYXNzQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyXCI7XG4vKipcbiAqIEFuIGFycmF5IG9mIGNvbWIgZmlsdGVyIGRlbGF5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJUdW5pbmdzID0gWzE1NTcgLyA0NDEwMCwgMTYxNyAvIDQ0MTAwLCAxNDkxIC8gNDQxMDAsIDE0MjIgLyA0NDEwMCwgMTI3NyAvIDQ0MTAwLCAxMzU2IC8gNDQxMDAsIDExODggLyA0NDEwMCwgMTExNiAvIDQ0MTAwXTtcbi8qKlxuICogQW4gYXJyYXkgb2YgYWxscGFzcyBmaWx0ZXIgZnJlcXVlbmN5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG4gKi9cbmNvbnN0IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcyA9IFsyMjUsIDU1NiwgNDQxLCAzNDFdO1xuLyoqXG4gKiBGcmVldmVyYiBpcyBhIHJldmVyYiBiYXNlZCBvbiBbRnJlZXZlcmJdKGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L35qb3MvcGFzcC9GcmVldmVyYi5odG1sKS5cbiAqIFJlYWQgbW9yZSBvbiByZXZlcmIgb24gW1NvdW5kIE9uIFNvdW5kXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDQwODM5MDIvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tOjgwL3Nvcy9mZWIwMS9hcnRpY2xlcy9zeW50aHNlY3JldHMuYXNwKS5cbiAqIEZyZWV2ZXJiIGlzIG5vdyBpbXBsZW1lbnRlZCB3aXRoIGFuIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggbWF5IHJlc3VsdCBvbiBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbiBvbiBzb21lIHBsYXRmb3Jtcy4gQ29uc2lkZXIgdXNpbmcgW1tSZXZlcmJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmcmVldmVyYiA9IG5ldyBUb25lLkZyZWV2ZXJiKCkudG9EZXN0aW5hdGlvbigpO1xuICogZnJlZXZlcmIuZGFtcGVuaW5nID0gMTAwMDtcbiAqIC8vIHJvdXRpbmcgc3ludGggdGhyb3VnaCB0aGUgcmV2ZXJiXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS5jb25uZWN0KGZyZWV2ZXJiKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuMDUpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRnJlZXZlcmIgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCIsIFwiZGFtcGVuaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlZXZlcmJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBjb21iIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSBsZWZ0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1IgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZWV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIiwgXCJkYW1wZW5pbmdcIl0pO1xuICAgICAgICB0aGlzLnJvb21TaXplID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yb29tU2l6ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTCA9IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzTCA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3NMLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIGFsbHBhc3NMLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzc0w7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIGxlZnRcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSID0gYWxscGFzc0ZpbHRlckZyZXF1ZW5jaWVzLm1hcChmcmVxID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFsbHBhc3NSID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzc1IudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgYWxscGFzc1IuZnJlcXVlbmN5LnZhbHVlID0gZnJlcTtcbiAgICAgICAgICAgIHJldHVybiBhbGxwYXNzUjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGNvbWIgZmlsdGVyc1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycyA9IGNvbWJGaWx0ZXJUdW5pbmdzLm1hcCgoZGVsYXlUaW1lLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGZwZiA9IG5ldyBMb3dwYXNzQ29tYkZpbHRlcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGRhbXBlbmluZzogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBjb21iRmlsdGVyVHVuaW5ncy5sZW5ndGggLyAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdChsZnBmLCAuLi50aGlzLl9hbGxwYXNzRmlsdGVyc0wpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQobGZwZiwgLi4udGhpcy5fYWxscGFzc0ZpbHRlcnNSKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdChsZnBmLnJlc29uYW5jZSk7XG4gICAgICAgICAgICByZXR1cm4gbGZwZjtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInJvb21TaXplXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcm9vbVNpemU6IDAuNyxcbiAgICAgICAgICAgIGRhbXBlbmluZzogMzAwMFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiBkYW1wZW5pbmcgb2YgdGhlIHJldmVyYmVyYW50IHNpZ25hbC5cbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tYkZpbHRlcnNbMF0uZGFtcGVuaW5nO1xuICAgIH1cbiAgICBzZXQgZGFtcGVuaW5nKGQpIHtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMuZm9yRWFjaChjID0+IGMuZGFtcGVuaW5nID0gZCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMLmZvckVhY2goYWwgPT4gYWwuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSLmZvckVhY2goYXIgPT4gYXIuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMuZm9yRWFjaChjZiA9PiBjZi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLnJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZlZWRiYWNrQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBhbiBhcnJheSBvZiB0aGUgY29tYiBmaWx0ZXIgZGVsYXkgdGltZSB2YWx1ZXNcbiAqL1xuY29uc3QgY29tYkZpbHRlckRlbGF5VGltZXMgPSBbMTY4NyAvIDI1MDAwLCAxNjAxIC8gMjUwMDAsIDIwNTMgLyAyNTAwMCwgMjI1MSAvIDI1MDAwXTtcbi8qKlxuICogdGhlIHJlc29uYW5jZXMgb2YgZWFjaCBvZiB0aGUgY29tYiBmaWx0ZXJzXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJSZXNvbmFuY2VzID0gWzAuNzczLCAwLjgwMiwgMC43NTMsIDAuNzMzXTtcbi8qKlxuICogdGhlIGFsbHBhc3MgZmlsdGVyIGZyZXF1ZW5jaWVzXG4gKi9cbmNvbnN0IGFsbHBhc3NGaWx0ZXJGcmVxcyA9IFszNDcsIDExMywgMzddO1xuLyoqXG4gKiBKQ1JldmVyYiBpcyBhIHNpbXBsZSBbU2Nocm9lZGVyIFJldmVyYmVyYXRvcl0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL1NjaHJvZWRlcl9SZXZlcmJlcmF0b3JzLmh0bWwpXG4gKiB0dW5lZCBieSBKb2huIENob3duaW5nIGluIDE5NzAuXG4gKiBJdCBpcyBtYWRlIHVwIG9mIHRocmVlIGFsbHBhc3MgZmlsdGVycyBhbmQgZm91ciBbW0ZlZWRiYWNrQ29tYkZpbHRlcl1dLlxuICogSkNSZXZlcmIgaXMgbm93IGltcGxlbWVudGVkIHdpdGggYW4gQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBtYXkgcmVzdWx0IG9uIHBlcmZvcm1hbmNlIGRlZ3JhZGF0aW9uIG9uIHNvbWUgcGxhdGZvcm1zLiBDb25zaWRlciB1c2luZyBbW1JldmVyYl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJldmVyYiA9IG5ldyBUb25lLkpDUmV2ZXJiKDAuNCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgZGVsYXkgPSBuZXcgVG9uZS5GZWVkYmFja0RlbGF5KDAuNSk7XG4gKiAvLyBjb25uZWN0aW5nIHRoZSBzeW50aCB0byByZXZlcmIgdGhyb3VnaCBkZWxheVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLmNoYWluKGRlbGF5LCByZXZlcmIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBNFwiLCBcIjhuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEpDUmV2ZXJiIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoSkNSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkpDUmV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhIHNlcmllcyBvZiBhbGxwYXNzIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBwYXJhbGxlbCBmZWVkYmFjayBjb21iIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEpDUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIl0pO1xuICAgICAgICB0aGlzLnJvb21TaXplID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yb29tU2l6ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogLTAuNzMzLFxuICAgICAgICAgICAgbWF4OiAwLjE5NyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGFsbHBhc3MgZmlsdGVyc1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycyA9IGFsbHBhc3NGaWx0ZXJGcmVxcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzcy50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICBhbGxwYXNzLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzcztcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGFuZCB0aGUgY29tYiBmaWx0ZXJzXG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBjb21iRmlsdGVyRGVsYXlUaW1lcy5tYXAoKGRlbGF5VGltZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZiY2YgPSBuZXcgRmVlZGJhY2tDb21iRmlsdGVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmNvbm5lY3QoZmJjZi5yZXNvbmFuY2UpO1xuICAgICAgICAgICAgZmJjZi5yZXNvbmFuY2UudmFsdWUgPSBjb21iRmlsdGVyUmVzb25hbmNlc1tpbmRleF07XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBjb21iRmlsdGVyRGVsYXlUaW1lcy5sZW5ndGggLyAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCguLi50aGlzLl9hbGxwYXNzRmlsdGVycywgZmJjZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCguLi50aGlzLl9hbGxwYXNzRmlsdGVycywgZmJjZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmJjZjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNoYWluIHRoZSBhbGxwYXNzIGZpbHRlcnMgdG9nZXRoZXJcbiAgICAgICAgdGhpcy5yb29tU2l6ZS5jb25uZWN0KHRoaXMuX3NjYWxlUm9vbVNpemUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyb29tU2l6ZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHJvb21TaXplOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzLmZvckVhY2goYXBmID0+IGFwZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzLmZvckVhY2goZmJjZiA9PiBmYmNmLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMucm9vbVNpemUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SkNSZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBKdXN0IGxpa2UgYSBbW1N0ZXJlb0ZlZWRiYWNrRWZmZWN0XV0sIGJ1dCB0aGUgZmVlZGJhY2sgaXMgcm91dGVkIGZyb20gbGVmdCB0byByaWdodFxuICogYW5kIHJpZ2h0IHRvIGxlZnQgaW5zdGVhZCBvZiBvbiB0aGUgc2FtZSBjaGFubmVsLlxuICogYGBgXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIGZlZWRiYWNrTCA8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiArLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0+ICAgICAgICArLS0tLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLStcbiAqICAgICAgZmVlZGJhY2tNZXJnZSArLS0+IHNwbGl0ICAgICAgICAoRUZGRUNUKSAgICAgICBtZXJnZSArLS0+IGZlZWRiYWNrU3BsaXQgICAgIHwgfFxuICogKy0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tPiAgICAgICAgKy0tLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tKyB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgZmVlZGJhY2tSIDwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9YRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBTdGVyZW9GZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLy8gdGhlIGxlZnQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tNZXJnZSwgMCwgMSk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDApO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmZWVkYmFja1wiXSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvWEZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb1hGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb1hGZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBpbmdQb25nRGVsYXkgaXMgYSBmZWVkYmFjayBkZWxheSBlZmZlY3Qgd2hlcmUgdGhlIGVjaG8gaXMgaGVhcmRcbiAqIGZpcnN0IGluIG9uZSBjaGFubmVsIGFuZCBuZXh0IGluIHRoZSBvcHBvc2l0ZSBjaGFubmVsLiBJbiBhIHN0ZXJlb1xuICogc3lzdGVtIHRoZXNlIGFyZSB0aGUgcmlnaHQgYW5kIGxlZnQgY2hhbm5lbHMuXG4gKiBQaW5nUG9uZ0RlbGF5IGluIG1vcmUgc2ltcGxpZmllZCB0ZXJtcyBpcyB0d28gVG9uZS5GZWVkYmFja0RlbGF5c1xuICogd2l0aCBpbmRlcGVuZGVudCBkZWxheSB2YWx1ZXMuIEVhY2ggZGVsYXkgaXMgcm91dGVkIHRvIG9uZSBjaGFubmVsXG4gKiAobGVmdCBvciByaWdodCksIGFuZCB0aGUgY2hhbm5lbCB0cmlnZ2VyZWQgc2Vjb25kIHdpbGwgYWx3YXlzXG4gKiB0cmlnZ2VyIGF0IHRoZSBzYW1lIGludGVydmFsIGFmdGVyIHRoZSBmaXJzdC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwaW5nUG9uZyA9IG5ldyBUb25lLlBpbmdQb25nRGVsYXkoXCI0blwiLCAwLjIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGRydW0gPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKCkuY29ubmVjdChwaW5nUG9uZyk7XG4gKiBkcnVtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCIzMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaW5nUG9uZ0RlbGF5IGV4dGVuZHMgU3RlcmVvWEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGluZ1BvbmdEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGluZ1BvbmdEZWxheVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGluZ1BvbmdEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKTtcbiAgICAgICAgdGhpcy5fbGVmdERlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHREZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9sZWZ0RGVsYXkpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCh0aGlzLl9yaWdodFByZURlbGF5LCB0aGlzLl9yaWdodERlbGF5KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZmFuKHRoaXMuX2xlZnREZWxheS5kZWxheVRpbWUsIHRoaXMuX3JpZ2h0RGVsYXkuZGVsYXlUaW1lLCB0aGlzLl9yaWdodFByZURlbGF5LmRlbGF5VGltZSk7XG4gICAgICAgIC8vIHJlYXJyYW5nZWQgdGhlIGZlZWRiYWNrIHRvIGJlIGFmdGVyIHRoZSByaWdodFByZURlbGF5XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX3JpZ2h0RGVsYXkpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJkZWxheVRpbWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb1hGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMjUsXG4gICAgICAgICAgICBtYXhEZWxheTogMVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0RGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodERlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGluZ1BvbmdEZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL0ZlZWRiYWNrRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbi8qKlxuICogUGl0Y2hTaGlmdCBkb2VzIG5lYXItcmVhbHRpbWUgcGl0Y2ggc2hpZnRpbmcgdG8gdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIFRoZSBlZmZlY3QgaXMgYWNoaWV2ZWQgYnkgc3BlZWRpbmcgdXAgb3Igc2xvd2luZyBkb3duIHRoZSBkZWxheVRpbWVcbiAqIG9mIGEgRGVsYXlOb2RlIHVzaW5nIGEgc2F3dG9vdGggd2F2ZS5cbiAqIEFsZ29yaXRobSBmb3VuZCBpbiBbdGhpcyBwZGZdKGh0dHA6Ly9kc3AtYm9vay5uYXJvZC5ydS9zb3VuZHByb2MucGRmKS5cbiAqIEFkZGl0aW9uYWwgcmVmZXJlbmNlIGJ5IFtNaWxsZXIgUHVja2V0XShodHRwOi8vbXNwLnVjc2QuZWR1L3RlY2huaXF1ZXMvdjAuMTEvYm9vay1odG1sL25vZGUxMTUuaHRtbCkuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaXRjaFNoaWZ0IGV4dGVuZHMgRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQaXRjaFNoaWZ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGl0Y2hcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQaXRjaFNoaWZ0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaXRjaFNoaWZ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGl0Y2hcIl0pO1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9kZWxheUEgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb0EgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fZGVsYXlBLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2RlbGF5QiA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvQiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAwLjEsXG4gICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCIsXG4gICAgICAgICAgICBwaGFzZTogMTgwXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fZGVsYXlCLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZSA9IG5ldyBDcm9zc0ZhZGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgdHlwZTogXCJ0cmlhbmdsZVwiLFxuICAgICAgICAgICAgcGhhc2U6IDkwXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmZhZGUpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0RlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IHRoaXMuX2ZlZWRiYWNrRGVsYXkuZGVsYXlUaW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICAgICAgdGhpcy5fcGl0Y2ggPSBvcHRpb25zLnBpdGNoO1xuICAgICAgICB0aGlzLl93aW5kb3dTaXplID0gb3B0aW9ucy53aW5kb3dTaXplO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSB0d28gZGVsYXkgbGluZXMgdXBcbiAgICAgICAgdGhpcy5fZGVsYXlBLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmEpO1xuICAgICAgICB0aGlzLl9kZWxheUIuY29ubmVjdCh0aGlzLl9jcm9zc0ZhZGUuYik7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLl9mcmVxdWVuY3kuZmFuKHRoaXMuX2xmb0EuZnJlcXVlbmN5LCB0aGlzLl9sZm9CLmZyZXF1ZW5jeSwgdGhpcy5fY3Jvc3NGYWRlTEZPLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHJvdXRlIHRoZSBpbnB1dFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuZmFuKHRoaXMuX2RlbGF5QSwgdGhpcy5fZGVsYXlCKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlLmNoYWluKHRoaXMuX2ZlZWRiYWNrRGVsYXksIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIExGT3MgYXQgdGhlIHNhbWUgdGltZVxuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl9sZm9BLnN0YXJ0KG5vdyk7XG4gICAgICAgIHRoaXMuX2xmb0Iuc3RhcnQobm93KTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPLnN0YXJ0KG5vdyk7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgICAgICB0aGlzLndpbmRvd1NpemUgPSB0aGlzLl93aW5kb3dTaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEZlZWRiYWNrRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBpdGNoOiAwLFxuICAgICAgICAgICAgd2luZG93U2l6ZTogMC4xLFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgZmVlZGJhY2s6IDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGl0Y2ggdGhlIGluY29taW5nIHNpZ25hbCBieSBzb21lIGludGVydmFsIChtZWFzdXJlZCBpbiBzZW1pLXRvbmVzKS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBpdGNoU2hpZnQgPSBuZXcgVG9uZS5QaXRjaFNoaWZ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHBpdGNoU2hpZnQpLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBpdGNoU2hpZnQucGl0Y2ggPSAtMTI7IC8vIGRvd24gb25lIG9jdGF2ZVxuICAgICAqIHBpdGNoU2hpZnQucGl0Y2ggPSA3OyAvLyB1cCBhIGZpZnRoXG4gICAgICovXG4gICAgZ2V0IHBpdGNoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGl0Y2g7XG4gICAgfVxuICAgIHNldCBwaXRjaChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl9waXRjaCA9IGludGVydmFsO1xuICAgICAgICBsZXQgZmFjdG9yID0gMDtcbiAgICAgICAgaWYgKGludGVydmFsIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5taW4gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5tYXggPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5taW4gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5tYXggPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgZmFjdG9yID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsIC0gMSkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5taW4gPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5tYXggPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5taW4gPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5tYXggPSAwO1xuICAgICAgICAgICAgZmFjdG9yID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5LnZhbHVlID0gZmFjdG9yICogKDEuMiAvIHRoaXMuX3dpbmRvd1NpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgd2luZG93IHNpemUgY29ycmVzcG9uZHMgcm91Z2hseSB0byB0aGUgc2FtcGxlIGxlbmd0aCBpbiBhIGxvb3Bpbmcgc2FtcGxlci5cbiAgICAgKiBTbWFsbGVyIHZhbHVlcyBhcmUgZGVzaXJhYmxlIGZvciBhIGxlc3Mgbm90aWNlYWJsZSBkZWxheSB0aW1lIG9mIHRoZSBwaXRjaCBzaGlmdGVkXG4gICAgICogc2lnbmFsLCBidXQgbGFyZ2VyIHZhbHVlcyB3aWxsIHJlc3VsdCBpbiBzbW9vdGhlciBwaXRjaCBzaGlmdGluZyBmb3IgbGFyZ2VyIGludGVydmFscy5cbiAgICAgKiBBIG5vbWluYWwgcmFuZ2Ugb2YgMC4wMyB0byAwLjEgaXMgcmVjb21tZW5kZWQuXG4gICAgICovXG4gICAgZ2V0IHdpbmRvd1NpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93aW5kb3dTaXplO1xuICAgIH1cbiAgICBzZXQgd2luZG93U2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX3dpbmRvd1NpemUgPSB0aGlzLnRvU2Vjb25kcyhzaXplKTtcbiAgICAgICAgdGhpcy5waXRjaCA9IHRoaXMuX3BpdGNoO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5QS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Qi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0EuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9CLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tEZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBpdGNoU2hpZnQuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBoYXNlciBpcyBhIHBoYXNlciBlZmZlY3QuIFBoYXNlcnMgd29yayBieSBjaGFuZ2luZyB0aGUgcGhhc2VcbiAqIG9mIGRpZmZlcmVudCBmcmVxdWVuY3kgY29tcG9uZW50cyBvZiBhbiBpbmNvbWluZyBzaWduYWwuIFJlYWQgbW9yZSBvblxuICogW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUGhhc2VyXyhlZmZlY3QpKS5cbiAqIEluc3BpcmF0aW9uIGZvciB0aGlzIHBoYXNlciBjb21lcyBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYS8pLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBoYXNlciA9IG5ldyBUb25lLlBoYXNlcih7XG4gKiBcdGZyZXF1ZW5jeTogMTUsXG4gKiBcdG9jdGF2ZXM6IDUsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IDEwMDBcbiAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLmNvbm5lY3QocGhhc2VyKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiRTNcIiwgXCIyblwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFBoYXNlciBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBoYXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJiYXNlRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGhhc2VyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaGFzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwiYmFzZUZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDFcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBwaGFzZTogMTgwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNMID0gdGhpcy5fbWFrZUZpbHRlcnMob3B0aW9ucy5zdGFnZXMsIHRoaXMuX2xmb0wpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzUiA9IHRoaXMuX21ha2VGaWx0ZXJzKG9wdGlvbnMuc3RhZ2VzLCB0aGlzLl9sZm9SKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm9MLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kudmFsdWUgPSBvcHRpb25zLmZyZXF1ZW5jeTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGVtIHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQoLi4udGhpcy5fZmlsdGVyc0wpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCguLi50aGlzLl9maWx0ZXJzUik7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIGZyZXF1ZW5jeSB3aXRoIG9uZSBMRk9cbiAgICAgICAgdGhpcy5fbGZvTC5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHNldCB0aGUgb3B0aW9uc1xuICAgICAgICB0aGlzLmJhc2VGcmVxdWVuY3kgPSBvcHRpb25zLmJhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgLy8gc3RhcnQgdGhlIGxmb1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQoKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiUVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMC41LFxuICAgICAgICAgICAgb2N0YXZlczogMyxcbiAgICAgICAgICAgIHN0YWdlczogMTAsXG4gICAgICAgICAgICBROiAxMCxcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9tYWtlRmlsdGVycyhzdGFnZXMsIGNvbm5lY3RUb0ZyZXEpIHtcbiAgICAgICAgY29uc3QgZmlsdGVycyA9IFtdO1xuICAgICAgICAvLyBtYWtlIGFsbCB0aGUgZmlsdGVyc1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YWdlczsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBmaWx0ZXIudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgdGhpcy5RLmNvbm5lY3QoZmlsdGVyLlEpO1xuICAgICAgICAgICAgY29ubmVjdFRvRnJlcS5jb25uZWN0KGZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgZmlsdGVycy5wdXNoKGZpbHRlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbHRlcnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyB0aGUgcGhhc2UgZ29lcyBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeVxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIG9jdGF2ZXMpO1xuICAgICAgICB0aGlzLl9sZm9MLm1heCA9IG1heDtcbiAgICAgICAgdGhpcy5fbGZvUi5tYXggPSBtYXg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aGUgYmFzZSBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlcnMuXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KGZyZXEpO1xuICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2xmb1IubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNMLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNSLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGhhc2VyLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWVyZ2VcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogU2ltcGxlIGNvbnZvbHV0aW9uIGNyZWF0ZWQgd2l0aCBkZWNheWluZyBub2lzZS5cbiAqIEdlbmVyYXRlcyBhbiBJbXB1bHNlIFJlc3BvbnNlIEJ1ZmZlclxuICogd2l0aCBUb25lLk9mZmxpbmUgdGhlbiBmZWVkcyB0aGUgSVIgaW50byBDb252b2x2ZXJOb2RlLlxuICogVGhlIGltcHVsc2UgcmVzcG9uc2UgZ2VuZXJhdGlvbiBpcyBhc3luYywgc28geW91IGhhdmVcbiAqIHRvIHdhaXQgdW50aWwgW1tyZWFkeV1dIHJlc29sdmVzIGJlZm9yZSBpdCB3aWxsIG1ha2UgYSBzb3VuZC5cbiAqXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtSZXZlcmJHZW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9hZGVsZXNwaW5hc3NlL3JldmVyYkdlbikuXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgQWxhbiBkZUxlc3BpbmFzc2UgQXBhY2hlIDIuMCBMaWNlbnNlLlxuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFJldmVyYiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFJldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlY2F5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUmV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252b2x2ZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVzb2x2ZXMgd2hlbiB0aGUgcmV2ZXJiIGJ1ZmZlciBpcyBnZW5lcmF0ZWQuIFdoZW5ldmVyIGVpdGhlciBbW2RlY2F5XV1cbiAgICAgICAgICogb3IgW1twcmVEZWxheV1dIGFyZSBzZXQsIHlvdSBoYXZlIHRvIHdhaXQgdW50aWwgW1tyZWFkeV1dIHJlc29sdmVzXG4gICAgICAgICAqIGJlZm9yZSB0aGUgSVIgaXMgZ2VuZXJhdGVkIHdpdGggdGhlIGxhdGVzdCB2YWx1ZXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlYWR5ID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWNheVwiXSk7XG4gICAgICAgIHRoaXMuX2RlY2F5ID0gb3B0aW9ucy5kZWNheTtcbiAgICAgICAgdGhpcy5fcHJlRGVsYXkgPSBvcHRpb25zLnByZURlbGF5O1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9jb252b2x2ZXIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWNheTogMS41LFxuICAgICAgICAgICAgcHJlRGVsYXk6IDAuMDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gb2YgdGhlIHJldmVyYi5cbiAgICAgKi9cbiAgICBnZXQgZGVjYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNheTtcbiAgICB9XG4gICAgc2V0IGRlY2F5KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwLjAwMSk7XG4gICAgICAgIHRoaXMuX2RlY2F5ID0gdGltZTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSByZXZlcmIgaXMgZnVsbHkgcmFtcGVkIGluLlxuICAgICAqL1xuICAgIGdldCBwcmVEZWxheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ByZURlbGF5O1xuICAgIH1cbiAgICBzZXQgcHJlRGVsYXkodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDApO1xuICAgICAgICB0aGlzLl9wcmVEZWxheSA9IHRpbWU7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgdGhlIEltcHVsc2UgUmVzcG9uc2UuIFJldHVybnMgYSBwcm9taXNlIHdoaWxlIHRoZSBJUiBpcyBiZWluZyBnZW5lcmF0ZWQuXG4gICAgICogQHJldHVybiBQcm9taXNlIHdoaWNoIHJldHVybnMgdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgZ2VuZXJhdGUoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c1JlYWR5ID0gdGhpcy5yZWFkeTtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5vaXNlIGJ1cnN0IHdoaWNoIGRlY2F5cyBvdmVyIHRoZSBkdXJhdGlvbiBpbiBlYWNoIGNoYW5uZWxcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMiwgdGhpcy5fZGVjYXkgKyB0aGlzLl9wcmVEZWxheSwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3Qgbm9pc2VMID0gbmV3IE5vaXNlKHsgY29udGV4dCB9KTtcbiAgICAgICAgICAgIGNvbnN0IG5vaXNlUiA9IG5ldyBOb2lzZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBub2lzZUwuY29ubmVjdChtZXJnZSwgMCwgMCk7XG4gICAgICAgICAgICBub2lzZVIuY29ubmVjdChtZXJnZSwgMCwgMSk7XG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZSA9IG5ldyBHYWluKHsgY29udGV4dCB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAgICBtZXJnZS5jb25uZWN0KGdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5vaXNlTC5zdGFydCgwKTtcbiAgICAgICAgICAgIG5vaXNlUi5zdGFydCgwKTtcbiAgICAgICAgICAgIC8vIHByZWRlbGF5XG4gICAgICAgICAgICBnYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIDApO1xuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aGlzLl9wcmVEZWxheSk7XG4gICAgICAgICAgICAvLyBkZWNheVxuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoMCwgdGhpcy5fcHJlRGVsYXksIHRoaXMuZGVjYXkpO1xuICAgICAgICAgICAgLy8gcmVuZGVyIHRoZSBidWZmZXJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclByb21pc2UgPSBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5yZWFkeSA9IHJlbmRlclByb21pc2UudGhlbihub09wKTtcbiAgICAgICAgICAgIC8vIHdhaXQgZm9yIHRoZSBwcmV2aW91cyBgcmVhZHlgIHRvIHJlc29sdmVcbiAgICAgICAgICAgIHlpZWxkIHByZXZpb3VzUmVhZHk7XG4gICAgICAgICAgICAvLyBzZXQgdGhlIGJ1ZmZlclxuICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyLmJ1ZmZlciA9ICh5aWVsZCByZW5kZXJQcm9taXNlKS5nZXQoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1SZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi9TcGxpdFwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWwgKHdoaWNoIGNvbWVzIG91dCBvZiBib3RoIHRoZSBsZWZ0IGFuZCB0aGUgcmlnaHQgY2hhbm5lbClcbiAqIGFuZCB0aGUgJ3NpZGUnICh3aGljaCBvbmx5IGNvbWVzIG91dCBvZiB0aGUgdGhlIHNpZGUgY2hhbm5lbHMpLlxuICogYGBgXG4gKiBNaWQgPSAoTGVmdCtSaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gbWlkLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBTaWRlID0gKExlZnQtUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIHNpZGUtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWlkU2lkZVNwbGl0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlU3BsaXRcIjtcbiAgICAgICAgdGhpcy5fc3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IFNwbGl0KHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taWRBZGQgPSBuZXcgQWRkKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0ID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLnNpZGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fbWlkQWRkLCAwKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9taWRBZGQuYWRkZW5kLCAxKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9zaWRlU3VidHJhY3QsIDApO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX3NpZGVTdWJ0cmFjdC5zdWJ0cmFoZW5kLCAxKTtcbiAgICAgICAgdGhpcy5fbWlkQWRkLmNvbm5lY3QodGhpcy5taWQpO1xuICAgICAgICB0aGlzLl9zaWRlU3VidHJhY3QuY29ubmVjdCh0aGlzLnNpZGUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkQWRkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlU3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi9NZXJnZVwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWlkU2lkZU1lcmdlIG1lcmdlcyB0aGUgbWlkIGFuZCBzaWRlIHNpZ25hbCBhZnRlciB0aGV5J3ZlIGJlZW4gc2VwYXJhdGVkIGJ5IFtbTWlkU2lkZVNwbGl0XV1cbiAqIGBgYFxuICogTWlkID0gKExlZnQrUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIG1pZC1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogU2lkZSA9IChMZWZ0LVJpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBzaWRlLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVNZXJnZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZU1lcmdlXCI7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuc2lkZSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbmV3IEFkZCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbGVmdE11bHQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHQgPSBuZXcgU3VidHJhY3QoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IE1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZC5mYW4odGhpcy5fbGVmdCk7XG4gICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX2xlZnQuYWRkZW5kKTtcbiAgICAgICAgdGhpcy5taWQuY29ubmVjdCh0aGlzLl9yaWdodCk7XG4gICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX3JpZ2h0LnN1YnRyYWhlbmQpO1xuICAgICAgICB0aGlzLl9sZWZ0LmNvbm5lY3QodGhpcy5fbGVmdE11bHQpO1xuICAgICAgICB0aGlzLl9yaWdodC5jb25uZWN0KHRoaXMuX3JpZ2h0TXVsdCk7XG4gICAgICAgIHRoaXMuX2xlZnRNdWx0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0TXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xlZnQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVNZXJnZS5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IE1pZFNpZGVTcGxpdCB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlU3BsaXRcIjtcbmltcG9ydCB7IE1pZFNpZGVNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbi8qKlxuICogTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWxcbiAqICh3aGljaCBjb21lcyBvdXQgb2YgYm90aCB0aGUgbGVmdCBhbmQgdGhlIHJpZ2h0IGNoYW5uZWwpXG4gKiBhbmQgdGhlICdzaWRlJyAod2hpY2ggb25seSBjb21lcyBvdXQgb2YgdGhlIHRoZSBzaWRlIGNoYW5uZWxzKVxuICogYW5kIGVmZmVjdHMgdGhlbSBzZXBhcmF0ZWx5IGJlZm9yZSBiZWluZyByZWNvbWJpbmVkLlxuICogQXBwbGllcyBhIE1pZC9TaWRlIHNlcGVyYXRpb24gYW5kIHJlY29tYmluYXRpb24uXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW2t2cmF1ZGlvIGZvcnVtc10oaHR0cDovL3d3dy5rdnJhdWRpby5jb20vZm9ydW0vdmlld3RvcGljLnBocD90PTIxMjU4NykuXG4gKiBUaGlzIGlzIGEgYmFzZS1jbGFzcyBmb3IgTWlkL1NpZGUgRWZmZWN0cy5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVFZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZUVmZmVjdFwiO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSBuZXcgTWlkU2lkZU1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSBuZXcgTWlkU2lkZVNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZDtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQgPSB0aGlzLl9taWRTaWRlU3BsaXQuc2lkZTtcbiAgICAgICAgdGhpcy5fbWlkUmV0dXJuID0gdGhpcy5fbWlkU2lkZU1lcmdlLm1pZDtcbiAgICAgICAgdGhpcy5fc2lkZVJldHVybiA9IHRoaXMuX21pZFNpZGVNZXJnZS5zaWRlO1xuICAgICAgICAvLyB0aGUgY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNvbm5lY3QodGhpcy5fbWlkU2lkZVNwbGl0KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBtaWQgY2hhaW4gb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RNaWQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fbWlkU2VuZC5jaGFpbiguLi5ub2RlcywgdGhpcy5fbWlkUmV0dXJuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgc2lkZSBjaGFpbiBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdFNpZGUoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQuY2hhaW4oLi4ubm9kZXMsIHRoaXMuX3NpZGVSZXR1cm4pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlU2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFJldHVybi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVSZXR1cm4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IE1pZFNpZGVFZmZlY3QgfSBmcm9tIFwiLi4vZWZmZWN0L01pZFNpZGVFZmZlY3RcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIEFwcGxpZXMgYSB3aWR0aCBmYWN0b3IgdG8gdGhlIG1pZC9zaWRlIHNlcGVyYXRpb24uXG4gKiAwIGlzIGFsbCBtaWQgYW5kIDEgaXMgYWxsIHNpZGUuXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW2t2cmF1ZGlvIGZvcnVtc10oaHR0cDovL3d3dy5rdnJhdWRpby5jb20vZm9ydW0vdmlld3RvcGljLnBocD90PTIxMjU4NykuXG4gKiBgYGBcbiAqIE1pZCAqPSAyKigxLXdpZHRoKTxicj5cbiAqIFNpZGUgKj0gMip3aWR0aFxuICogYGBgXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9XaWRlbmVyIGV4dGVuZHMgTWlkU2lkZUVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN0ZXJlb1dpZGVuZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ3aWR0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN0ZXJlb1dpZGVuZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFN0ZXJlb1dpZGVuZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLndpZHRoLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIndpZHRoXCJdKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkTXVsdCA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZC5jb25uZWN0KHRoaXMuX21pZE11bHQuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TWlkKHRoaXMuX21pZE11bHQpO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoLmNvbm5lY3QodGhpcy5fdHdvVGltZXNXaWR0aE1pZCk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDEpLCB0aGlzLl9vbmVNaW51c1dpZHRoKTtcbiAgICAgICAgdGhpcy53aWR0aC5jb25uZWN0KHRoaXMuX29uZU1pbnVzV2lkdGguc3VidHJhaGVuZCk7XG4gICAgICAgIHRoaXMuX3NpZGVNdWx0ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLndpZHRoLmNvbm5lY3QodGhpcy5fdHdvVGltZXNXaWR0aFNpZGUpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZS5jb25uZWN0KHRoaXMuX3NpZGVNdWx0LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFNpZGUodGhpcy5fc2lkZU11bHQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1pZFNpZGVFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2lkdGg6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlTXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29uZU1pbnVzV2lkdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9XaWRlbmVyLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBUcmVtb2xvIG1vZHVsYXRlcyB0aGUgYW1wbGl0dWRlIG9mIGFuIGluY29taW5nIHNpZ25hbCB1c2luZyBhbiBbW0xGT11dLlxuICogVGhlIGVmZmVjdCBpcyBhIHN0ZXJlbyBlZmZlY3Qgd2hlcmUgdGhlIG1vZHVsYXRpb24gcGhhc2UgaXMgaW52ZXJ0ZWQgaW4gZWFjaCBjaGFubmVsLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYSB0cmVtb2xvIGFuZCBzdGFydCBpdCdzIExGT1xuICogY29uc3QgdHJlbW9sbyA9IG5ldyBUb25lLlRyZW1vbG8oOSwgMC43NSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIHRyZW1vbG8gYW5kIHN0YXJ0IGl0XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QodHJlbW9sbykuc3RhcnQoKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBUcmVtb2xvIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJlbW9sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJlbW9sb1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJlbW9sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlTCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVwdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlcHRoLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9hbXBsaXR1ZGVMKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQodGhpcy5fYW1wbGl0dWRlUik7XG4gICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGVMLmdhaW4pO1xuICAgICAgICB0aGlzLl9sZm9SLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlUi5nYWluKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZmFuKHRoaXMuX2xmb0wuZnJlcXVlbmN5LCB0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGVwdGguZmFuKHRoaXMuX2xmb1IuYW1wbGl0dWRlLCB0aGlzLl9sZm9MLmFtcGxpdHVkZSk7XG4gICAgICAgIHRoaXMuc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMTAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIGRlcHRoOiAwLjUsXG4gICAgICAgICAgICBzcHJlYWQ6IDE4MCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSB0cmVtb2xvLlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHRyZW1vbG8uXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZWZmZWN0IHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3luYygpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBmaWx0ZXIgZnJvbSB0aGUgdHJhbnNwb3J0XG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnVuc3luYygpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnVuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvTC50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cbiAgICAgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTsgLy8gMTgwXG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX2xmb0wucGhhc2UgPSA5MCAtIChzcHJlYWQgLyAyKTtcbiAgICAgICAgdGhpcy5fbGZvUi5waGFzZSA9IChzcHJlYWQgLyAyKSArIDkwO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9SLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZVIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmVtb2xvLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQSBWaWJyYXRvIGVmZmVjdCBjb21wb3NlZCBvZiBhIFRvbmUuRGVsYXkgYW5kIGEgVG9uZS5MRk8uIFRoZSBMRk9cbiAqIG1vZHVsYXRlcyB0aGUgZGVsYXlUaW1lIG9mIHRoZSBkZWxheSwgY2F1c2luZyB0aGUgcGl0Y2ggdG8gcmlzZSBhbmQgZmFsbC5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFZpYnJhdG8gZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhWaWJyYXRvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJWaWJyYXRvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhWaWJyYXRvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBwaGFzZTogLTkwIC8vIG9mZnNlIHRoZSBwaGFzZSBzbyB0aGUgcmVzdGluZyBwb3NpdGlvbiBpcyBpbiB0aGUgY2VudGVyXG4gICAgICAgIH0pLnN0YXJ0KCkuY29ubmVjdCh0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fbGZvLmFtcGxpdHVkZTtcbiAgICAgICAgdGhpcy5kZXB0aC52YWx1ZSA9IG9wdGlvbnMuZGVwdGg7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2RlbGF5Tm9kZSwgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtYXhEZWxheTogMC4wMDUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDUsXG4gICAgICAgICAgICBkZXB0aDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFR5cGUgb2Ygb3NjaWxsYXRvciBhdHRhY2hlZCB0byB0aGUgVmlicmF0by5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmby50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1WaWJyYXRvLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0F1dG9GaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1dG9QYW5uZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1dG9XYWhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0JpdENydXNoZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0NoZWJ5c2hldlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQ2hvcnVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EaXN0b3J0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GZWVkYmFja0RlbGF5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GcmVxdWVuY3lTaGlmdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GcmVldmVyYlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vSkNSZXZlcmJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpbmdQb25nRGVsYXlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpdGNoU2hpZnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BoYXNlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUmV2ZXJiXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TdGVyZW9XaWRlbmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9UcmVtb2xvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9WaWJyYXRvXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgV2ViIEF1ZGlvJ3MgW0FuYWx5c2VyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNpZGwtZGVmLUFuYWx5c2VyTm9kZSkuXG4gKiBFeHRyYWN0cyBGRlQgb3IgV2F2ZWZvcm0gZGF0YSBmcm9tIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBbmFseXNlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBbmFseXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIiwgXCJzaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQW5hbHlzZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbmFseXNlciBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYnVmZmVyIHRoYXQgdGhlIEZGVCBkYXRhIGlzIHdyaXR0ZW4gdG9cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEFuYWx5c2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiLCBcInNpemVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gbmV3IFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNoYW5uZWxzOiBvcHRpb25zLmNoYW5uZWxzLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgYXNzZXJ0UmFuZ2Uob3B0aW9ucy5jaGFubmVscywgMSk7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgYW5hbHlzZXJzXG4gICAgICAgIGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgb3B0aW9ucy5jaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmFseXNlcnNbY2hhbm5lbF0gPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICAgICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fYW5hbHlzZXJzW2NoYW5uZWxdLCBjaGFubmVsLCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHZhbHVlcyBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgICAgICB0eXBlOiBcImZmdFwiLFxuICAgICAgICAgICAgY2hhbm5lbHM6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSdW4gdGhlIGFuYWx5c2lzIGdpdmVuIHRoZSBjdXJyZW50IHNldHRpbmdzLiBJZiBbW2NoYW5uZWxzXV0gPSAxLFxuICAgICAqIGl0IHdpbGwgcmV0dXJuIGEgRmxvYXQzMkFycmF5LiBJZiBbW2NoYW5uZWxzXV0gPiAxLCBpdCB3aWxsXG4gICAgICogcmV0dXJuIGFuIGFycmF5IG9mIEZsb2F0MzJBcnJheXMgd2hlcmUgZWFjaCBpbmRleCBpbiB0aGUgYXJyYXlcbiAgICAgKiByZXByZXNlbnRzIHRoZSBhbmFseXNpcyBkb25lIG9uIGEgY2hhbm5lbC5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goKGFuYWx5c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fYnVmZmVyc1tpbmRleF07XG4gICAgICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJmZnRcIikge1xuICAgICAgICAgICAgICAgIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShidWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3YXZlZm9ybVwiKSB7XG4gICAgICAgICAgICAgICAgYW5hbHlzZXIuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YShidWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlcnNbMF0uZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgfVxuICAgIHNldCBzaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goKGFuYWx5c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgYW5hbHlzZXIuZmZ0U2l6ZSA9IHNpemUgKiAyO1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVyc1tpbmRleF0gPSBuZXcgRmxvYXQzMkFycmF5KHNpemUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBjaGFubmVscyB0aGUgYW5hbHlzZXIgZG9lcyB0aGUgYW5hbHlzaXMgb24uIENoYW5uZWxcbiAgICAgKiBzZXBhcmF0aW9uIGlzIGRvbmUgdXNpbmcgW1tTcGxpdF1dXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXJzLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuYWx5c2lzIGZ1bmN0aW9uIHJldHVybmVkIGJ5IGFuYWx5c2VyLmdldFZhbHVlKCksIGVpdGhlciBcImZmdFwiIG9yIFwid2F2ZWZvcm1cIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgYXNzZXJ0KHR5cGUgPT09IFwid2F2ZWZvcm1cIiB8fCB0eXBlID09PSBcImZmdFwiLCBgQW5hbHlzZXI6IGludmFsaWQgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogMCByZXByZXNlbnRzIG5vIHRpbWUgYXZlcmFnaW5nIHdpdGggdGhlIGxhc3QgYW5hbHlzaXMgZnJhbWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2Vyc1swXS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQ7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcodmFsKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKGEgPT4gYS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSB2YWwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKGEgPT4gYS5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BbmFseXNlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEFuYWx5c2VyIH0gZnJvbSBcIi4vQW5hbHlzZXJcIjtcbi8qKlxuICogVGhlIGJhc2UgY2xhc3MgZm9yIE1ldGVyaW5nIGNsYXNzZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRlckJhc2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXJCYXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGVyQmFzZVwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBBbmFseXNlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzaXplOiAyNTYsXG4gICAgICAgICAgICB0eXBlOiBcIndhdmVmb3JtXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0ZXJCYXNlLmpzLm1hcCIsImltcG9ydCB7IGdhaW5Ub0RiIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbmltcG9ydCB7IHdhcm4gfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBBbmFseXNlciB9IGZyb20gXCIuL0FuYWx5c2VyXCI7XG4vKipcbiAqIE1ldGVyIGdldHMgdGhlIFtSTVNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1Jvb3RfbWVhbl9zcXVhcmUpXG4gKiBvZiBhbiBpbnB1dCBzaWduYWwuIEl0IGNhbiBhbHNvIGdldCB0aGUgcmF3IHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpO1xuICogbWljLm9wZW4oKTtcbiAqIC8vIGNvbm5lY3QgbWljIHRvIHRoZSBtZXRlclxuICogbWljLmNvbm5lY3QobWV0ZXIpO1xuICogLy8gdGhlIGN1cnJlbnQgbGV2ZWwgb2YgdGhlIG1pY1xuICogc2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2cobWV0ZXIuZ2V0VmFsdWUoKSksIDEwMCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRlciBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwcmV2aW91cyBmcmFtZSdzIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ybXMgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBBbmFseXNlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzaXplOiAyNTYsXG4gICAgICAgICAgICB0eXBlOiBcIndhdmVmb3JtXCIsXG4gICAgICAgICAgICBjaGFubmVsczogb3B0aW9ucy5jaGFubmVscyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc21vb3RoaW5nID0gb3B0aW9ucy5zbW9vdGhpbmcsXG4gICAgICAgICAgICB0aGlzLm5vcm1hbFJhbmdlID0gb3B0aW9ucy5ub3JtYWxSYW5nZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNZXRlckJhc2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgICAgICBub3JtYWxSYW5nZTogZmFsc2UsXG4gICAgICAgICAgICBjaGFubmVsczogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVzZSBbW2dldFZhbHVlXV0gaW5zdGVhZC4gRm9yIHRoZSBwcmV2aW91cyBnZXRWYWx1ZSBiZWhhdmlvciwgdXNlIERDTWV0ZXIuXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXRMZXZlbCgpIHtcbiAgICAgICAgd2FybihcIidnZXRMZXZlbCcgaGFzIGJlZW4gY2hhbmdlZCB0byAnZ2V0VmFsdWUnXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbC5cbiAgICAgKiBPdXRwdXQgaXMgaW4gZGVjaWJlbHMgd2hlbiBbW25vcm1hbFJhbmdlXV0gaXMgYGZhbHNlYC5cbiAgICAgKiBJZiBbW2NoYW5uZWxzXV0gPSAxLCB0aGVuIHRoZSBvdXRwdXQgaXMgYSBzaW5nbGUgbnVtYmVyXG4gICAgICogcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsLiBXaGVuIFtbY2hhbm5lbHNdXSA+IDEsXG4gICAgICogdGhlbiBlYWNoIGNoYW5uZWwgaXMgcmV0dXJuZWQgYXMgYSB2YWx1ZSBpbiBhIG51bWJlciBhcnJheS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgYVZhbHVlcyA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxWYWx1ZXMgPSB0aGlzLmNoYW5uZWxzID09PSAxID8gW2FWYWx1ZXNdIDogYVZhbHVlcztcbiAgICAgICAgY29uc3QgdmFscyA9IGNoYW5uZWxWYWx1ZXMubWFwKHZhbHVlcyA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b3RhbFNxdWFyZWQgPSB2YWx1ZXMucmVkdWNlKCh0b3RhbCwgY3VycmVudCkgPT4gdG90YWwgKyBjdXJyZW50ICogY3VycmVudCwgMCk7XG4gICAgICAgICAgICBjb25zdCBybXMgPSBNYXRoLnNxcnQodG90YWxTcXVhcmVkIC8gdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgICAgICAvLyB0aGUgcm1zIGNhbiBvbmx5IGZhbGwgYXQgdGhlIHJhdGUgb2YgdGhlIHNtb290aGluZ1xuICAgICAgICAgICAgLy8gYnV0IGNhbiBqdW1wIHVwIGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy5fcm1zID0gTWF0aC5tYXgocm1zLCB0aGlzLl9ybXMgKiB0aGlzLnNtb290aGluZyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxSYW5nZSA/IHRoaXMuX3JtcyA6IGdhaW5Ub0RiKHRoaXMuX3Jtcyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5jaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFscztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIGFuYWx5c2lzLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLmNoYW5uZWxzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgZGJUb0dhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgZnJlcXVlbmN5IGRhdGEgb2YgdGhlIGNvbm5lY3RlZCBhdWRpbyBzb3VyY2UgdXNpbmcgYSBmYXN0IEZvdXJpZXIgdHJhbnNmb3JtLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRkZUIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRkZULmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZGVFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRkZULmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSk7XG4gICAgICAgIHRoaXMubm9ybWFsUmFuZ2UgPSBvcHRpb25zLm5vcm1hbFJhbmdlO1xuICAgICAgICB0aGlzLl9hbmFseXNlci50eXBlID0gXCJmZnRcIjtcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbm9ybWFsUmFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgY3VycmVudCBmcmVxdWVuY3kgZGF0YSBmcm9tIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuICAgICAqIFJldHVybnMgdGhlIGZyZXF1ZW5jeSBkYXRhIG9mIGxlbmd0aCBbW3NpemVdXSBhcyBhIEZsb2F0MzJBcnJheSBvZiBkZWNpYmVsIHZhbHVlcy5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5tYXAodiA9PiB0aGlzLm5vcm1hbFJhbmdlID8gZGJUb0dhaW4odikgOiB2KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgW1tnZXRWYWx1ZV1dIChpLmUuIHRoZSBudW1iZXIgb2ZcbiAgICAgKiBmcmVxdWVuY3kgYmlucykuIExhcmdlIEZGVCBzaXplcyBtYXkgYmUgY29zdGx5IHRvIGNvbXB1dGUuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5zaXplO1xuICAgIH1cbiAgICBzZXQgc2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSBzaXplO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAwIHJlcHJlc2VudHMgbm8gdGltZSBhdmVyYWdpbmcgd2l0aCB0aGUgbGFzdCBhbmFseXNpcyBmcmFtZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHZhbCkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zbW9vdGhpbmcgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZyZXF1ZW5jeSB2YWx1ZSBpbiBoZXJ0eiBvZiBlYWNoIG9mIHRoZSBpbmRpY2VzIG9mIHRoZSBGRlQncyBbW2dldFZhbHVlXV0gcmVzcG9uc2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmZnQgPSBuZXcgVG9uZS5GRlQoMzIpO1xuICAgICAqIGNvbnNvbGUubG9nKFswLCAxLCAyLCAzLCA0XS5tYXAoaW5kZXggPT4gZmZ0LmdldEZyZXF1ZW5jeU9mSW5kZXgoaW5kZXgpKSk7XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5T2ZJbmRleChpbmRleCkge1xuICAgICAgICBhc3NlcnQoMCA8PSBpbmRleCAmJiBpbmRleCA8IHRoaXMuc2l6ZSwgYGluZGV4IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MgdGhhbiAke3RoaXMuc2l6ZX1gKTtcbiAgICAgICAgcmV0dXJuIGluZGV4ICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAodGhpcy5zaXplICogMik7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RkZULmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG4vKipcbiAqIERDTWV0ZXIgZ2V0cyB0aGUgcmF3IHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwgYXQgdGhlIGN1cnJlbnQgdGltZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWV0ZXIgPSBuZXcgVG9uZS5EQ01ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAqIG1pYy5vcGVuKCk7XG4gKiAvLyBjb25uZWN0IG1pYyB0byB0aGUgbWV0ZXJcbiAqIG1pYy5jb25uZWN0KG1ldGVyKTtcbiAqIC8vIHRoZSBjdXJyZW50IGxldmVsIG9mIHRoZSBtaWNcbiAqIGNvbnN0IGxldmVsID0gbWV0ZXIuZ2V0VmFsdWUoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIERDTWV0ZXIgZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEQ01ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRDTWV0ZXJcIjtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwid2F2ZWZvcm1cIjtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc2l6ZSA9IDI1NjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzaWduYWwgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbFxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIHJldHVybiB2YWx1ZVswXTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EQ01ldGVyLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG4vKipcbiAqIEdldCB0aGUgY3VycmVudCB3YXZlZm9ybSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgV2F2ZWZvcm0gZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlZm9ybS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJXYXZlZm9ybVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZWZvcm0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwid2F2ZWZvcm1cIjtcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1ldGVyQmFzZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB3YXZlZm9ybSBmb3IgdGhlIGN1cnJlbnQgdGltZSBhcyBhIEZsb2F0MzJBcnJheSB3aGVyZSBlYWNoIHZhbHVlIGluIHRoZSBhcnJheVxuICAgICAqIHJlcHJlc2VudHMgYSBzYW1wbGUgaW4gdGhlIHdhdmVmb3JtLlxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgW1tnZXRWYWx1ZV1dLlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc2l6ZTtcbiAgICB9XG4gICAgc2V0IHNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gc2l6ZTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1XYXZlZm9ybS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogU29sbyBsZXRzIHlvdSBpc29sYXRlIGEgc3BlY2lmaWMgYXVkaW8gc3RyZWFtLiBXaGVuIGFuIGluc3RhbmNlIGlzIHNldCB0byBgc29sbz10cnVlYCxcbiAqIGl0IHdpbGwgbXV0ZSBhbGwgb3RoZXIgaW5zdGFuY2VzIG9mIFNvbG8uXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc29sb0EgPSBuZXcgVG9uZS5Tb2xvKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjQSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJDNFwiLCBcInNhd3Rvb3RoXCIpLmNvbm5lY3Qoc29sb0EpO1xuICogY29uc3Qgc29sb0IgPSBuZXcgVG9uZS5Tb2xvKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjQiA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJFNFwiLCBcInNxdWFyZVwiKS5jb25uZWN0KHNvbG9CKTtcbiAqIHNvbG9BLnNvbG8gPSB0cnVlO1xuICogLy8gbm8gYXVkaW8gd2lsbCBwYXNzIHRocm91Z2ggc29sb0JcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNvbG8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU29sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNvbG9cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTb2xvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTb2xvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic29sb1wiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghU29sby5fYWxsU29sb3MuaGFzKHRoaXMuY29udGV4dCkpIHtcbiAgICAgICAgICAgIFNvbG8uX2FsbFNvbG9zLnNldCh0aGlzLmNvbnRleHQsIG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgU29sby5fYWxsU29sb3MuZ2V0KHRoaXMuY29udGV4dCkuYWRkKHRoaXMpO1xuICAgICAgICAvLyBzZXQgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMuc29sbyA9IG9wdGlvbnMuc29sbztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNvbG86IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXNvbGF0ZXMgdGhpcyBpbnN0YW5jZSBhbmQgbXV0ZXMgYWxsIG90aGVyIGluc3RhbmNlcyBvZiBTb2xvLlxuICAgICAqIE9ubHkgb25lIGluc3RhbmNlIGNhbiBiZSBzb2xvZWQgYXQgYSB0aW1lLiBBIHNvbG9lZFxuICAgICAqIGluc3RhbmNlIHdpbGwgcmVwb3J0IGBzb2xvPWZhbHNlYCB3aGVuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkLlxuICAgICAqL1xuICAgIGdldCBzb2xvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNTb2xvZWQoKTtcbiAgICB9XG4gICAgc2V0IHNvbG8oc29sbykge1xuICAgICAgICBpZiAoc29sbykge1xuICAgICAgICAgICAgdGhpcy5fYWRkU29sbygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuICAgICAgICB9XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmZvckVhY2goaW5zdGFuY2UgPT4gaW5zdGFuY2UuX3VwZGF0ZVNvbG8oKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBjdXJyZW50IGluc3RhbmNlIGlzIG11dGVkLCBpLmUuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkXG4gICAgICovXG4gICAgZ2V0IG11dGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5nYWluLnZhbHVlID09PSAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgdGhpcyB0byB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX2FkZFNvbG8oKSB7XG4gICAgICAgIGlmICghU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICBTb2xvLl9zb2xvZWQuc2V0KHRoaXMuY29udGV4dCwgbmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBTb2xvLl9zb2xvZWQuZ2V0KHRoaXMuY29udGV4dCkuYWRkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhpcyBmcm9tIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfcmVtb3ZlU29sbygpIHtcbiAgICAgICAgaWYgKFNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmRlbGV0ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJcyB0aGlzIG9uIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfaXNTb2xvZWQoKSB7XG4gICAgICAgIHJldHVybiBTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgJiYgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmhhcyh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIG5vIG9uZSBpcyBzb2xvZWRcbiAgICAgKi9cbiAgICBfbm9Tb2xvcygpIHtcbiAgICAgICAgLy8gZWl0aGVyIGRvZXMgbm90IGhhdmUgYW55IHNvbG9lZCBhZGRlZFxuICAgICAgICByZXR1cm4gIVNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSB8fFxuICAgICAgICAgICAgLy8gb3IgaGFzIGEgc29sbyBzZXQgYnV0IGRvZXNuJ3QgaW5jbHVkZSBhbnkgaXRlbXNcbiAgICAgICAgICAgIChTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgJiYgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLnNpemUgPT09IDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTb2xvIHRoZSBjdXJyZW50IGluc3RhbmNlIGFuZCB1bnNvbG8gYWxsIG90aGVyIGluc3RhbmNlcy5cbiAgICAgKi9cbiAgICBfdXBkYXRlU29sbygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU29sb2VkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fbm9Tb2xvcygpKSB7XG4gICAgICAgICAgICAvLyBubyBvbmUgaXMgc29sb2VkXG4gICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmRlbGV0ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEhvbGQgYWxsIG9mIHRoZSBzb2xvJ2VkIHRyYWNrcyBiZWxvbmdpbmcgdG8gYSBzcGVjaWZpYyBjb250ZXh0XG4gKi9cblNvbG8uX2FsbFNvbG9zID0gbmV3IE1hcCgpO1xuLyoqXG4gKiBIb2xkIHRoZSBjdXJyZW50bHkgc29sbydlZCBpbnN0YW5jZShzKVxuICovXG5Tb2xvLl9zb2xvZWQgPSBuZXcgTWFwKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Tb2xvLmpzLm1hcCIsImltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUGFubmVyIH0gZnJvbSBcIi4vUGFubmVyXCI7XG5pbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi9Wb2x1bWVcIjtcbi8qKlxuICogUGFuVm9sIGlzIGEgVG9uZS5QYW5uZXIgYW5kIFRvbmUuVm9sdW1lIGluIG9uZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBwYW4gdGhlIGluY29taW5nIHNpZ25hbCBsZWZ0IGFuZCBkcm9wIHRoZSB2b2x1bWVcbiAqIGNvbnN0IHBhblZvbCA9IG5ldyBUb25lLlBhblZvbCgtMC4yNSwgLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChwYW5Wb2wpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5Wb2wgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFuVm9sLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCIsIFwidm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFuVm9sXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5Wb2wuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmlucHV0ID0gbmV3IFBhbm5lcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYW46IG9wdGlvbnMucGFuLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGFuID0gdGhpcy5fcGFubmVyLnBhbjtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25uZWN0KHRoaXMuX3ZvbHVtZSk7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZS91bm11dGUgdGhlIHZvbHVtZVxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5Wb2wuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTb2xvIH0gZnJvbSBcIi4vU29sb1wiO1xuaW1wb3J0IHsgUGFuVm9sIH0gZnJvbSBcIi4vUGFuVm9sXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIENoYW5uZWwgcHJvdmlkZXMgYSBjaGFubmVsIHN0cmlwIGludGVyZmFjZSB3aXRoIHZvbHVtZSwgcGFuLCBzb2xvIGFuZCBtdXRlIGNvbnRyb2xzLlxuICogU2VlIFtbUGFuVm9sXV0gYW5kIFtbU29sb11dXG4gKiBAZXhhbXBsZVxuICogLy8gcGFuIHRoZSBpbmNvbWluZyBzaWduYWwgbGVmdCBhbmQgZHJvcCB0aGUgdm9sdW1lIDEyZGJcbiAqIGNvbnN0IGNoYW5uZWwgPSBuZXcgVG9uZS5DaGFubmVsKC0wLjI1LCAtMTIpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ2hhbm5lbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGFubmVsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCIsIFwicGFuXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hhbm5lbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hhbm5lbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiLCBcInBhblwiXSk7XG4gICAgICAgIHRoaXMuX3NvbG8gPSB0aGlzLmlucHV0ID0gbmV3IFNvbG8oe1xuICAgICAgICAgICAgc29sbzogb3B0aW9ucy5zb2xvLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFuVm9sID0gdGhpcy5vdXRwdXQgPSBuZXcgUGFuVm9sKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhbjogb3B0aW9ucy5wYW4sXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICAgICAgbXV0ZTogb3B0aW9ucy5tdXRlLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wYW4gPSB0aGlzLl9wYW5Wb2wucGFuO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3BhblZvbC52b2x1bWU7XG4gICAgICAgIHRoaXMuX3NvbG8uY29ubmVjdCh0aGlzLl9wYW5Wb2wpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBzb2xvOiBmYWxzZSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNvbG8vdW5zb2xvIHRoZSBjaGFubmVsLiBTb2xvaW5nIGlzIG9ubHkgcmVsYXRpdmUgdG8gb3RoZXIgW1tDaGFubmVsc11dIGFuZCBbW1NvbG9dXSBpbnN0YW5jZXNcbiAgICAgKi9cbiAgICBnZXQgc29sbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvbG8uc29sbztcbiAgICB9XG4gICAgc2V0IHNvbG8oc29sbykge1xuICAgICAgICB0aGlzLl9zb2xvLnNvbG8gPSBzb2xvO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY3VycmVudCBpbnN0YW5jZSBpcyBtdXRlZCwgaS5lLiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZCxcbiAgICAgKiBvciB0aGUgY2hhbm5lbCBpcyBtdXRlZFxuICAgICAqL1xuICAgIGdldCBtdXRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvbG8ubXV0ZWQgfHwgdGhpcy5tdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlL3VubXV0ZSB0aGUgdm9sdW1lXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5Wb2wubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl9wYW5Wb2wubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZ2FpbiBub2RlIGJlbG9uZ2luZyB0byB0aGUgYnVzIG5hbWUuIENyZWF0ZSBpdCBpZlxuICAgICAqIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYnVzIG5hbWVcbiAgICAgKi9cbiAgICBfZ2V0QnVzKG5hbWUpIHtcbiAgICAgICAgaWYgKCFDaGFubmVsLmJ1c2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgQ2hhbm5lbC5idXNlcy5zZXQobmFtZSwgbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDaGFubmVsLmJ1c2VzLmdldChuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZCBhdWRpbyB0byBhbm90aGVyIGNoYW5uZWwgdXNpbmcgYSBzdHJpbmcuIGBzZW5kYCBpcyBhIGxvdCBsaWtlXG4gICAgICogW1tjb25uZWN0XV0sIGV4Y2VwdCBpdCB1c2VzIGEgc3RyaW5nIGluc3RlYWQgb2YgYW4gb2JqZWN0LiBUaGlzIGNhblxuICAgICAqIGJlIHVzZWZ1bCBpbiBsYXJnZSBhcHBsaWNhdGlvbnMgdG8gZGVjb3VwbGUgc2VjdGlvbnMgc2luY2UgW1tzZW5kXV1cbiAgICAgKiBhbmQgW1tyZWNlaXZlXV0gY2FuIGJlIGludm9rZWQgc2VwYXJhdGVseSBpbiBvcmRlciB0byBjb25uZWN0IGFuIG9iamVjdFxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBjaGFubmVsIG5hbWUgdG8gc2VuZCB0aGUgYXVkaW9cbiAgICAgKiBAcGFyYW0gdm9sdW1lIFRoZSBhbW91bnQgb2YgdGhlIHNpZ25hbCB0byBzZW5kLlxuICAgICAqIFx0RGVmYXVsdHMgdG8gMGRiLCBpLmUuIHNlbmQgdGhlIGVudGlyZSBzaWduYWxcbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIHRoZSBnYWluIG5vZGUgb2YgdGhpcyBjb25uZWN0aW9uLlxuICAgICAqL1xuICAgIHNlbmQobmFtZSwgdm9sdW1lID0gMCkge1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLl9nZXRCdXMobmFtZSk7XG4gICAgICAgIGNvbnN0IHNlbmRLbm9iID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGdhaW46IHZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY29ubmVjdChzZW5kS25vYik7XG4gICAgICAgIHNlbmRLbm9iLmNvbm5lY3QoYnVzKTtcbiAgICAgICAgcmV0dXJuIHNlbmRLbm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWNlaXZlIGF1ZGlvIGZyb20gYSBjaGFubmVsIHdoaWNoIHdhcyBjb25uZWN0ZWQgd2l0aCBbW3NlbmRdXS5cbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgY2hhbm5lbCBuYW1lIHRvIHJlY2VpdmUgYXVkaW8gZnJvbS5cbiAgICAgKi9cbiAgICByZWNlaXZlKG5hbWUpIHtcbiAgICAgICAgY29uc3QgYnVzID0gdGhpcy5fZ2V0QnVzKG5hbWUpO1xuICAgICAgICBidXMuY29ubmVjdCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFuVm9sLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NvbG8uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIFN0b3JlIHRoZSBzZW5kL3JlY2VpdmUgY2hhbm5lbHMgYnkgbmFtZS5cbiAqL1xuQ2hhbm5lbC5idXNlcyA9IG5ldyBNYXAoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNoYW5uZWwuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuL01lcmdlXCI7XG4vKipcbiAqIE1vbm8gY29lcmNlcyB0aGUgaW5jb21pbmcgbW9ubyBvciBzdGVyZW8gc2lnbmFsIGludG8gYSBtb25vIHNpZ25hbFxuICogd2hlcmUgYm90aCBsZWZ0IGFuZCByaWdodCBjaGFubmVscyBoYXZlIHRoZSBzYW1lIHZhbHVlLiBUaGlzIGNhbiBiZSB1c2VmdWxcbiAqIGZvciBbc3RlcmVvIGltYWdpbmddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N0ZXJlb19pbWFnaW5nKS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9uby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb25vXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBNZXJnZSh7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9uby5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2ZpbHRlci9GaWx0ZXJcIjtcbi8qKlxuICogU3BsaXQgdGhlIGluY29taW5nIHNpZ25hbCBpbnRvIHRocmVlIGJhbmRzIChsb3csIG1pZCwgaGlnaClcbiAqIHdpdGggdHdvIGNyb3Nzb3ZlciBmcmVxdWVuY3kgY29udHJvbHMuXG4gKiBgYGBcbiAqICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICArLT4gaW5wdXQgPCBsb3dGcmVxdWVuY3kgKy0tLS0tLS0tLS0tLS0tLS0tLT4gbG93XG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgfFxuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBpbnB1dCAtLS0rLT4gbG93RnJlcXVlbmN5IDwgaW5wdXQgPCBoaWdoRnJlcXVlbmN5ICstLT4gbWlkXG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgIHxcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgKy0+IGhpZ2hGcmVxdWVuY3kgPCBpbnB1dCArLS0tLS0tLS0tLS0tLS0tLS0+IGhpZ2hcbiAqICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNdWx0aWJhbmRTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aWJhbmRTcGxpdFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBubyBvdXRwdXQgbm9kZSwgdXNlIGVpdGhlciBsb3csIG1pZCBvciBoaWdoIG91dHB1dHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvdyBiYW5kLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sb3cgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBsb3dlciBmaWx0ZXIgb2YgdGhlIG1pZCBiYW5kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwiaGlnaHBhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWlkIGJhbmQgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5taWQgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBoaWdoIGJhbmQgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oaWdoID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImhpZ2hwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMubG93LCB0aGlzLm1pZCwgdGhpcy5oaWdoXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpYmFuZFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmxvd0ZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuZmFuKHRoaXMubG93LCB0aGlzLmhpZ2gpO1xuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2xvd01pZEZpbHRlciwgdGhpcy5taWQpO1xuICAgICAgICAvLyB0aGUgZnJlcXVlbmN5IGNvbnRyb2wgc2lnbmFsXG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmZhbih0aGlzLmxvdy5mcmVxdWVuY3ksIHRoaXMuX2xvd01pZEZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kuZmFuKHRoaXMubWlkLmZyZXF1ZW5jeSwgdGhpcy5oaWdoLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHRoZSBRIHZhbHVlXG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMubG93LlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLl9sb3dNaWRGaWx0ZXIuUSk7XG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMubWlkLlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLmhpZ2guUSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyNTAwLFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiA0MDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5sb3cuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGliYW5kU3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4vUGFyYW1cIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG4vKipcbiAqIFRvbmUuTGlzdGVuZXIgaXMgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBBdWRpb0xpc3RlbmVyLiBMaXN0ZW5lciBjb21iaW5lZFxuICogd2l0aCBbW1Bhbm5lcjNEXV0gbWFrZXMgdXAgdGhlIFdlYiBBdWRpbyBBUEkncyAzRCBwYW5uaW5nIHN5c3RlbS4gUGFubmVyM0QgYWxsb3dzIHlvdVxuICogdG8gcGxhY2Ugc291bmRzIGluIDNEIGFuZCBMaXN0ZW5lciBhbGxvd3MgeW91IHRvIG5hdmlnYXRlIHRoZSAzRCBzb3VuZCBlbnZpcm9ubWVudCBmcm9tXG4gKiBhIGZpcnN0LXBlcnNvbiBwZXJzcGVjdGl2ZS4gVGhlcmUgaXMgb25seSBvbmUgbGlzdGVuZXIgcGVyIGF1ZGlvIGNvbnRleHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMaXN0ZW5lciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxpc3RlbmVyXCI7XG4gICAgICAgIHRoaXMucG9zaXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5wb3NpdGlvblgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIucG9zaXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRYLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIuZm9yd2FyZFksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcndhcmRaID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5mb3J3YXJkWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBYID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci51cFgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIudXBZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cFogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnVwWixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwb3NpdGlvblg6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblk6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblo6IDAsXG4gICAgICAgICAgICBmb3J3YXJkWDogMCxcbiAgICAgICAgICAgIGZvcndhcmRZOiAwLFxuICAgICAgICAgICAgZm9yd2FyZFo6IC0xLFxuICAgICAgICAgICAgdXBYOiAwLFxuICAgICAgICAgICAgdXBZOiAxLFxuICAgICAgICAgICAgdXBaOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZvcndhcmRYLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVwWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudXBZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51cFouZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0Lmxpc3RlbmVyID0gbmV3IExpc3RlbmVyKHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5saXN0ZW5lci5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxpc3RlbmVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgXCIuLi8uLi9jb3JlL2NvbnRleHQvTGlzdGVuZXJcIjtcbi8qKlxuICogQSBzcGF0aWFsaXplZCBwYW5uZXIgbm9kZSB3aGljaCBzdXBwb3J0cyBlcXVhbHBvd2VyIG9yIEhSVEYgcGFubmluZy5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhbm5lcjNEIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lcjNELmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicG9zaXRpb25YXCIsIFwicG9zaXRpb25ZXCIsIFwicG9zaXRpb25aXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFubmVyM0RcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lcjNELmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicG9zaXRpb25YXCIsIFwicG9zaXRpb25ZXCIsIFwicG9zaXRpb25aXCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgICAgICAvLyBzZXQgc29tZSB2YWx1ZXNcbiAgICAgICAgdGhpcy5wYW5uaW5nTW9kZWwgPSBvcHRpb25zLnBhbm5pbmdNb2RlbDtcbiAgICAgICAgdGhpcy5tYXhEaXN0YW5jZSA9IG9wdGlvbnMubWF4RGlzdGFuY2U7XG4gICAgICAgIHRoaXMuZGlzdGFuY2VNb2RlbCA9IG9wdGlvbnMuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgdGhpcy5jb25lT3V0ZXJHYWluID0gb3B0aW9ucy5jb25lT3V0ZXJHYWluO1xuICAgICAgICB0aGlzLmNvbmVPdXRlckFuZ2xlID0gb3B0aW9ucy5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgdGhpcy5jb25lSW5uZXJBbmdsZSA9IG9wdGlvbnMuY29uZUlubmVyQW5nbGU7XG4gICAgICAgIHRoaXMucmVmRGlzdGFuY2UgPSBvcHRpb25zLnJlZkRpc3RhbmNlO1xuICAgICAgICB0aGlzLnJvbGxvZmZGYWN0b3IgPSBvcHRpb25zLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgIHRoaXMucG9zaXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucG9zaXRpb25YLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucG9zaXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wb3NpdGlvblksXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wb3NpdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBvc2l0aW9uWixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBvc2l0aW9uWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIub3JpZW50YXRpb25YLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub3JpZW50YXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblksXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vcmllbnRhdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLm9yaWVudGF0aW9uWixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9yaWVudGF0aW9uWixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb25lSW5uZXJBbmdsZTogMzYwLFxuICAgICAgICAgICAgY29uZU91dGVyQW5nbGU6IDM2MCxcbiAgICAgICAgICAgIGNvbmVPdXRlckdhaW46IDAsXG4gICAgICAgICAgICBkaXN0YW5jZU1vZGVsOiBcImludmVyc2VcIixcbiAgICAgICAgICAgIG1heERpc3RhbmNlOiAxMDAwMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWDogMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWTogMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWjogMCxcbiAgICAgICAgICAgIHBhbm5pbmdNb2RlbDogXCJlcXVhbHBvd2VyXCIsXG4gICAgICAgICAgICBwb3NpdGlvblg6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblk6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblo6IDAsXG4gICAgICAgICAgICByZWZEaXN0YW5jZTogMSxcbiAgICAgICAgICAgIHJvbGxvZmZGYWN0b3I6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc291cmNlIGluIDNkIHNwYWNlLlxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uKHgsIHksIHopIHtcbiAgICAgICAgdGhpcy5wb3NpdGlvblgudmFsdWUgPSB4O1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS52YWx1ZSA9IHk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLnZhbHVlID0gejtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBzb3VyY2UgaW4gM2Qgc3BhY2UuXG4gICAgICovXG4gICAgc2V0T3JpZW50YXRpb24oeCwgeSwgeikge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWC52YWx1ZSA9IHg7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZLnZhbHVlID0geTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbloudmFsdWUgPSB6O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhbm5pbmcgbW9kZWwuIEVpdGhlciBcImVxdWFscG93ZXJcIiBvciBcIkhSVEZcIi5cbiAgICAgKi9cbiAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbDtcbiAgICB9XG4gICAgc2V0IHBhbm5pbmdNb2RlbCh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbCA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWZlcmVuY2UgZGlzdGFuY2UgZm9yIHJlZHVjaW5nIHZvbHVtZSBhcyBzb3VyY2UgbW92ZSBmdXJ0aGVyIGZyb20gdGhlIGxpc3RlbmVyXG4gICAgICovXG4gICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnJlZkRpc3RhbmNlO1xuICAgIH1cbiAgICBzZXQgcmVmRGlzdGFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5yZWZEaXN0YW5jZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzY3JpYmVzIGhvdyBxdWlja2x5IHRoZSB2b2x1bWUgaXMgcmVkdWNlZCBhcyBzb3VyY2UgbW92ZXMgYXdheSBmcm9tIGxpc3RlbmVyLlxuICAgICAqL1xuICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnJvbGxvZmZGYWN0b3I7XG4gICAgfVxuICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIucm9sbG9mZkZhY3RvciA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRpc3RhbmNlIG1vZGVsIHVzZWQgYnksICBcImxpbmVhclwiLCBcImludmVyc2VcIiwgb3IgXCJleHBvbmVudGlhbFwiLlxuICAgICAqL1xuICAgIGdldCBkaXN0YW5jZU1vZGVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmRpc3RhbmNlTW9kZWw7XG4gICAgfVxuICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzdGFuY2VNb2RlbCA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuZ2xlLCBpbiBkZWdyZWVzLCBpbnNpZGUgb2Ygd2hpY2ggdGhlcmUgd2lsbCBiZSBubyB2b2x1bWUgcmVkdWN0aW9uXG4gICAgICovXG4gICAgZ2V0IGNvbmVJbm5lckFuZ2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVJbm5lckFuZ2xlO1xuICAgIH1cbiAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lSW5uZXJBbmdsZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuZ2xlLCBpbiBkZWdyZWVzLCBvdXRzaWRlIG9mIHdoaWNoIHRoZSB2b2x1bWUgd2lsbCBiZSByZWR1Y2VkXG4gICAgICogdG8gYSBjb25zdGFudCB2YWx1ZSBvZiBjb25lT3V0ZXJHYWluXG4gICAgICovXG4gICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVPdXRlckFuZ2xlO1xuICAgIH1cbiAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJBbmdsZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGdhaW4gb3V0c2lkZSBvZiB0aGUgY29uZU91dGVyQW5nbGVcbiAgICAgKi9cbiAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJHYWluO1xuICAgIH1cbiAgICBzZXQgY29uZU91dGVyR2Fpbih2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVPdXRlckdhaW4gPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIGRpc3RhbmNlIGJldHdlZW4gc291cmNlIGFuZCBsaXN0ZW5lcixcbiAgICAgKiBhZnRlciB3aGljaCB0aGUgdm9sdW1lIHdpbGwgbm90IGJlIHJlZHVjZWQgYW55IGZ1cnRoZXIuXG4gICAgICovXG4gICAgZ2V0IG1heERpc3RhbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLm1heERpc3RhbmNlO1xuICAgIH1cbiAgICBzZXQgbWF4RGlzdGFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5tYXhEaXN0YW5jZSA9IHZhbDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblouZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5uZXIzRC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHRoZVdpbmRvdyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogQSB3cmFwcGVyIGFyb3VuZCB0aGUgTWVkaWFSZWNvcmRlciBBUEkuIFVubGlrZSB0aGUgcmVzdCBvZiBUb25lLmpzLCB0aGlzIG1vZHVsZSBkb2VzIG5vdCBvZmZlclxuICogYW55IHNhbXBsZS1hY2N1cmF0ZSBzY2hlZHVsaW5nIGJlY2F1c2UgaXQgaXMgbm90IGEgZmVhdHVyZSBvZiB0aGUgTWVkaWFSZWNvcmRlciBBUEkuXG4gKiBUaGlzIGlzIG9ubHkgbmF0aXZlbHkgc3VwcG9ydGVkIGluIENocm9tZSBhbmQgRmlyZWZveC5cbiAqIEZvciBhIGNyb3NzLWJyb3dzZXIgc2hpbSwgaW5zdGFsbCAoYXVkaW8tcmVjb3JkZXItcG9seWZpbGwpW2h0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2F1ZGlvLXJlY29yZGVyLXBvbHlmaWxsXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZWNvcmRlciA9IG5ldyBUb25lLlJlY29yZGVyKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkuY29ubmVjdChyZWNvcmRlcik7XG4gKiAvLyBzdGFydCByZWNvcmRpbmdcbiAqIHJlY29yZGVyLnN0YXJ0KCk7XG4gKiAvLyBnZW5lcmF0ZSBhIGZldyBub3Rlc1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDM1wiLCAwLjUpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCAwLjUsIFwiKzFcIik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM1XCIsIDAuNSwgXCIrMlwiKTtcbiAqIC8vIHdhaXQgZm9yIHRoZSBub3RlcyB0byBlbmQgYW5kIHN0b3AgdGhlIHJlY29yZGluZ1xuICogc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gKiBcdC8vIHRoZSByZWNvcmRlZCBhdWRpbyBpcyByZXR1cm5lZCBhcyBhIGJsb2JcbiAqIFx0Y29uc3QgcmVjb3JkaW5nID0gYXdhaXQgcmVjb3JkZXIuc3RvcCgpO1xuICogXHQvLyBkb3dubG9hZCB0aGUgcmVjb3JkaW5nIGJ5IGNyZWF0aW5nIGFuIGFuY2hvciBlbGVtZW50IGFuZCBibG9iIHVybFxuICogXHRjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHJlY29yZGluZyk7XG4gKiBcdGNvbnN0IGFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICogXHRhbmNob3IuZG93bmxvYWQgPSBcInJlY29yZGluZy53ZWJtXCI7XG4gKiBcdGFuY2hvci5ocmVmID0gdXJsO1xuICogXHRhbmNob3IuY2xpY2soKTtcbiAqIH0sIDQwMDApO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUmVjb3JkZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUmVjb3JkZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFJlY29yZGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydChSZWNvcmRlci5zdXBwb3J0ZWQsIFwiTWVkaWEgUmVjb3JkZXIgQVBJIGlzIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICAgIHRoaXMuX3N0cmVhbSA9IHRoaXMuY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9zdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuX3N0cmVhbS5zdHJlYW0sIHtcbiAgICAgICAgICAgIG1pbWVUeXBlOiBvcHRpb25zLm1pbWVUeXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW1lIHR5cGUgaXMgdGhlIGZvcm1hdCB0aGF0IHRoZSBhdWRpbyBpcyBlbmNvZGVkIGluLiBGb3IgQ2hyb21lXG4gICAgICogdGhhdCBpcyB0eXBpY2FsbHkgd2VibSBlbmNvZGVkIGFzIFwidm9yYmlzXCIuXG4gICAgICovXG4gICAgZ2V0IG1pbWVUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVjb3JkZXIubWltZVR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlc3QgaWYgeW91ciBwbGF0Zm9ybSBzdXBwb3J0cyB0aGUgTWVkaWEgUmVjb3JkZXIgQVBJLiBJZiBpdCdzIG5vdCBhdmFpbGFibGUsXG4gICAgICogdHJ5IGluc3RhbGxpbmcgdGhpcyAocG9seWZpbGwpW2h0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2F1ZGlvLXJlY29yZGVyLXBvbHlmaWxsXS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHN1cHBvcnRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoZVdpbmRvdyAhPT0gbnVsbCAmJiBSZWZsZWN0Lmhhcyh0aGVXaW5kb3csIFwiTWVkaWFSZWNvcmRlclwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgUmVjb3JkZXIsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIgb3IgXCJwYXVzZWRcIlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3JlY29yZGVyLnN0YXRlID09PSBcImluYWN0aXZlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBcInN0b3BwZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9yZWNvcmRlci5zdGF0ZSA9PT0gXCJwYXVzZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIFwicGF1c2VkXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gXCJzdGFydGVkXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIFJlY29yZGVyLiBSZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlc1xuICAgICAqIHdoZW4gdGhlIHJlY29yZGVyIGhhcyBzdGFydGVkLlxuICAgICAqL1xuICAgIHN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgIT09IFwic3RhcnRlZFwiLCBcIlJlY29yZGVyIGlzIGFscmVhZHkgc3RhcnRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ldyBQcm9taXNlKGRvbmUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZVN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5yZW1vdmVFdmVudExpc3RlbmVyKFwic3RhcnRcIiwgaGFuZGxlU3RhcnQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuYWRkRXZlbnRMaXN0ZW5lcihcInN0YXJ0XCIsIGhhbmRsZVN0YXJ0LCBmYWxzZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnN0YXJ0KCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgc3RhcnRQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcmVjb3JkZXIuIFJldHVybnMgYSBwcm9taXNlIHdpdGggdGhlIHJlY29yZGVkIGNvbnRlbnQgdW50aWwgdGhpcyBwb2ludFxuICAgICAqIGVuY29kZWQgYXMgW1ttaW1lVHlwZV1dXG4gICAgICovXG4gICAgc3RvcCgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLnN0YXRlICE9PSBcInN0b3BwZWRcIiwgXCJSZWNvcmRlciBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFQcm9taXNlID0gbmV3IFByb21pc2UoZG9uZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlRGF0YSA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJkYXRhYXZhaWxhYmxlXCIsIGhhbmRsZURhdGEsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShlLmRhdGEpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuYWRkRXZlbnRMaXN0ZW5lcihcImRhdGFhdmFpbGFibGVcIiwgaGFuZGxlRGF0YSwgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgZGF0YVByb21pc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgcmVjb3JkZXJcbiAgICAgKi9cbiAgICBwYXVzZSgpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiLCBcIlJlY29yZGVyIG11c3QgYmUgc3RhcnRlZFwiKTtcbiAgICAgICAgdGhpcy5fcmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0cmVhbS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVJlY29yZGVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENvbXByZXNzb3IgaXMgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBXZWIgQXVkaW9cbiAqIFtEeW5hbWljc0NvbXByZXNzb3JOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1keW5hbWljc2NvbXByZXNzb3Jub2RlLWludGVyZmFjZSkuXG4gKiBDb21wcmVzc2lvbiByZWR1Y2VzIHRoZSB2b2x1bWUgb2YgbG91ZCBzb3VuZHMgb3IgYW1wbGlmaWVzIHF1aWV0IHNvdW5kc1xuICogYnkgbmFycm93aW5nIG9yIFwiY29tcHJlc3NpbmdcIiBhbiBhdWRpbyBzaWduYWwncyBkeW5hbWljIHJhbmdlLlxuICogUmVhZCBtb3JlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0R5bmFtaWNfcmFuZ2VfY29tcHJlc3Npb24pLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbXAgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJyYXRpb1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbXByZXNzb3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBjb21wcmVzc29yIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9jb21wcmVzc29yO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2NvbXByZXNzb3I7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwicmF0aW9cIl0pO1xuICAgICAgICB0aGlzLnRocmVzaG9sZCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy50aHJlc2hvbGQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2subWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2subWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2ssXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5hdHRhY2ssXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmVsZWFzZS5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJlbGVhc2UubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmVsZWFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMua25lZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5rbmVlLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3Iua25lZS5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3Iua25lZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5rbmVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yYXRpbyA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yYXRpby5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJhdGlvLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5yYXRpbyxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yYXRpbyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNldCB0aGUgZGVmYXVsdHNcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wia25lZVwiLCBcInJlbGVhc2VcIiwgXCJhdHRhY2tcIiwgXCJyYXRpb1wiLCBcInRocmVzaG9sZFwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2s6IDAuMDAzLFxuICAgICAgICAgICAga25lZTogMzAsXG4gICAgICAgICAgICByYXRpbzogMTIsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjI1LFxuICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlYWQtb25seSBkZWNpYmVsIHZhbHVlIGZvciBtZXRlcmluZyBwdXJwb3NlcywgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGFtb3VudCBvZiBnYWluXG4gICAgICogcmVkdWN0aW9uIHRoYXQgdGhlIGNvbXByZXNzb3IgaXMgYXBwbHlpbmcgdG8gdGhlIHNpZ25hbC4gSWYgZmVkIG5vIHNpZ25hbCB0aGUgdmFsdWUgd2lsbCBiZSAwIChubyBnYWluIHJlZHVjdGlvbikuXG4gICAgICovXG4gICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXByZXNzb3IucmVkdWN0aW9uO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmF0dGFjay5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmVsZWFzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yYXRpby5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMua25lZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR3JlYXRlclRoYW4gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0dyZWF0ZXJUaGFuXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBGb2xsb3dlciB9IGZyb20gXCIuLi9hbmFseXNpcy9Gb2xsb3dlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG4vKipcbiAqIEdhdGUgb25seSBwYXNzZXMgYSBzaWduYWwgdGhyb3VnaCB3aGVuIHRoZSBpbmNvbWluZ1xuICogc2lnbmFsIGV4Y2VlZHMgYSBzcGVjaWZpZWQgdGhyZXNob2xkLiBJdCB1c2VzIFtbRm9sbG93ZXJdXSB0byBmb2xsb3cgdGhlIGFtcGx0aXVkZVxuICogb2YgdGhlIGluY29taW5nIHNpZ25hbCBhbmQgY29tcGFyZXMgaXQgdG8gdGhlIFtbdGhyZXNob2xkXV0gdmFsdWUgdXNpbmcgW1tHcmVhdGVyVGhhbl1dLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBnYXRlID0gbmV3IFRvbmUuR2F0ZSgtMzAsIDAuMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCkuY29ubmVjdChnYXRlKTtcbiAqIC8vIHRoZSBnYXRlIHdpbGwgb25seSBwYXNzIHRocm91Z2ggdGhlIGluY29taW5nXG4gKiAvLyBzaWduYWwgd2hlbiBpdCdzIGxvdWRlciB0aGFuIC0zMGRiXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR2F0ZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInNtb290aGluZ1wiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYXRlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHYXRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIgPSBuZXcgRm9sbG93ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiBvcHRpb25zLnNtb290aGluZyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2d0ID0gbmV3IEdyZWF0ZXJUaGFuKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBkYlRvR2FpbihvcHRpb25zLnRocmVzaG9sZCksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2dhdGUgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fZ2F0ZSk7XG4gICAgICAgIC8vIHRoZSBjb250cm9sIHNpZ25hbFxuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2ZvbGxvd2VyLCB0aGlzLl9ndCwgdGhpcy5fZ2F0ZS5nYWluKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC4xLFxuICAgICAgICAgICAgdGhyZXNob2xkOiAtNDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aHJlc2hvbGQgb2YgdGhlIGdhdGUgaW4gZGVjaWJlbHNcbiAgICAgKi9cbiAgICBnZXQgdGhyZXNob2xkKCkge1xuICAgICAgICByZXR1cm4gZ2FpblRvRGIodGhpcy5fZ3QudmFsdWUpO1xuICAgIH1cbiAgICBzZXQgdGhyZXNob2xkKHRocmVzaCkge1xuICAgICAgICB0aGlzLl9ndC52YWx1ZSA9IGRiVG9HYWluKHRocmVzaCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdHRhY2svZGVjYXkgc3BlZWQgb2YgdGhlIGdhdGUuIFNlZSBbW0ZvbGxvd2VyLnNtb290aGluZ11dXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyhzbW9vdGhpbmdUaW1lKSB7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZyA9IHNtb290aGluZ1RpbWU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2F0ZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG47XG4vKipcbiAqIExpbWl0ZXIgd2lsbCBsaW1pdCB0aGUgbG91ZG5lc3Mgb2YgYW4gaW5jb21pbmcgc2lnbmFsLlxuICogVW5kZXIgdGhlIGhvb2QgaXQncyBjb21wb3NlZCBvZiBhIFtbQ29tcHJlc3Nvcl1dIHdpdGggYSBmYXN0IGF0dGFja1xuICogYW5kIHJlbGVhc2UgYW5kIG1heCBjb21wcmVzc2lvbiByYXRpby5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbGltaXRlciA9IG5ldyBUb25lLkxpbWl0ZXIoLTIwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QobGltaXRlcik7XG4gKiBvc2NpbGxhdG9yLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBMaW1pdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTGltaXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMaW1pdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMaW1pdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCJdKTtcbiAgICAgICAgdGhpcy5fY29tcHJlc3NvciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBDb21wcmVzc29yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHJhdGlvOiAyMCxcbiAgICAgICAgICAgIGF0dGFjazogMC4wMDMsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjAxLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBvcHRpb25zLnRocmVzaG9sZFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQgPSB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ0aHJlc2hvbGRcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB0aHJlc2hvbGQ6IC0xMlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWFkLW9ubHkgZGVjaWJlbCB2YWx1ZSBmb3IgbWV0ZXJpbmcgcHVycG9zZXMsIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBhbW91bnQgb2YgZ2FpblxuICAgICAqIHJlZHVjdGlvbiB0aGF0IHRoZSBjb21wcmVzc29yIGlzIGFwcGx5aW5nIHRvIHRoZSBzaWduYWwuXG4gICAgICovXG4gICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXByZXNzb3IucmVkdWN0aW9uO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRocmVzaG9sZC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxpbWl0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWlkU2lkZVNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5pbXBvcnQgeyBNaWRTaWRlTWVyZ2UgfSBmcm9tIFwiLi4vY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogTWlkU2lkZUNvbXByZXNzb3IgYXBwbGllcyB0d28gZGlmZmVyZW50IGNvbXByZXNzb3JzIHRvIHRoZSBbW21pZF1dXG4gKiBhbmQgW1tzaWRlXV0gc2lnbmFsIGNvbXBvbmVudHMgb2YgdGhlIGlucHV0LiBTZWUgW1tNaWRTaWRlU3BsaXRdXSBhbmQgW1tNaWRTaWRlTWVyZ2VdXS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZUNvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVDb21wcmVzc29yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IE1pZFNpZGVTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlID0gdGhpcy5vdXRwdXQgPSBuZXcgTWlkU2lkZU1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5taWQsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5zaWRlID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLnNpZGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZC5jaGFpbih0aGlzLm1pZCwgdGhpcy5fbWlkU2lkZU1lcmdlLm1pZCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5zaWRlLmNoYWluKHRoaXMuc2lkZSwgdGhpcy5fbWlkU2lkZU1lcmdlLnNpZGUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJtaWRcIiwgXCJzaWRlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1pZDoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiAzLFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMDMsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAyLFxuICAgICAgICAgICAgICAgIGtuZWU6IDE2XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2lkZToge1xuICAgICAgICAgICAgICAgIHJhdGlvOiA2LFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTMwLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAzLFxuICAgICAgICAgICAgICAgIGtuZWU6IDEwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZUNvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGliYW5kU3BsaXQgfSBmcm9tIFwiLi4vY2hhbm5lbC9NdWx0aWJhbmRTcGxpdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBBIGNvbXByZXNzb3Igd2l0aCBzZXBhcmF0ZSBjb250cm9scyBvdmVyIGxvdy9taWQvaGlnaCBkeW5hbWljcy4gU2VlIFtbQ29tcHJlc3Nvcl1dIGFuZCBbW011bHRpYmFuZFNwbGl0XV1cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbXVsdGliYW5kID0gbmV3IFRvbmUuTXVsdGliYW5kQ29tcHJlc3Nvcih7XG4gKiBcdGxvd0ZyZXF1ZW5jeTogMjAwLFxuICogXHRoaWdoRnJlcXVlbmN5OiAxMzAwLFxuICogXHRsb3c6IHtcbiAqIFx0XHR0aHJlc2hvbGQ6IC0xMlxuICogXHR9XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpYmFuZENvbXByZXNzb3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aWJhbmRDb21wcmVzc29yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aWJhbmRTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IHRoaXMuX3NwbGl0dGVyLmxvd0ZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gdGhpcy5fc3BsaXR0ZXIuaGlnaEZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5sb3cgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMubG93LCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm1pZCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmhpZ2ggPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMuaGlnaCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBjb21wcmVzc29yXG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmxvdy5jaGFpbih0aGlzLmxvdywgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5taWQuY2hhaW4odGhpcy5taWQsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuaGlnaC5jaGFpbih0aGlzLmhpZ2gsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiaGlnaFwiLCBcIm1pZFwiLCBcImxvd1wiLCBcImhpZ2hGcmVxdWVuY3lcIiwgXCJsb3dGcmVxdWVuY3lcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiAyNTAsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyMDAwLFxuICAgICAgICAgICAgbG93OiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDYsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMzAsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yNSxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDMsXG4gICAgICAgICAgICAgICAga25lZTogMTBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtaWQ6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhpZ2g6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvdy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NdWx0aWJhbmRDb21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpYmFuZFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbi8qKlxuICogRVEzIHByb3ZpZGVzIDMgZXF1YWxpemVyIGJpbnM6IExvdy9NaWQvSGlnaC5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEVRMyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhFUTMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRVEzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhFUTMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX211bHRpYmFuZFNwbGl0ID0gbmV3IE11bHRpYmFuZFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogb3B0aW9ucy5sb3dGcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sb3dHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5sb3csXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMubWlkLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2hpZ2hHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5oaWdoLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG93ID0gdGhpcy5fbG93R2Fpbi5nYWluO1xuICAgICAgICB0aGlzLm1pZCA9IHRoaXMuX21pZEdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5oaWdoID0gdGhpcy5faGlnaEdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5RID0gdGhpcy5fbXVsdGliYW5kU3BsaXQuUTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdC5sb3dGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IHRoaXMuX211bHRpYmFuZFNwbGl0LmhpZ2hGcmVxdWVuY3k7XG4gICAgICAgIC8vIHRoZSBmcmVxdWVuY3kgYmFuZHNcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQubG93LmNoYWluKHRoaXMuX2xvd0dhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQubWlkLmNoYWluKHRoaXMuX21pZEdhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuaGlnaC5jaGFpbih0aGlzLl9oaWdoR2FpbiwgdGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCIsIFwibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fbXVsdGliYW5kU3BsaXRdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGlnaDogMCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IDI1MDAsXG4gICAgICAgICAgICBsb3c6IDAsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IDQwMCxcbiAgICAgICAgICAgIG1pZDogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiLCBcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93R2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZEdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9oaWdoR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2guZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FUTMuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ29udm9sdmVyIGlzIGEgd3JhcHBlciBhcm91bmQgdGhlIE5hdGl2ZSBXZWIgQXVkaW9cbiAqIFtDb252b2x2ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1jb252b2x2ZXJub2RlLWludGVyZmFjZSkuXG4gKiBDb252b2x1dGlvbiBpcyB1c2VmdWwgZm9yIHJldmVyYiBhbmQgZmlsdGVyIGVtdWxhdGlvbi4gUmVhZCBtb3JlIGFib3V0IGNvbnZvbHV0aW9uIHJldmVyYiBvblxuICogW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29udm9sdXRpb25fcmV2ZXJiKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6aW5nIHRoZSBjb252b2x2ZXIgd2l0aCBhbiBpbXB1bHNlIHJlc3BvbnNlXG4gKiBjb25zdCBjb252b2x2ZXIgPSBuZXcgVG9uZS5Db252b2x2ZXIoXCIuL3BhdGgvdG8vaXIud2F2XCIpLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnZvbHZlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDb252b2x2ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb252b2x2ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYXRpdmUgQ29udm9sdmVyTm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29udm9sdmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcihvcHRpb25zLnVybCwgYnVmZmVyID0+IHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICAgICAgb3B0aW9ucy5vbmxvYWQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gc2V0IGlmIGl0J3MgYWxyZWFkeSBsb2FkZWQsIHNldCBpdCBpbW1lZGlhdGVseVxuICAgICAgICBpZiAodGhpcy5fYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSB0aGlzLl9idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW5pdGlhbGx5IHNldCBub3JtYWxpemF0aW9uXG4gICAgICAgIHRoaXMubm9ybWFsaXplID0gb3B0aW9ucy5ub3JtYWxpemU7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9jb252b2x2ZXIsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZTogdHJ1ZSxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWQgYW4gaW1wdWxzZSByZXNwb25zZSB1cmwgYXMgYW4gYXVkaW8gYnVmZmVyLlxuICAgICAqIERlY29kZXMgdGhlIGF1ZGlvIGFzeW5jaHJvbm91c2x5IGFuZCBpbnZva2VzXG4gICAgICogdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGF1ZGlvIGJ1ZmZlciBsb2Fkcy5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIGJ1ZmZlciB0byBsb2FkLiBmaWxldHlwZSBzdXBwb3J0IGRlcGVuZHMgb24gdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0geWllbGQgdGhpcy5fYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjb252b2x2ZXIncyBidWZmZXJcbiAgICAgKi9cbiAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiBpdCdzIGFscmVhZHkgZ290IGEgYnVmZmVyLCBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgIGlmICh0aGlzLl9jb252b2x2ZXIuYnVmZmVyKSB7XG4gICAgICAgICAgICAvLyBkaXNjb25uZWN0IHRoZSBvbGQgb25lXG4gICAgICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYW5kIGNvbm5lY3QgYSBuZXcgb25lXG4gICAgICAgICAgICB0aGlzLl9jb252b2x2ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2NvbnZvbHZlciwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmYgPSB0aGlzLl9idWZmZXIuZ2V0KCk7XG4gICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSBidWZmID8gYnVmZiA6IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBub3JtYWxpemUgcHJvcGVydHkgb2YgdGhlIENvbnZvbHZlck5vZGUgaW50ZXJmYWNlIGlzIGEgYm9vbGVhbiB0aGF0XG4gICAgICogY29udHJvbHMgd2hldGhlciB0aGUgaW1wdWxzZSByZXNwb25zZSBmcm9tIHRoZSBidWZmZXIgd2lsbCBiZSBzY2FsZWQgYnlcbiAgICAgKiBhbiBlcXVhbC1wb3dlciBub3JtYWxpemF0aW9uIHdoZW4gdGhlIGJ1ZmZlciBhdHRyaWJ1dGUgaXMgc2V0LCBvciBub3QuXG4gICAgICovXG4gICAgZ2V0IG5vcm1hbGl6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZvbHZlci5ub3JtYWxpemU7XG4gICAgfVxuICAgIHNldCBub3JtYWxpemUobm9ybSkge1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIubm9ybWFsaXplID0gbm9ybTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db252b2x2ZXIuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvQW5hbHlzZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL01ldGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9GRlRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0RDTWV0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL1dhdmVmb3JtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9Gb2xsb3dlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9DaGFubmVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NZXJnZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01vbm9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUGFubmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1Bhbm5lcjNEXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1BhblZvbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9SZWNvcmRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Tb2xvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1NwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1ZvbHVtZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvQ29tcHJlc3NvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvR2F0ZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTGltaXRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTWlkU2lkZUNvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL011bHRpYmFuZENvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52ZWxvcGUvRnJlcXVlbmN5RW52ZWxvcGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9FUTNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9GaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9PbmVQb2xlRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9Db252b2x2ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9CaXF1YWRGaWx0ZXJcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL2NvcmUvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NvdXJjZS9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc2lnbmFsL2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnN0cnVtZW50L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ldmVudC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZWZmZWN0L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb21wb25lbnQvaW5kZXhcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsYXNzZXMuanMubWFwIiwiZXhwb3J0IHsgZ2V0Q29udGV4dCwgc2V0Q29udGV4dCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jbGFzc2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92ZXJzaW9uXCI7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmV4cG9ydCB7IHN0YXJ0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmV4cG9ydCB7IHN1cHBvcnRlZCB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbi8qKlxuICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIG9mIHRoZSBnbG9iYWwgW1tDb250ZXh0XV0uXG4gKiBTZWUgW1tDb250ZXh0Lm5vd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm93KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkubm93KCk7XG59XG4vKipcbiAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBvZiB0aGUgZ2xvYmFsIFtbQ29udGV4dF1dIHdpdGhvdXQgdGhlIFtbQ29udGV4dC5sb29rQWhlYWRdXVxuICogU2VlIFtbQ29udGV4dC5pbW1lZGlhdGVdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGltbWVkaWF0ZSgpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmltbWVkaWF0ZSgpO1xufVxuLyoqXG4gKiBUaGUgVHJhbnNwb3J0IG9iamVjdCBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tUcmFuc3BvcnRdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRyYW5zcG9ydCA9IGdldENvbnRleHQoKS50cmFuc3BvcnQ7XG4vKipcbiAqIFRoZSBUcmFuc3BvcnQgb2JqZWN0IGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW1RyYW5zcG9ydF1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNwb3J0KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkudHJhbnNwb3J0O1xufVxuLyoqXG4gKiBUaGUgRGVzdGluYXRpb24gKG91dHB1dCkgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbRGVzdGluYXRpb25dXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IERlc3RpbmF0aW9uID0gZ2V0Q29udGV4dCgpLmRlc3RpbmF0aW9uO1xuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgW1tEZXN0aW5hdGlvbl1dXG4gKi9cbmV4cG9ydCBjb25zdCBNYXN0ZXIgPSBnZXRDb250ZXh0KCkuZGVzdGluYXRpb247XG4vKipcbiAqIFRoZSBEZXN0aW5hdGlvbiAob3V0cHV0KSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tEZXN0aW5hdGlvbl1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVzdGluYXRpb24oKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5kZXN0aW5hdGlvbjtcbn1cbi8qKlxuICogVGhlIFtbTGlzdGVuZXJdXSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgTGlzdGVuZXIgPSBnZXRDb250ZXh0KCkubGlzdGVuZXI7XG4vKipcbiAqIFRoZSBbW0xpc3RlbmVyXV0gYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExpc3RlbmVyKCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkubGlzdGVuZXI7XG59XG4vKipcbiAqIERyYXcgaXMgdXNlZCB0byBzeW5jaHJvbml6ZSB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUcmFuc3BvcnQncyBjYWxsYmFja3MuXG4gKiBTZWUgW1tEcmF3XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBEcmF3ID0gZ2V0Q29udGV4dCgpLmRyYXc7XG4vKipcbiAqIEdldCB0aGUgc2luZ2xldG9uIGF0dGFjaGVkIHRvIHRoZSBnbG9iYWwgY29udGV4dC5cbiAqIERyYXcgaXMgdXNlZCB0byBzeW5jaHJvbml6ZSB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUcmFuc3BvcnQncyBjYWxsYmFja3MuXG4gKiBTZWUgW1tEcmF3XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREcmF3KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkuZHJhdztcbn1cbi8qKlxuICogQSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBjb250ZXh0XG4gKiBTZWUgW1tDb250ZXh0XV1cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4vKipcbiAqIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIGxvYWRpbmcgcHJvbWlzZXMgYXJlIHJlc29sdmVkLlxuICogQWxpYXMgZm9yIHN0YXRpYyBbW1RvbmVBdWRpb0J1ZmZlci5sb2FkZWRdXSBtZXRob2QuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZGVkKCkge1xuICAgIHJldHVybiBUb25lQXVkaW9CdWZmZXIubG9hZGVkKCk7XG59XG4vLyB0aGlzIGZpbGxzIGluIG5hbWUgY2hhbmdlcyBmcm9tIDEzLnggdG8gMTQueFxuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5leHBvcnQgY29uc3QgQnVmZmVyID0gVG9uZUF1ZGlvQnVmZmVyO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlcnMgPSBUb25lQXVkaW9CdWZmZXJzO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlclNvdXJjZSA9IFRvbmVCdWZmZXJTb3VyY2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgU3RhcnRBdWRpb0NvbnRleHQgZnJvbSBcIi4vc3RhcnRBdWRpb0NvbnRleHRcIjtcblxuY29uc3QgaXNJcGhvbmUgPVxuICBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBvZC9pKTtcbmNvbnN0IGlzSXBhZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSk7XG5jb25zdCBpc0FuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpO1xuY29uc3QgaXNNb2JpbGUgPSBpc0lwaG9uZSB8fCBpc0lwYWQgfHwgaXNBbmRyb2lkO1xuY29uc3QgaXNEZXNrdG9wID0gIWlzTW9iaWxlO1xuXG5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCIpO1xuXG5leHBvcnQgY29uc3QgYnJvd3NlciA9IHsgaXNJcGhvbmUsIGlzSXBhZCwgaXNNb2JpbGUsIGlzRGVza3RvcCB9O1xuZXhwb3J0IGNvbnN0IGNob2ljZSA9IChhKSA9PiBhW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGEubGVuZ3RoKV07XG5leHBvcnQgY29uc3QgbW9kID0gKG4sIG0pID0+IG4gLSBtICogTWF0aC5mbG9vcihuIC8gbSk7XG5leHBvcnQgY29uc3QgcmFuZG9tID0gKCkgPT4gTWF0aC5yYW5kb20oKTtcbmV4cG9ydCBjb25zdCByYW5kID0gKG4pID0+IE1hdGgucmFuZG9tKCkgKiBuO1xuZXhwb3J0IGNvbnN0IHJhbmRpbnQgPSAobikgPT4gcmFuZChuKSB8IDA7XG5leHBvcnQgY29uc3QgcmFuZHJhbmdlID0gKGEsIGIpID0+IGEgKyByYW5kKGIgLSBhKTtcbmV4cG9ydCBjb25zdCByYW5kc2lnbiA9ICgpID0+IChyYW5kb20oKSA+PSAwLjUgPyAtMSA6IDEpO1xuZXhwb3J0IGNvbnN0IHJhbmRudWxsc2lnbiA9ICgpID0+IHtcbiAgdmFyIHIgPSByYW5kb20oKTtcbiAgcmV0dXJuIHIgPCAwLjMzMyA/IC0xIDogciA8IDAuNjY2ID8gMCA6IDE7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcmVxdWVzdEF1ZGlvQ29udGV4dChmbikge1xuICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBidXR0b24uaW5uZXJIVE1MID0gXCJUYXAgdG8gc3RhcnQgLSBwbGVhc2UgdW5tdXRlIHlvdXIgcGhvbmVcIjtcbiAgT2JqZWN0LmFzc2lnbihjb250YWluZXIuc3R5bGUsIHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgaGVpZ2h0OiBcIjEwMCVcIixcbiAgICB6SW5kZXg6IFwiMTAwMDBcIixcbiAgICB0b3A6IFwiMHB4XCIsXG4gICAgbGVmdDogXCIwcHhcIixcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IFwicmdiYSgwLCAwLCAwLCAwLjgpXCIsXG4gIH0pO1xuICBPYmplY3QuYXNzaWduKGJ1dHRvbi5zdHlsZSwge1xuICAgIGRpc3BsYXk6IFwiYmxvY2tcIixcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIGxlZnQ6IFwiNTAlXCIsXG4gICAgdG9wOiBcIjUwJVwiLFxuICAgIHBhZGRpbmc6IFwiMjBweFwiLFxuICAgIGJhY2tncm91bmRDb2xvcjogXCIjN0YzM0VEXCIsXG4gICAgY29sb3I6IFwid2hpdGVcIixcbiAgICBmb250RmFtaWx5OiBcIm1vbm9zcGFjZVwiLFxuICAgIGJvcmRlclJhZGl1czogXCIzcHhcIixcbiAgICB0cmFuc2Zvcm06IFwidHJhbnNsYXRlM0QoLTUwJSwtNTAlLDApXCIsXG4gICAgdGV4dEFsaWduOiBcImNlbnRlclwiLFxuICAgIGxpbmVIZWlnaHQ6IFwiMS41XCIsXG4gICAgd2lkdGg6IFwiMTUwcHhcIixcbiAgfSk7XG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChidXR0b24pO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gIFN0YXJ0QXVkaW9Db250ZXh0LnNldENvbnRleHQoVG9uZS5jb250ZXh0KTtcbiAgU3RhcnRBdWRpb0NvbnRleHQub24oYnV0dG9uKTtcbiAgU3RhcnRBdWRpb0NvbnRleHQub25TdGFydGVkKChfKSA9PiB7XG4gICAgY29udGFpbmVyLnJlbW92ZSgpO1xuICAgIGZuKCk7XG4gIH0pO1xufVxuIiwiLyoqXG4gKiBSZWxhYmkgd2F2ZWZvcm0gZGlzcGxheVxuICogQG1vZHVsZSBzcmMvcmVsYWJpL2NhbnZhcy5qcztcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWxhYmlDYW52YXMge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSByZWxhYmkgd2F2ZSByZW5kZXJlclxuICAgKi9cbiAgY29uc3RydWN0b3IoeyByZWxhYmksIHBhcmVudCB9KSB7XG4gICAgdGhpcy5yZWxhYmkgPSByZWxhYmk7XG4gICAgdGhpcy5oZWlnaHQgPSA0MDA7XG4gICAgdGhpcy5sYXN0RnJhbWUgPSAwO1xuICAgIHRoaXMubGFzdEFwcGVuZFRpbWUgPSAwO1xuICAgIHRoaXMubGFzdEFwcGVuZEZyYW1lID0gMDtcblxuICAgIC8vIFNwZWVkIG9mIHRoZSB3YXZlIGluIHBpeGVscyBwZXIgc2Vjb25kXG4gICAgdGhpcy5zcGVlZCA9IDEgLyA1O1xuXG4gICAgLy8gUG9zaXRpb24gb2YgY3VycmVudCB0aW1lIG9uIHRoZSBzY3JlZW4sIGZyb20gdGhlIGxlZnRcbiAgICB0aGlzLnRaZXJvT2Zmc2V0ID0gMjA7XG5cbiAgICAvLyBBdHRhY2ggdG8gdGhlIERPTVxuICAgIHRoaXMuYXBwZW5kQ2FudmFzKHBhcmVudCk7XG4gICAgLy8gSW5pdGlhbGl6ZSBhcnJheVxuICAgIHRoaXMudmFsdWVzID0gbmV3IEFycmF5KHdpbmRvdy5pbm5lcldpZHRoKS5maWxsKDApO1xuICAgIHRoaXMubm90ZXMgPSBbXTtcbiAgICB0aGlzLmFwcGVuZChbXSk7XG5cbiAgICAvLyBDbGVhciB0aGUgY2FudmFzXG4gICAgdGhpcy5yZXNpemUoKTtcblxuICAgIC8vIFN0YXJ0IGRyYXdpbmdcbiAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZSgwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIGNhbnZhc1xuICAgKi9cbiAgYXBwZW5kQ2FudmFzKHBhcmVudCkge1xuICAgIHRoaXMucGFyZW50ID0gcGFyZW50IHx8IGRvY3VtZW50LmJvZHk7XG4gICAgdGhpcy5jYW52YXMgPSB0aGlzLmNhbnZhcyB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgIHRoaXMuY3R4ID0gdGhpcy5jdHggfHwgdGhpcy5jYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuY2FudmFzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSBuZXh0IGZyYW1lXG4gICAqL1xuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnJhbWUpIHtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKGZyYW1lKSA9PiB7XG4gICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZShmcmFtZSk7XG4gICAgfSk7XG4gICAgdGhpcy5wYWludChmcmFtZSk7XG4gICAgdGhpcy5sYXN0RnJhbWUgPSBmcmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgd2luZG93IHJlc2l6ZVxuICAgKi9cbiAgcmVzaXplKCkge1xuICAgIHRoaXMuY2FudmFzLndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgdGhlIGNhbnZhc1xuICAgKi9cbiAgY2xlYXIoKSB7XG4gICAgdGhpcy5jdHguY2xlYXJSZWN0KDAsIDAsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZCB2YWx1ZXNcbiAgICovXG4gIGFwcGVuZCh0aW1lLCB2YWx1ZXMsIG5vdGVzKSB7XG4gICAgdGhpcy5sYXN0QXBwZW5kVGltZSA9IHRpbWU7XG4gICAgdGhpcy5sYXN0QXBwZW5kRnJhbWUgPSB0aGlzLmxhc3RGcmFtZTtcbiAgICB0aGlzLnZhbHVlcyA9IHRoaXMudmFsdWVzXG4gICAgICAuY29uY2F0KHZhbHVlcylcbiAgICAgIC5zbGljZSgtdGhpcy5jYW52YXMud2lkdGgpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuXG4gICAgaWYgKG5vdGVzPy5sZW5ndGgpIHtcbiAgICAgIHRoaXMubm90ZXMgPSB0aGlzLm5vdGVzXG4gICAgICAgIC5jb25jYXQobm90ZXMpXG4gICAgICAgIC5zbGljZSgtNTApXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhaW50IHRoZSBjYW52YXNcbiAgICovXG4gIHBhaW50KGZyYW1lKSB7XG4gICAgdGhpcy5jbGVhcigpO1xuICAgIHRoaXMuZHJhd1JlbGFiaVdhdmUoZnJhbWUpO1xuICAgIHRoaXMuZHJhd0JvdW5kcygpO1xuICAgIHRoaXMuZHJhd05vdGVzKGZyYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSBib3VuZHNcbiAgICovXG4gIGRyYXdCb3VuZHMoKSB7XG4gICAgY29uc3QgeyBjYW52YXMsIGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNhbnZhcztcblxuICAgIC8vIERyYXcgZGFzaGVkIGxpbmVzIGZvciBhbGwgYm91bmRzXG4gICAgZm9yIChjb25zdCBib3VuZCBvZiB0aGlzLnJlbGFiaS5ib3VuZHMpIHtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KGJvdW5kLmxldmVsLCBoZWlnaHQpO1xuXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHguc2V0TGluZURhc2goWzQsIDRdKTtcbiAgICAgIGN0eC5saW5lV2lkdGggPSAxO1xuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gYm91bmQuY29sb3IgfHwgXCIjODg4XCI7XG4gICAgICBjdHgubW92ZVRvKDAsIHkpO1xuICAgICAgY3R4LmxpbmVUbyh3aWR0aCwgeSk7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgLy8gRHJhdyB0aGUgemVybyBwb3NpdGlvblxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHguc2V0TGluZURhc2goWzEsIDFdKTtcbiAgICBjdHgubGluZVdpZHRoID0gMjtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBcIiM2NjZcIjtcbiAgICBjdHgubW92ZVRvKHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCwgMCk7XG4gICAgY3R4LmxpbmVUbyh3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQsIGhlaWdodCk7XG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIHJlbGFiaSB3YXZlXG4gICAqL1xuICBkcmF3UmVsYWJpV2F2ZShmcmFtZSkge1xuICAgIGNvbnN0IHsgY2FudmFzLCBjdHggfSA9IHRoaXM7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBjYW52YXM7XG5cbiAgICBjb25zdCBwb2ludENvdW50ID0gdGhpcy52YWx1ZXMubGVuZ3RoO1xuICAgIGxldCBpbmRleCA9IDA7XG5cbiAgICAvLyBTdGFydCB0aGUgcGF0aFxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBcIiNkZmZcIjtcbiAgICBjdHgubGluZVdpZHRoID0gMC43NTtcbiAgICBjdHguc2V0TGluZURhc2goW10pO1xuXG4gICAgLy8gVGhpcyBpcyB0aGUgb2Zmc2V0IGluIHNlY29uZHMgZnJvbSB0aGUgbGFzdCBmcmFtZSB3ZSBjb21wdXRlZFxuICAgIGNvbnN0IGZyYW1lT2Zmc2V0ID0gKGZyYW1lIC0gdGhpcy5sYXN0QXBwZW5kRnJhbWUpIC8gMTAwMDtcblxuICAgIC8vIE1ha2UgYSBwYXRoIGNvbm5lY3RpbmcgYWxsIHZhbHVlc1xuICAgIGZvciAoY29uc3QgcG9pbnQgb2YgdGhpcy52YWx1ZXMpIHtcbiAgICAgIGlmICghcG9pbnQpIHtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFt0aW1lLCB2YWx1ZV0gPSBwb2ludDtcblxuICAgICAgLy8gVGhpcyBpcyB0aGUgb2Zmc2V0IG9mIHRoaXMgdGltZSBmcm9tIGN1cnJlbnQgdGltZVxuICAgICAgLy8gSWYgdGhpcyBpcyBpbiB0aGUgZnV0dXJlLCBpdCB3aWxsIGJlIHBvc2l0aXZlLlxuICAgICAgLy8gU3VidHJhY3RpbmcgdGhlIGZyYW1lIG9mZnNldCBwdWxscyBpdCBuZWdhdGl2ZS5cbiAgICAgIGNvbnN0IHRpbWVPZmZzZXQgPSB0aGlzLmxhc3RBcHBlbmRUaW1lICsgZnJhbWVPZmZzZXQgLSB0aW1lO1xuXG4gICAgICBjb25zdCB4ID0gd2lkdGggLSB0aW1lT2Zmc2V0ICogdGhpcy5zcGVlZCAqIHdpZHRoIC0gdGhpcy50WmVyb09mZnNldDtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KHZhbHVlLCBoZWlnaHQpO1xuXG4gICAgICBpZiAoeCA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICBjdHgubW92ZVRvKHgsIHkpO1xuICAgICAgfVxuICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcbiAgICAgIGluZGV4ICs9IDE7XG4gICAgfVxuXG4gICAgLy8gUGFpbnQgdGhlIGxpbmVcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cblxuICAvKipcbiAgICogRHJhdyB0aGUgbm90ZXNcbiAgICovXG4gIGRyYXdOb3RlcyhmcmFtZSkge1xuICAgIGNvbnN0IHsgY2FudmFzLCBjdHggfSA9IHRoaXM7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBjYW52YXM7XG5cbiAgICAvLyBUaGlzIGlzIHRoZSBvZmZzZXQgaW4gc2Vjb25kcyBmcm9tIHRoZSBsYXN0IGZyYW1lIHdlIGNvbXB1dGVkXG4gICAgY29uc3QgZnJhbWVPZmZzZXQgPSAoZnJhbWUgLSB0aGlzLmxhc3RBcHBlbmRGcmFtZSkgLyAxMDAwO1xuXG4gICAgLy8gTWFrZSBhIHBhdGggY29ubmVjdGluZyBhbGwgdmFsdWVzXG4gICAgZm9yIChjb25zdCBub3RlIG9mIHRoaXMubm90ZXMpIHtcbiAgICAgIGNvbnN0IFt0aW1lLCB2YWx1ZSwgZGlyZWN0aW9uXSA9IG5vdGU7XG4gICAgICBjb25zdCB0aW1lT2Zmc2V0ID0gdGhpcy5sYXN0QXBwZW5kVGltZSArIGZyYW1lT2Zmc2V0IC0gdGltZTtcbiAgICAgIGNvbnN0IHggPSB3aWR0aCAtIHRpbWVPZmZzZXQgKiB0aGlzLnNwZWVkICogd2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0O1xuICAgICAgY29uc3QgeSA9IGdldFdhdmVIZWlnaHQodmFsdWUsIGhlaWdodCk7XG5cbiAgICAgIC8vIERvbid0IGRyYXcgbm90ZXMgdGhhdCBoYXZlbid0IHBsYXllZCB5ZXRcbiAgICAgIGlmICh4ID4gd2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBEcmF3IG5vdGVzIGFzIGEgZG90IHRoYXQgZmFkZXMgb3V0XG4gICAgICBjb25zdCBvcGFjaXR5ID0gMSAtICh0aW1lT2Zmc2V0ICogdGhpcy5zcGVlZCAqIHdpZHRoKSAvIDEwMDA7XG4gICAgICBpZiAob3BhY2l0eSA8IDAuMDAxKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgY3R4LmFyYyh4IC0gMi41LCB5LCA1LCAwLCAyICogTWF0aC5QSSk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gZGlyZWN0aW9uXG4gICAgICAgID8gYHJnYmEoMjU1LDEyOCwxOTIsJHtvcGFjaXR5fSlgXG4gICAgICAgIDogYHJnYmEoMTkyLDI1NSwxMjgsJHtvcGFjaXR5fSlgO1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGhlaWdodCBvZiB0aGUgd2F2ZSBhdCBhIGdpdmVuIHZhbHVlXG4gKi9cbmNvbnN0IGdldFdhdmVIZWlnaHQgPSAodmFsdWUsIGhlaWdodCkgPT4gKCh2YWx1ZSArIDEpIC8gMikgKiBoZWlnaHQ7XG4iLCIvKipcbiAqIFJlbGFiaSBldmVudCBnZW5lcmF0b3JcbiAqL1xuXG5pbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgUmVsYWJpQ2FudmFzIGZyb20gXCIuL2NhbnZhc1wiO1xuXG5jb25zdCBUV09fUEkgPSAyICogTWF0aC5QSTtcblxuLyoqXG4gKiBXYXZlIGZ1bmN0aW9uc1xuICovXG5jb25zdCBXQVZFX0ZVTkNUSU9OUyA9IHtcbiAgc2luZTogTWF0aC5jb3MsXG4gIHRyaWFuZ2xlOiAodGltZSkgPT5cbiAgICAoNCAvIFRXT19QSSkgKlxuICAgICAgTWF0aC5hYnMoXG4gICAgICAgICgoKCh0aW1lIC0gVFdPX1BJIC8gNCkgJSBUV09fUEkpICsgVFdPX1BJKSAlIFRXT19QSSkgLSBUV09fUEkgLyAyXG4gICAgICApIC1cbiAgICAxLFxuICBzcXVhcmU6ICh0aW1lKSA9PiAodGltZSAlIFRXT19QSSA8IE1hdGguUEkgPyAxIDogLTEpLFxuICBzYXc6ICh0aW1lKSA9PiAoKHRpbWUgJSBUV09fUEkpIC0gTWF0aC5QSSkgLyBNYXRoLlBJLFxufTtcblxuLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbGFiaSB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGdlbmVyYXRvclxuICAgKi9cbiAgY29uc3RydWN0b3IoeyB3YXZlcywgYm91bmRzLCBwYXJlbnQgfSkge1xuICAgIHRoaXMudXBkYXRlVGltZSA9IDE7XG4gICAgdGhpcy5zdGVwcyA9IDUwO1xuICAgIHRoaXMud2F2ZXMgPSB3YXZlcyB8fCBbXG4gICAgICB7IHR5cGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC41LCAxLjUpIH0sXG4gICAgICB7IHR5cGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC43NSwgMi4yNSkgfSxcbiAgICAgIHsgdHlwZTogXCJ0cmlhbmdsZVwiLCBmcmVxdWVuY3k6IHJhbmRyYW5nZSgxLCAzKSB9LFxuICAgICAgeyB0eXBlOiBcInRyaWFuZ2xlXCIsIGZyZXF1ZW5jeTogcmFuZHJhbmdlKDIsIDQpIH0sXG4gICAgXTtcbiAgICB0aGlzLmJvdW5kcyA9IGJvdW5kcztcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBudWxsO1xuICAgIHRoaXMuY2FudmFzID0gbmV3IFJlbGFiaUNhbnZhcyh7IHJlbGFiaTogdGhpcywgcGFyZW50IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBnZW5lcmF0b3JcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGNvbnNvbGUubG9nKFwiU3RhcnQgUmVsYWJpXCIpO1xuICAgIHRoaXMuc3RvcCgpO1xuICAgIHRoaXMuY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygodGltZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5nZW5lcmF0ZSh0aW1lKTtcbiAgICAgIGNvbnN0IG5vdGVzID0gdGhpcy5wbGF5KHZhbHVlcyk7XG4gICAgICB0aGlzLmNhbnZhcy5hcHBlbmQodGltZSwgdmFsdWVzLCBub3Rlcyk7XG4gICAgfSwgdGhpcy51cGRhdGVUaW1lKTtcbiAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCB0aGUgZ2VuZXJhdG9yIGFuZCByZXNldCBpdFxuICAgKi9cbiAgc3RvcCgpIHtcbiAgICBpZiAodGhpcy5jbG9jaykge1xuICAgICAgdGhpcy5jbG9jay5zdG9wKCk7XG4gICAgICB0aGlzLmNsb2NrLmRpc3Bvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcmVsYWJpIGV2ZW50c1xuICAgKi9cbiAgZ2VuZXJhdGUodGltZSkge1xuICAgIGNvbnN0IHdhdmVDb3VudCA9IHRoaXMud2F2ZXMubGVuZ3RoO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgdmFsdWU7XG4gICAgbGV0IHZhbHVlcyA9IFtdO1xuXG4gICAgLy8gT3ZlcnNob290IHRoZSBsaW5lIHNsaWdodGx5IGVhY2ggdGltZVxuICAgIGxldCBzdGVwQ291bnQgPSB0aGlzLnN0ZXBzICsgMjA7XG5cbiAgICAvLyBHZW5lcmF0ZSBzZXZlcmFsIGV2ZW50cyBwZXIgc2Vjb25kXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHN0ZXBDb3VudDsgc3RlcCArPSAxKSB7XG4gICAgICAvLyBUaW1lIG9mZnNldCBmb3IgdGhpcyBldmVudFxuICAgICAgY29uc3QgdGltZU9mZnNldCA9IHRpbWUgKyAoc3RlcCAqIHRoaXMudXBkYXRlVGltZSkgLyB0aGlzLnN0ZXBzO1xuXG4gICAgICAvLyBJbml0aWFsaXplIHZhbHVlXG4gICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgIC8vIENvbXB1dGUgdGhlIHdhdmUgZnVuY3Rpb25zIGZvciB0aGlzIGV2ZW50XG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCB3YXZlQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgY29uc3Qgd2F2ZSA9IHRoaXMud2F2ZXNbaW5kZXhdO1xuICAgICAgICB2YWx1ZSArPSBXQVZFX0ZVTkNUSU9OU1t3YXZlLnR5cGVdKHRpbWVPZmZzZXQgKiB3YXZlLmZyZXF1ZW5jeSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNjYWxlIHRvIFstMSwgMV1cbiAgICAgIHZhbHVlIC89IHdhdmVDb3VudDtcblxuICAgICAgdmFsdWVzLnB1c2goW3RpbWVPZmZzZXQsIHZhbHVlXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBwbGF5KHZhbHVlcykge1xuICAgIGNvbnN0IGJvdW5kc0NvdW50ID0gdGhpcy5ib3VuZHMubGVuZ3RoO1xuICAgIGxldCBwcmV2aW91c1ZhbHVlID0gdGhpcy5wcmV2aW91c1ZhbHVlO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgbm90ZUNvdW50ID0gMDtcbiAgICBjb25zdCBub3RlcyA9IFtdO1xuXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gR2V0IHRoZSBuZXh0IHZhbHVlXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gdmFsdWVzW3N0ZXBdO1xuXG4gICAgICAvLyBDb21wdXRlIHdoZXRoZXIgd2UgY3Jvc3NlZCBhIGJvdW5kYXJ5LCBhbmQgd2hpY2ggZGlyZWN0aW9uXG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBib3VuZHNDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCBib3VuZCA9IHRoaXMuYm91bmRzW2luZGV4XTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHZhbHVlIDwgYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA8IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIGRvd25cbiAgICAgICAgICB0aGlzLnRyaWdnZXIodGltZSwgYm91bmQuc291bmRzWzBdKTtcbiAgICAgICAgICBub3Rlcy5wdXNoKFt0aW1lLCBib3VuZC5sZXZlbCwgdHJ1ZV0pO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHZhbHVlID4gYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA+IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIHVwXG4gICAgICAgICAgdGhpcy50cmlnZ2VyKHRpbWUsIGJvdW5kLnNvdW5kc1sxXSk7XG4gICAgICAgICAgbm90ZXMucHVzaChbdGltZSwgYm91bmQubGV2ZWwsIGZhbHNlXSk7XG4gICAgICAgICAgbm90ZUNvdW50ICs9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgcHJldmlvdXNWYWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFN0b3JlIHRoZSBsYXRlc3QgdmFsdWVcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBwcmV2aW91c1ZhbHVlO1xuXG4gICAgLy8gUmV0dXJuIHRoZSBub3Rlc1xuICAgIHJldHVybiBub3RlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGV2ZW50XG4gICAqL1xuICB0cmlnZ2VyKHRpbWUsIHNvdW5kKSB7XG4gICAgLy8gY29uc29sZS5sb2coXCJ0cmlnZ2VyIGluZGV4XCIsIGluZGV4LCB0aW1lKTtcbiAgICBzb3VuZC5pbnN0cnVtZW50LnBsYXkodGltZSwgc291bmQpO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5cbmNvbnN0IGNvbXByZXNzb3IgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG5jb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigwLjMpO1xuY29tcHJlc3Nvci5jb25uZWN0KGdhaW4pO1xuZ2Fpbi50b0Rlc3RpbmF0aW9uKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNvbXByZXNzb3I7XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgeyBjaG9pY2UsIHJhbmRyYW5nZSB9IGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCBvdXRwdXQgZnJvbSBcIi4vb3V0cHV0XCI7XG5cbmNvbnN0IFBMQVlFUl9DT1VOVCA9IDQ7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNhbXBsZXIge1xuICBjb25zdHJ1Y3Rvcih7IHNhbXBsZXMsIHRvbmFsIH0pIHtcbiAgICB0aGlzLnRvbmFsID0gdG9uYWw7XG4gICAgdGhpcy5zYW1wbGVzID0gc2FtcGxlcy5tYXAoKHsgLi4uc2FtcGxlIH0pID0+IHtcbiAgICAgIHNhbXBsZS5wbGF5ZXJzID0gW107XG4gICAgICBzYW1wbGUuaW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUExBWUVSX0NPVU5UOyBpKyspIHtcbiAgICAgICAgbGV0IGZuID0gc2FtcGxlLmZuO1xuICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL2FzZGYudXMvKSkge1xuICAgICAgICAgIGZuID0gXCIvL2FzZGYudXMva2FsaW1iYS9cIiArIGZuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoe1xuICAgICAgICAgIHVybDogZm4sXG4gICAgICAgICAgcmV0cmlnZ2VyOiB0cnVlLFxuICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBsYXllci5jb25uZWN0KG91dHB1dCk7XG4gICAgICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW1wbGU7XG4gICAgfSk7XG4gIH1cblxuICBwbGF5KHRpbWUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VuZCA9IG9wdGlvbnMuaW5kZXhcbiAgICAgID8gdGhpcy5zYW1wbGVzW29wdGlvbnMuaW5kZXhdXG4gICAgICA6IGNob2ljZSh0aGlzLnNhbXBsZXMpO1xuXG4gICAgc291bmQuaW5kZXggPSAoc291bmQuaW5kZXggKyAxKSAlIFBMQVlFUl9DT1VOVDtcblxuICAgIGNvbnN0IHBsYXllciA9IHNvdW5kLnBsYXllcnNbc291bmQuaW5kZXhdO1xuXG4gICAgaWYgKHRoaXMudG9uYWwpIHtcbiAgICAgIHBsYXllci5wbGF5YmFja1JhdGUgPVxuICAgICAgICAob3B0aW9ucy5mcmVxdWVuY3kgKiBjaG9pY2UoWzAuNSwgMV0pICsgcmFuZHJhbmdlKDAsIDEwKSkgLyBzb3VuZC5yb290O1xuICAgIH1cblxuICAgIHBsYXllci5zdGFydCh0aW1lIHx8IDApO1xuICB9XG59XG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi9zYW1wbGVyXCI7XG5cbmV4cG9ydCBjb25zdCBLYWxpbWJhID0gbmV3IFNhbXBsZXIoe1xuICB0b25hbDogdHJ1ZSxcbiAgc2FtcGxlczogW1xuICAgIHsgcm9vdDogMjI2LCBmbjogXCJzYW1wbGVzLzM4MDczN19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDEtYS1yYXcubXAzXCIgfSxcbiAgICB7IHJvb3Q6IDI2NywgZm46IFwic2FtcGxlcy8zODA3MzZfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAyLWMtcmF3Lm1wM1wiIH0sXG4gICAgeyByb290OiAzNDAsIGZuOiBcInNhbXBsZXMvMzgwNzM1X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMy1lLXJhdy5tcDNcIiB9LFxuICAgIHsgcm9vdDogNDUyLCBmbjogXCJzYW1wbGVzLzM4MDczM19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDYtYS0wMi1yYXcubXAzXCIgfSxcbiAgXSxcbn0pO1xuXG5leHBvcnQgY29uc3QgRHJ1bXMgPSBuZXcgU2FtcGxlcih7XG4gIHRvbmFsOiBmYWxzZSxcbiAgc2FtcGxlczogW1xuICAgIHsgZm46IFwic2FtcGxlcy83MDdfYmQubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2NsYXAubXAzXCIgfSxcbiAgICAvLyB7IGZuOiBcInNhbXBsZXMvNzA3X2Nvdy5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfaGF0Lm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19yaW0ubXAzXCIgfSxcbiAgXSxcbn0pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yIFVJXG4gKiBAbW9kdWxlIHNyYy91aS9BcHAuanM7XG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBSZWxhYmkgZnJvbSBcIi4uL3JlbGFiaVwiO1xuaW1wb3J0IHsgS2FsaW1iYSwgRHJ1bXMgfSBmcm9tIFwiLi4vbGliL2luc3RydW1lbnRzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFwcCgpIHtcbiAgY29uc3QgW3JlbGFiaSwgc2V0UmVsYWJpXSA9IHVzZVN0YXRlKCk7XG4gIGNvbnN0IHJlbGFiaVJlZiA9IHVzZVJlZigpO1xuXG4gIC8qKlxuICAgKiBJbnN0YW50aWF0ZSB0aGUgUmVsYWJpIGdlbmVyYXRvclxuICAgKi9cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXJlbGFiaSkge1xuICAgICAgY29uc3QgcmVsYWJpR2VuZXJhdG9yID0gbmV3IFJlbGFiaSh7XG4gICAgICAgIHdhdmVzOiBbXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAwLjc1IH0sXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAxLjAgfSxcbiAgICAgICAgICB7IHR5cGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuNjE3IH0sXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAzLjE0MSB9LFxuICAgICAgICBdLFxuICAgICAgICBib3VuZHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogLTAuNzUsXG4gICAgICAgICAgICBjb2xvcjogXCIjZjMzXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDAgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDEgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogMC43NSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiNmODNcIixcbiAgICAgICAgICAgIHNvdW5kczogW1xuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IERydW1zLCBpbmRleDogMiB9LFxuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IERydW1zLCBpbmRleDogMyB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxldmVsOiAtMC4yNSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiMzYjhcIixcbiAgICAgICAgICAgIHNvdW5kczogW1xuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogNDQwIH0sXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiAoNDQwICogMykgLyAyIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGV2ZWw6IDAuMjUsXG4gICAgICAgICAgICBjb2xvcjogXCIjMzZmXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDUgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDcgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgICAgcmVsYWJpR2VuZXJhdG9yLnN0YXJ0KCk7XG4gICAgICBzZXRSZWxhYmkocmVsYWJpR2VuZXJhdG9yKTtcbiAgICB9XG4gIH0sIFtyZWxhYmldKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChyZWxhYmkgJiYgcmVsYWJpUmVmLmN1cnJlbnQpIHtcbiAgICAgIHJlbGFiaS5jYW52YXMuYXBwZW5kQ2FudmFzKHJlbGFiaVJlZi5jdXJyZW50KTtcbiAgICB9XG4gIH0sIFtyZWxhYmksIHJlbGFiaVJlZi5jdXJyZW50XSk7XG5cbiAgLyoqXG4gICAqIFJlbmRlclxuICAgKi9cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBzdHlsZT17e1xuICAgICAgICBoZWlnaHQ6IFwiMTAwJVwiLFxuICAgICAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgICAgIHBhZGRpbmc6IDAsXG4gICAgICAgIG1hcmdpbjogMCxcbiAgICAgICAgZGlzcGxheTogXCJmbGV4XCIsXG4gICAgICAgIGZsZXhEaXJlY3Rpb246IFwiY29sdW1uXCIsXG4gICAgICAgIGp1c3RpZnlDb250ZW50OiBcImNlbnRlclwiLFxuICAgICAgfX1cbiAgICA+XG4gICAgICA8ZGl2IHJlZj17cmVsYWJpUmVmfSAvPlxuICAgIDwvZGl2PlxuICApO1xufVxuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBjcmVhdGVSb290IH0gZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIjtcbmltcG9ydCB7IHJlcXVlc3RBdWRpb0NvbnRleHQsIHJhbmRyYW5nZSB9IGZyb20gXCIuL2xpYi91dGlsXCI7XG5cbmltcG9ydCBBcHAgZnJvbSBcIi4vdWkvQXBwLmpzeFwiO1xuXG5kb2N1bWVudC5ib2R5LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiIzExMVwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5jb2xvciA9IFwiI2ZmZlwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW4gPSAwO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nID0gMDtcbmRvY3VtZW50LmJvZHkuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuc3R5bGUubWFyZ2luID0gMDtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5wYWRkaW5nID0gMDtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuXG5yZXF1ZXN0QXVkaW9Db250ZXh0KCgpID0+IHtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgY29udGFpbmVyLnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuICBjb250YWluZXIuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcbiAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBcIlwiO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KGNvbnRhaW5lcik7XG4gIHJvb3QucmVuZGVyKDxBcHAgLz4pO1xufSk7XG4iXSwibmFtZXMiOlsiVG9uZSIsIlN0YXJ0QXVkaW9Db250ZXh0IiwiaXNJcGhvbmUiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJtYXRjaCIsImlzSXBhZCIsImlzQW5kcm9pZCIsImlzTW9iaWxlIiwiaXNEZXNrdG9wIiwiZG9jdW1lbnQiLCJib2R5IiwiY2xhc3NMaXN0IiwiYWRkIiwiYnJvd3NlciIsImNob2ljZSIsImEiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJsZW5ndGgiLCJtb2QiLCJuIiwibSIsInJhbmQiLCJyYW5kaW50IiwicmFuZHJhbmdlIiwiYiIsInJhbmRzaWduIiwicmFuZG51bGxzaWduIiwiciIsInJlcXVlc3RBdWRpb0NvbnRleHQiLCJmbiIsImNvbnRhaW5lciIsImNyZWF0ZUVsZW1lbnQiLCJidXR0b24iLCJpbm5lckhUTUwiLCJPYmplY3QiLCJhc3NpZ24iLCJzdHlsZSIsImRpc3BsYXkiLCJwb3NpdGlvbiIsIndpZHRoIiwiaGVpZ2h0IiwiekluZGV4IiwidG9wIiwibGVmdCIsImJhY2tncm91bmRDb2xvciIsInBhZGRpbmciLCJjb2xvciIsImZvbnRGYW1pbHkiLCJib3JkZXJSYWRpdXMiLCJ0cmFuc2Zvcm0iLCJ0ZXh0QWxpZ24iLCJsaW5lSGVpZ2h0IiwiYXBwZW5kQ2hpbGQiLCJzZXRDb250ZXh0IiwiY29udGV4dCIsIm9uIiwib25TdGFydGVkIiwiXyIsInJlbW92ZSIsIlJlbGFiaUNhbnZhcyIsIl9yZWYiLCJyZWxhYmkiLCJwYXJlbnQiLCJfY2xhc3NDYWxsQ2hlY2siLCJsYXN0RnJhbWUiLCJsYXN0QXBwZW5kVGltZSIsImxhc3RBcHBlbmRGcmFtZSIsInNwZWVkIiwidFplcm9PZmZzZXQiLCJhcHBlbmRDYW52YXMiLCJ2YWx1ZXMiLCJBcnJheSIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJmaWxsIiwibm90ZXMiLCJhcHBlbmQiLCJyZXNpemUiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsImNhbnZhcyIsImN0eCIsImdldENvbnRleHQiLCJfcmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiX3giLCJhcHBseSIsImFyZ3VtZW50cyIsInRvU3RyaW5nIiwiZnJhbWUiLCJfdGhpcyIsInBhaW50IiwiY2xlYXIiLCJjbGVhclJlY3QiLCJ0aW1lIiwiY29uY2F0Iiwic2xpY2UiLCJzb3J0IiwiZHJhd1JlbGFiaVdhdmUiLCJkcmF3Qm91bmRzIiwiZHJhd05vdGVzIiwiX2l0ZXJhdG9yIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJib3VuZHMiLCJfc3RlcCIsInMiLCJkb25lIiwiYm91bmQiLCJ5IiwiZ2V0V2F2ZUhlaWdodCIsImxldmVsIiwiYmVnaW5QYXRoIiwic2V0TGluZURhc2giLCJsaW5lV2lkdGgiLCJzdHJva2VTdHlsZSIsIm1vdmVUbyIsImxpbmVUbyIsInN0cm9rZSIsImVyciIsImUiLCJmIiwicG9pbnRDb3VudCIsImluZGV4IiwiZnJhbWVPZmZzZXQiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicG9pbnQiLCJfcG9pbnQiLCJfc2xpY2VkVG9BcnJheSIsInRpbWVPZmZzZXQiLCJ4IiwiX2l0ZXJhdG9yMyIsIl9zdGVwMyIsIm5vdGUiLCJfbm90ZSIsImRpcmVjdGlvbiIsIm9wYWNpdHkiLCJhcmMiLCJQSSIsImZpbGxTdHlsZSIsImRlZmF1bHQiLCJUV09fUEkiLCJXQVZFX0ZVTkNUSU9OUyIsInNpbmUiLCJjb3MiLCJ0cmlhbmdsZSIsImFicyIsInNxdWFyZSIsInNhdyIsIlJlbGFiaSIsIndhdmVzIiwidXBkYXRlVGltZSIsInN0ZXBzIiwidHlwZSIsImZyZXF1ZW5jeSIsInByZXZpb3VzVmFsdWUiLCJzdGFydCIsImNvbnNvbGUiLCJsb2ciLCJzdG9wIiwiY2xvY2siLCJDbG9jayIsImdlbmVyYXRlIiwicGxheSIsImRpc3Bvc2UiLCJ3YXZlQ291bnQiLCJzdGVwIiwic3RlcENvdW50Iiwid2F2ZSIsInB1c2giLCJib3VuZHNDb3VudCIsIm5vdGVDb3VudCIsIl92YWx1ZXMkc3RlcCIsInRyaWdnZXIiLCJzb3VuZHMiLCJzb3VuZCIsImluc3RydW1lbnQiLCJjb21wcmVzc29yIiwiQ29tcHJlc3NvciIsImdhaW4iLCJHYWluIiwiY29ubmVjdCIsInRvRGVzdGluYXRpb24iLCJvdXRwdXQiLCJQTEFZRVJfQ09VTlQiLCJTYW1wbGVyIiwic2FtcGxlcyIsInRvbmFsIiwibWFwIiwiX3JlZjIiLCJzYW1wbGUiLCJfZXh0ZW5kcyIsIl9vYmplY3REZXN0cnVjdHVyaW5nRW1wdHkiLCJwbGF5ZXJzIiwiaSIsImxvY2F0aW9uIiwiaHJlZiIsInBsYXllciIsIlBsYXllciIsInVybCIsInJldHJpZ2dlciIsInBsYXliYWNrUmF0ZSIsIm9wdGlvbnMiLCJyb290IiwiS2FsaW1iYSIsIkRydW1zIiwiUmVhY3QiLCJ1c2VTdGF0ZSIsInVzZUVmZmVjdCIsInVzZVJlZiIsIkFwcCIsIl91c2VTdGF0ZSIsIl91c2VTdGF0ZTIiLCJzZXRSZWxhYmkiLCJyZWxhYmlSZWYiLCJyZWxhYmlHZW5lcmF0b3IiLCJjdXJyZW50IiwibWFyZ2luIiwiZmxleERpcmVjdGlvbiIsImp1c3RpZnlDb250ZW50IiwicmVmIiwiY3JlYXRlUm9vdCIsInBhcmVudE5vZGUiLCJyZW5kZXIiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///441\n')},631:function(module,exports){eval('var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }\n/**\n * StartAudioContext.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2016 Yotam Mann\n */\n\nwindow.__audio_context_started = false;\n(function (root, factory) {\n if (true) {\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === \'function\' ?\n\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(this, function () {\n /**\n * The StartAudioContext object\n */\n var StartAudioContext = {\n /**\n * The audio context passed in by the user\n * @type {AudioContext}\n */\n context: null,\n /**\n * The TapListeners bound to the elements\n * @type {Array}\n * @private\n */\n _tapListeners: [],\n /**\n * Callbacks to invoke when the audio context is started\n * @type {Array}\n * @private\n */\n _onStarted: []\n };\n\n /**\n * Set the context\n * @param {AudioContext} ctx\n * @returns {StartAudioContext}\n */\n StartAudioContext.setContext = function (ctx) {\n StartAudioContext.context = ctx;\n return StartAudioContext;\n };\n\n /**\n * Add a tap listener to the audio context\n * @param {Array|Element|String|jQuery} element\n * @returns {StartAudioContext}\n */\n StartAudioContext.on = function (element) {\n if (Array.isArray(element) || NodeList && element instanceof NodeList) {\n for (var i = 0; i < element.length; i++) {\n StartAudioContext.on(element[i]);\n }\n } else if (typeof element === "string") {\n StartAudioContext.on(document.querySelectorAll(element));\n } else if (element.jquery && typeof element.toArray === "function") {\n StartAudioContext.on(element.toArray());\n } else if (Element && element instanceof Element) {\n //if it\'s an element, create a TapListener\n var tap = new TapListener(element, onTap);\n StartAudioContext._tapListeners.push(tap);\n }\n return StartAudioContext;\n };\n\n /**\n * Bind a callback to when the audio context is started.\n * @param {Function} cb\n * @return {StartAudioContext}\n */\n StartAudioContext.onStarted = function (cb) {\n //if it\'s already started, invoke the callback\n if (StartAudioContext.isStarted()) {\n cb();\n } else {\n StartAudioContext._onStarted.push(cb);\n }\n return StartAudioContext;\n };\n\n /**\n * returns true if the context is started\n * @return {Boolean}\n */\n StartAudioContext.isStarted = function () {\n return StartAudioContext.context !== null && StartAudioContext.context.state === "running" || window.__audio_context_started;\n };\n\n /**\n * @class Listens for non-dragging tap ends on the given element\n * @param {Element} element\n * @internal\n */\n var TapListener = function TapListener(element) {\n this._dragged = false;\n this._element = element;\n this._bindedMove = this._moved.bind(this);\n this._bindedEnd = this._ended.bind(this);\n element.addEventListener("touchmove", this._bindedMove);\n element.addEventListener("touchend", this._bindedEnd);\n element.addEventListener("mouseup", this._bindedEnd);\n };\n\n /**\n * drag move event\n */\n TapListener.prototype._moved = function (e) {\n this._dragged = true;\n };\n\n /**\n * tap ended listener\n */\n TapListener.prototype._ended = function (e) {\n if (!this._dragged) {\n onTap();\n }\n this._dragged = false;\n };\n\n /**\n * remove all the bound events\n */\n TapListener.prototype.dispose = function () {\n this._element.removeEventListener("touchmove", this._bindedMove);\n this._element.removeEventListener("touchend", this._bindedEnd);\n this._element.removeEventListener("mouseup", this._bindedEnd);\n this._bindedMove = null;\n this._bindedEnd = null;\n this._element = null;\n };\n\n /**\n * Invoked the first time of the elements is tapped.\n * Creates a silent oscillator when a non-dragging touchend\n * event has been triggered.\n */\n function onTap() {\n try {\n //start the audio context with a silent oscillator\n if (StartAudioContext.context && !StartAudioContext.isStarted()) {\n var osc = StartAudioContext.context.createOscillator();\n var silent = StartAudioContext.context.createGain();\n silent.gain.value = 0;\n osc.connect(silent);\n silent.connect(StartAudioContext.context.destination);\n var now = StartAudioContext.context.currentTime;\n osc.start(now);\n osc.stop(now + 0.5);\n }\n\n //dispose all the tap listeners\n if (StartAudioContext._tapListeners) {\n for (var i = 0; i < StartAudioContext._tapListeners.length; i++) {\n StartAudioContext._tapListeners[i].dispose();\n }\n StartAudioContext._tapListeners = null;\n }\n\n //the onstarted callbacks\n if (StartAudioContext._onStarted) {\n for (var j = 0; j < StartAudioContext._onStarted.length; j++) {\n StartAudioContext._onStarted[j]();\n }\n StartAudioContext._onStarted = null;\n }\n window.__audio_context_started = true;\n } catch (error) {\n //\n }\n }\n return StartAudioContext;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjMxLmpzIiwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUFBLE1BQU0sQ0FBQ0MsdUJBQXVCLEdBQUcsS0FBSztBQUV0QyxDQUFDLFVBQVVDLElBQUksRUFBRUMsT0FBTyxFQUFFO0VBQ3hCLElBQUksSUFBMEMsRUFBRTtJQUM5Q0MsaUNBQU8sRUFBRSxvQ0FBRUQsT0FBTztBQUFBO0FBQUE7QUFBQSxrR0FBQztFQUNyQixDQUFDLE1BQU0sRUFJTjtBQUNILENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWTtFQUNuQjtBQUNGO0FBQ0E7RUFDRSxJQUFJTSxpQkFBaUIsR0FBRztJQUN0QjtBQUNKO0FBQ0E7QUFDQTtJQUNJQyxPQUFPLEVBQUUsSUFBSTtJQUNiO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7SUFDSUMsYUFBYSxFQUFFLEVBQUU7SUFDakI7QUFDSjtBQUNBO0FBQ0E7QUFDQTtJQUNJQyxVQUFVLEVBQUU7RUFDZCxDQUFDOztFQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDRUgsaUJBQWlCLENBQUNJLFVBQVUsR0FBRyxVQUFVQyxHQUFHLEVBQUU7SUFDNUNMLGlCQUFpQixDQUFDQyxPQUFPLEdBQUdJLEdBQUc7SUFDL0IsT0FBT0wsaUJBQWlCO0VBQzFCLENBQUM7O0VBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtFQUNFQSxpQkFBaUIsQ0FBQ00sRUFBRSxHQUFHLFVBQVVDLE9BQU8sRUFBRTtJQUN4QyxJQUFJQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ0YsT0FBTyxDQUFDLElBQUtHLFFBQVEsSUFBSUgsT0FBTyxZQUFZRyxRQUFTLEVBQUU7TUFDdkUsS0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdKLE9BQU8sQ0FBQ0ssTUFBTSxFQUFFRCxDQUFDLEVBQUUsRUFBRTtRQUN2Q1gsaUJBQWlCLENBQUNNLEVBQUUsQ0FBQ0MsT0FBTyxDQUFDSSxDQUFDLENBQUMsQ0FBQztNQUNsQztJQUNGLENBQUMsTUFBTSxJQUFJLE9BQU9KLE9BQU8sS0FBSyxRQUFRLEVBQUU7TUFDdENQLGlCQUFpQixDQUFDTSxFQUFFLENBQUNPLFFBQVEsQ0FBQ0MsZ0JBQWdCLENBQUNQLE9BQU8sQ0FBQyxDQUFDO0lBQzFELENBQUMsTUFBTSxJQUFJQSxPQUFPLENBQUNRLE1BQU0sSUFBSSxPQUFPUixPQUFPLENBQUNTLE9BQU8sS0FBSyxVQUFVLEVBQUU7TUFDbEVoQixpQkFBaUIsQ0FBQ00sRUFBRSxDQUFDQyxPQUFPLENBQUNTLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDekMsQ0FBQyxNQUFNLElBQUlDLE9BQU8sSUFBSVYsT0FBTyxZQUFZVSxPQUFPLEVBQUU7TUFDaEQ7TUFDQSxJQUFJQyxHQUFHLEdBQUcsSUFBSUMsV0FBVyxDQUFDWixPQUFPLEVBQUVhLEtBQUssQ0FBQztNQUN6Q3BCLGlCQUFpQixDQUFDRSxhQUFhLENBQUNtQixJQUFJLENBQUNILEdBQUcsQ0FBQztJQUMzQztJQUNBLE9BQU9sQixpQkFBaUI7RUFDMUIsQ0FBQzs7RUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0VBQ0VBLGlCQUFpQixDQUFDc0IsU0FBUyxHQUFHLFVBQVVDLEVBQUUsRUFBRTtJQUMxQztJQUNBLElBQUl2QixpQkFBaUIsQ0FBQ3dCLFNBQVMsQ0FBQyxDQUFDLEVBQUU7TUFDakNELEVBQUUsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxNQUFNO01BQ0x2QixpQkFBaUIsQ0FBQ0csVUFBVSxDQUFDa0IsSUFBSSxDQUFDRSxFQUFFLENBQUM7SUFDdkM7SUFDQSxPQUFPdkIsaUJBQWlCO0VBQzFCLENBQUM7O0VBRUQ7QUFDRjtBQUNBO0FBQ0E7RUFDRUEsaUJBQWlCLENBQUN3QixTQUFTLEdBQUcsWUFBWTtJQUN4QyxPQUNHeEIsaUJBQWlCLENBQUNDLE9BQU8sS0FBSyxJQUFJLElBQ2pDRCxpQkFBaUIsQ0FBQ0MsT0FBTyxDQUFDd0IsS0FBSyxLQUFLLFNBQVMsSUFDL0NsQyxNQUFNLENBQUNDLHVCQUF1QjtFQUVsQyxDQUFDOztFQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDRSxJQUFJMkIsV0FBVyxHQUFHLFNBQWRBLFdBQVdBLENBQWFaLE9BQU8sRUFBRTtJQUNuQyxJQUFJLENBQUNtQixRQUFRLEdBQUcsS0FBSztJQUVyQixJQUFJLENBQUNDLFFBQVEsR0FBR3BCLE9BQU87SUFFdkIsSUFBSSxDQUFDcUIsV0FBVyxHQUFHLElBQUksQ0FBQ0MsTUFBTSxDQUFDQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3pDLElBQUksQ0FBQ0MsVUFBVSxHQUFHLElBQUksQ0FBQ0MsTUFBTSxDQUFDRixJQUFJLENBQUMsSUFBSSxDQUFDO0lBRXhDdkIsT0FBTyxDQUFDMEIsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQ0wsV0FBVyxDQUFDO0lBQ3ZEckIsT0FBTyxDQUFDMEIsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQ0YsVUFBVSxDQUFDO0lBQ3JEeEIsT0FBTyxDQUFDMEIsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQ0YsVUFBVSxDQUFDO0VBQ3RELENBQUM7O0VBRUQ7QUFDRjtBQUNBO0VBQ0VaLFdBQVcsQ0FBQ2UsU0FBUyxDQUFDTCxNQUFNLEdBQUcsVUFBVU0sQ0FBQyxFQUFFO0lBQzFDLElBQUksQ0FBQ1QsUUFBUSxHQUFHLElBQUk7RUFDdEIsQ0FBQzs7RUFFRDtBQUNGO0FBQ0E7RUFDRVAsV0FBVyxDQUFDZSxTQUFTLENBQUNGLE1BQU0sR0FBRyxVQUFVRyxDQUFDLEVBQUU7SUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQ1QsUUFBUSxFQUFFO01BQ2xCTixLQUFLLENBQUMsQ0FBQztJQUNUO0lBQ0EsSUFBSSxDQUFDTSxRQUFRLEdBQUcsS0FBSztFQUN2QixDQUFDOztFQUVEO0FBQ0Y7QUFDQTtFQUNFUCxXQUFXLENBQUNlLFNBQVMsQ0FBQ0UsT0FBTyxHQUFHLFlBQVk7SUFDMUMsSUFBSSxDQUFDVCxRQUFRLENBQUNVLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUNULFdBQVcsQ0FBQztJQUNoRSxJQUFJLENBQUNELFFBQVEsQ0FBQ1UsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQ04sVUFBVSxDQUFDO0lBQzlELElBQUksQ0FBQ0osUUFBUSxDQUFDVSxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDTixVQUFVLENBQUM7SUFDN0QsSUFBSSxDQUFDSCxXQUFXLEdBQUcsSUFBSTtJQUN2QixJQUFJLENBQUNHLFVBQVUsR0FBRyxJQUFJO0lBQ3RCLElBQUksQ0FBQ0osUUFBUSxHQUFHLElBQUk7RUFDdEIsQ0FBQzs7RUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0VBQ0UsU0FBU1AsS0FBS0EsQ0FBQSxFQUFHO0lBQ2YsSUFBSTtNQUNGO01BQ0EsSUFBSXBCLGlCQUFpQixDQUFDQyxPQUFPLElBQUksQ0FBQ0QsaUJBQWlCLENBQUN3QixTQUFTLENBQUMsQ0FBQyxFQUFFO1FBQy9ELElBQUljLEdBQUcsR0FBR3RDLGlCQUFpQixDQUFDQyxPQUFPLENBQUNzQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3RELElBQUlDLE1BQU0sR0FBR3hDLGlCQUFpQixDQUFDQyxPQUFPLENBQUN3QyxVQUFVLENBQUMsQ0FBQztRQUNuREQsTUFBTSxDQUFDRSxJQUFJLENBQUNDLEtBQUssR0FBRyxDQUFDO1FBQ3JCTCxHQUFHLENBQUNNLE9BQU8sQ0FBQ0osTUFBTSxDQUFDO1FBQ25CQSxNQUFNLENBQUNJLE9BQU8sQ0FBQzVDLGlCQUFpQixDQUFDQyxPQUFPLENBQUM0QyxXQUFXLENBQUM7UUFDckQsSUFBSUMsR0FBRyxHQUFHOUMsaUJBQWlCLENBQUNDLE9BQU8sQ0FBQzhDLFdBQVc7UUFDL0NULEdBQUcsQ0FBQ1UsS0FBSyxDQUFDRixHQUFHLENBQUM7UUFDZFIsR0FBRyxDQUFDVyxJQUFJLENBQUNILEdBQUcsR0FBRyxHQUFHLENBQUM7TUFDckI7O01BRUE7TUFDQSxJQUFJOUMsaUJBQWlCLENBQUNFLGFBQWEsRUFBRTtRQUNuQyxLQUFLLElBQUlTLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR1gsaUJBQWlCLENBQUNFLGFBQWEsQ0FBQ1UsTUFBTSxFQUFFRCxDQUFDLEVBQUUsRUFBRTtVQUMvRFgsaUJBQWlCLENBQUNFLGFBQWEsQ0FBQ1MsQ0FBQyxDQUFDLENBQUN5QixPQUFPLENBQUMsQ0FBQztRQUM5QztRQUNBcEMsaUJBQWlCLENBQUNFLGFBQWEsR0FBRyxJQUFJO01BQ3hDOztNQUVBO01BQ0EsSUFBSUYsaUJBQWlCLENBQUNHLFVBQVUsRUFBRTtRQUNoQyxLQUFLLElBQUkrQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdsRCxpQkFBaUIsQ0FBQ0csVUFBVSxDQUFDUyxNQUFNLEVBQUVzQyxDQUFDLEVBQUUsRUFBRTtVQUM1RGxELGlCQUFpQixDQUFDRyxVQUFVLENBQUMrQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DO1FBQ0FsRCxpQkFBaUIsQ0FBQ0csVUFBVSxHQUFHLElBQUk7TUFDckM7TUFFQVosTUFBTSxDQUFDQyx1QkFBdUIsR0FBRyxJQUFJO0lBQ3ZDLENBQUMsQ0FBQyxPQUFPMkQsS0FBSyxFQUFFO01BQ2Q7SUFBQTtFQUVKO0VBRUEsT0FBT25ELGlCQUFpQjtBQUMxQixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3N0YXJ0QXVkaW9Db250ZXh0LmpzPzZlYmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgU3RhcnRBdWRpb0NvbnRleHQuanNcbiAqICBAYXV0aG9yIFlvdGFtIE1hbm5cbiAqICBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiAgQGNvcHlyaWdodCAyMDE2IFlvdGFtIE1hbm5cbiAqL1xuXG53aW5kb3cuX19hdWRpb19jb250ZXh0X3N0YXJ0ZWQgPSBmYWxzZTtcblxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuU3RhcnRBdWRpb0NvbnRleHQgPSBmYWN0b3J5KCk7XG4gIH1cbn0pKHRoaXMsIGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIFRoZSBTdGFydEF1ZGlvQ29udGV4dCBvYmplY3RcbiAgICovXG4gIHZhciBTdGFydEF1ZGlvQ29udGV4dCA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gY29udGV4dCBwYXNzZWQgaW4gYnkgdGhlIHVzZXJcbiAgICAgKiBAdHlwZSB7QXVkaW9Db250ZXh0fVxuICAgICAqL1xuICAgIGNvbnRleHQ6IG51bGwsXG4gICAgLyoqXG4gICAgICogVGhlIFRhcExpc3RlbmVycyBib3VuZCB0byB0aGUgZWxlbWVudHNcbiAgICAgKiBAdHlwZSB7QXJyYXl9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdGFwTGlzdGVuZXJzOiBbXSxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZFxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9vblN0YXJ0ZWQ6IFtdLFxuICB9O1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvbnRleHRcbiAgICogQHBhcmFtIHtBdWRpb0NvbnRleHR9IGN0eFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0ID0gZnVuY3Rpb24gKGN0eCkge1xuICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQgPSBjdHg7XG4gICAgcmV0dXJuIFN0YXJ0QXVkaW9Db250ZXh0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSB0YXAgbGlzdGVuZXIgdG8gdGhlIGF1ZGlvIGNvbnRleHRcbiAgICogQHBhcmFtICB7QXJyYXl8RWxlbWVudHxTdHJpbmd8alF1ZXJ5fSBlbGVtZW50XG4gICAqIEByZXR1cm5zIHtTdGFydEF1ZGlvQ29udGV4dH1cbiAgICovXG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbGVtZW50KSB8fCAoTm9kZUxpc3QgJiYgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGVsZW1lbnRbaV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbWVudCkpO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudC5qcXVlcnkgJiYgdHlwZW9mIGVsZW1lbnQudG9BcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5vbihlbGVtZW50LnRvQXJyYXkoKSk7XG4gICAgfSBlbHNlIGlmIChFbGVtZW50ICYmIGVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAvL2lmIGl0J3MgYW4gZWxlbWVudCwgY3JlYXRlIGEgVGFwTGlzdGVuZXJcbiAgICAgIHZhciB0YXAgPSBuZXcgVGFwTGlzdGVuZXIoZWxlbWVudCwgb25UYXApO1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5wdXNoKHRhcCk7XG4gICAgfVxuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogQmluZCBhIGNhbGxiYWNrIHRvIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAgICogQHJldHVybiB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5vblN0YXJ0ZWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICAvL2lmIGl0J3MgYWxyZWFkeSBzdGFydGVkLCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCgpKSB7XG4gICAgICBjYigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkLnB1c2goY2IpO1xuICAgIH1cbiAgICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGV4dCBpcyBzdGFydGVkXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5pc1N0YXJ0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIChTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICE9PSBudWxsICYmXG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuc3RhdGUgPT09IFwicnVubmluZ1wiKSB8fFxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogQGNsYXNzICBMaXN0ZW5zIGZvciBub24tZHJhZ2dpbmcgdGFwIGVuZHMgb24gdGhlIGdpdmVuIGVsZW1lbnRcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdmFyIFRhcExpc3RlbmVyID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSB0aGlzLl9tb3ZlZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IHRoaXMuX2VuZGVkLmJpbmQodGhpcyk7XG5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fYmluZGVkTW92ZSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGRyYWcgbW92ZSBldmVudFxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9tb3ZlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdGhpcy5fZHJhZ2dlZCA9IHRydWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIHRhcCBlbmRlZCBsaXN0ZW5lclxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9lbmRlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKCF0aGlzLl9kcmFnZ2VkKSB7XG4gICAgICBvblRhcCgpO1xuICAgIH1cbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJlbW92ZSBhbGwgdGhlIGJvdW5kIGV2ZW50c1xuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX2JpbmRlZE1vdmUpO1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLl9iaW5kZWRFbmQpO1xuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSBudWxsO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IG51bGw7XG4gICAgdGhpcy5fZWxlbWVudCA9IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEludm9rZWQgdGhlIGZpcnN0IHRpbWUgb2YgdGhlIGVsZW1lbnRzIGlzIHRhcHBlZC5cbiAgICogQ3JlYXRlcyBhIHNpbGVudCBvc2NpbGxhdG9yIHdoZW4gYSBub24tZHJhZ2dpbmcgdG91Y2hlbmRcbiAgICogZXZlbnQgaGFzIGJlZW4gdHJpZ2dlcmVkLlxuICAgKi9cbiAgZnVuY3Rpb24gb25UYXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQgd2l0aCBhIHNpbGVudCBvc2NpbGxhdG9yXG4gICAgICBpZiAoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dCAmJiAhU3RhcnRBdWRpb0NvbnRleHQuaXNTdGFydGVkKCkpIHtcbiAgICAgICAgdmFyIG9zYyA9IFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICB2YXIgc2lsZW50ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIHNpbGVudC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgb3NjLmNvbm5lY3Qoc2lsZW50KTtcbiAgICAgICAgc2lsZW50LmNvbm5lY3QoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHZhciBub3cgPSBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICBvc2Muc3RhcnQobm93KTtcbiAgICAgICAgb3NjLnN0b3Aobm93ICsgMC41KTtcbiAgICAgIH1cblxuICAgICAgLy9kaXNwb3NlIGFsbCB0aGUgdGFwIGxpc3RlbmVyc1xuICAgICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBTdGFydEF1ZGlvQ29udGV4dC5fdGFwTGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVyc1tpXS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vdGhlIG9uc3RhcnRlZCBjYWxsYmFja3NcbiAgICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWRbal0oKTtcbiAgICAgICAgfVxuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy9cbiAgICB9XG4gIH1cblxuICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG59KTtcbiJdLCJuYW1lcyI6WyJ3aW5kb3ciLCJfX2F1ZGlvX2NvbnRleHRfc3RhcnRlZCIsInJvb3QiLCJmYWN0b3J5IiwiZGVmaW5lIiwiYW1kIiwibW9kdWxlIiwiX3R5cGVvZiIsImV4cG9ydHMiLCJTdGFydEF1ZGlvQ29udGV4dCIsImNvbnRleHQiLCJfdGFwTGlzdGVuZXJzIiwiX29uU3RhcnRlZCIsInNldENvbnRleHQiLCJjdHgiLCJvbiIsImVsZW1lbnQiLCJBcnJheSIsImlzQXJyYXkiLCJOb2RlTGlzdCIsImkiLCJsZW5ndGgiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJqcXVlcnkiLCJ0b0FycmF5IiwiRWxlbWVudCIsInRhcCIsIlRhcExpc3RlbmVyIiwib25UYXAiLCJwdXNoIiwib25TdGFydGVkIiwiY2IiLCJpc1N0YXJ0ZWQiLCJzdGF0ZSIsIl9kcmFnZ2VkIiwiX2VsZW1lbnQiLCJfYmluZGVkTW92ZSIsIl9tb3ZlZCIsImJpbmQiLCJfYmluZGVkRW5kIiwiX2VuZGVkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByb3RvdHlwZSIsImUiLCJkaXNwb3NlIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIm9zYyIsImNyZWF0ZU9zY2lsbGF0b3IiLCJzaWxlbnQiLCJjcmVhdGVHYWluIiwiZ2FpbiIsInZhbHVlIiwiY29ubmVjdCIsImRlc3RpbmF0aW9uIiwibm93IiwiY3VycmVudFRpbWUiLCJzdGFydCIsInN0b3AiLCJqIiwiZXJyb3IiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n')},448:(__unused_webpack_module,exports,__webpack_require__)=>{"use strict";eval('/**\n * @license React\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\nvar aa=__webpack_require__(294),ca=__webpack_require__(840);function p(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;c<arguments.length;c++)b+="&args[]="+encodeURIComponent(arguments[c]);return"Minified React error #"+a+"; visit "+b+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var da=new Set,ea={};function fa(a,b){ha(a,b);ha(a+"Capture",b)}\nfunction ha(a,b){ea[a]=b;for(a=0;a<b.length;a++)da.add(b[a])}\nvar ia=!("undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement),ja=Object.prototype.hasOwnProperty,ka=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,la=\n{},ma={};function oa(a){if(ja.call(ma,a))return!0;if(ja.call(la,a))return!1;if(ka.test(a))return ma[a]=!0;la[a]=!0;return!1}function pa(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}\nfunction qa(a,b,c,d){if(null===b||"undefined"===typeof b||pa(a,b,c,d))return!0;if(d)return!1;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}function v(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}var z={};\n"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){z[a]=new v(a,0,!1,a,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];z[b]=new v(b,1,!1,a[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){z[a]=new v(a,2,!1,a.toLowerCase(),null,!1,!1)});\n["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){z[a]=new v(a,2,!1,a,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){z[a]=new v(a,3,!1,a.toLowerCase(),null,!1,!1)});\n["checked","multiple","muted","selected"].forEach(function(a){z[a]=new v(a,3,!0,a,null,!1,!1)});["capture","download"].forEach(function(a){z[a]=new v(a,4,!1,a,null,!1,!1)});["cols","rows","size","span"].forEach(function(a){z[a]=new v(a,6,!1,a,null,!1,!1)});["rowSpan","start"].forEach(function(a){z[a]=new v(a,5,!1,a.toLowerCase(),null,!1,!1)});var ra=/[\\-:]([a-z])/g;function sa(a){return a[1].toUpperCase()}\n"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=a.replace(ra,\nsa);z[b]=new v(b,1,!1,a,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!1,!1)});\nz.xlinkHref=new v("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!0,!0)});\nfunction ta(a,b,c,d){var e=z.hasOwnProperty(b)?z[b]:null;if(null!==e?0!==e.type:d||!(2<b.length)||"o"!==b[0]&&"O"!==b[0]||"n"!==b[1]&&"N"!==b[1])qa(b,c,e,d)&&(c=null),d||null===e?oa(b)&&(null===c?a.removeAttribute(b):a.setAttribute(b,""+c)):e.mustUseProperty?a[e.propertyName]=null===c?3===e.type?!1:"":c:(b=e.attributeName,d=e.attributeNamespace,null===c?a.removeAttribute(b):(e=e.type,c=3===e||4===e&&!0===c?"":""+c,d?a.setAttributeNS(d,b,c):a.setAttribute(b,c)))}\nvar ua=aa.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,va=Symbol.for("react.element"),wa=Symbol.for("react.portal"),ya=Symbol.for("react.fragment"),za=Symbol.for("react.strict_mode"),Aa=Symbol.for("react.profiler"),Ba=Symbol.for("react.provider"),Ca=Symbol.for("react.context"),Da=Symbol.for("react.forward_ref"),Ea=Symbol.for("react.suspense"),Fa=Symbol.for("react.suspense_list"),Ga=Symbol.for("react.memo"),Ha=Symbol.for("react.lazy");Symbol.for("react.scope");Symbol.for("react.debug_trace_mode");\nvar Ia=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden");Symbol.for("react.cache");Symbol.for("react.tracing_marker");var Ja=Symbol.iterator;function Ka(a){if(null===a||"object"!==typeof a)return null;a=Ja&&a[Ja]||a["@@iterator"];return"function"===typeof a?a:null}var A=Object.assign,La;function Ma(a){if(void 0===La)try{throw Error();}catch(c){var b=c.stack.trim().match(/\\n( *(at )?)/);La=b&&b[1]||""}return"\\n"+La+a}var Na=!1;\nfunction Oa(a,b){if(!a||Na)return"";Na=!0;var c=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(b)if(b=function(){throw Error();},Object.defineProperty(b.prototype,"props",{set:function(){throw Error();}}),"object"===typeof Reflect&&Reflect.construct){try{Reflect.construct(b,[])}catch(l){var d=l}Reflect.construct(a,[],b)}else{try{b.call()}catch(l){d=l}a.call(b.prototype)}else{try{throw Error();}catch(l){d=l}a()}}catch(l){if(l&&d&&"string"===typeof l.stack){for(var e=l.stack.split("\\n"),\nf=d.stack.split("\\n"),g=e.length-1,h=f.length-1;1<=g&&0<=h&&e[g]!==f[h];)h--;for(;1<=g&&0<=h;g--,h--)if(e[g]!==f[h]){if(1!==g||1!==h){do if(g--,h--,0>h||e[g]!==f[h]){var k="\\n"+e[g].replace(" at new "," at ");a.displayName&&k.includes("<anonymous>")&&(k=k.replace("<anonymous>",a.displayName));return k}while(1<=g&&0<=h)}break}}}finally{Na=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:"")?Ma(a):""}\nfunction Pa(a){switch(a.tag){case 5:return Ma(a.type);case 16:return Ma("Lazy");case 13:return Ma("Suspense");case 19:return Ma("SuspenseList");case 0:case 2:case 15:return a=Oa(a.type,!1),a;case 11:return a=Oa(a.type.render,!1),a;case 1:return a=Oa(a.type,!0),a;default:return""}}\nfunction Qa(a){if(null==a)return null;if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case ya:return"Fragment";case wa:return"Portal";case Aa:return"Profiler";case za:return"StrictMode";case Ea:return"Suspense";case Fa:return"SuspenseList"}if("object"===typeof a)switch(a.$$typeof){case Ca:return(a.displayName||"Context")+".Consumer";case Ba:return(a._context.displayName||"Context")+".Provider";case Da:var b=a.render;a=a.displayName;a||(a=b.displayName||\nb.name||"",a=""!==a?"ForwardRef("+a+")":"ForwardRef");return a;case Ga:return b=a.displayName||null,null!==b?b:Qa(a.type)||"Memo";case Ha:b=a._payload;a=a._init;try{return Qa(a(b))}catch(c){}}return null}\nfunction Ra(a){var b=a.type;switch(a.tag){case 24:return"Cache";case 9:return(b.displayName||"Context")+".Consumer";case 10:return(b._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return a=b.render,a=a.displayName||a.name||"",b.displayName||(""!==a?"ForwardRef("+a+")":"ForwardRef");case 7:return"Fragment";case 5:return b;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Qa(b);case 8:return b===za?"StrictMode":"Mode";case 22:return"Offscreen";\ncase 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"===typeof b)return b.displayName||b.name||null;if("string"===typeof b)return b}return null}function Sa(a){switch(typeof a){case "boolean":case "number":case "string":case "undefined":return a;case "object":return a;default:return""}}\nfunction Ta(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)}\nfunction Ua(a){var b=Ta(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a,b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=\nnull;delete a[b]}}}}function Va(a){a._valueTracker||(a._valueTracker=Ua(a))}function Wa(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=Ta(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Xa(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}\nfunction Ya(a,b){var c=b.checked;return A({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Za(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Sa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function ab(a,b){b=b.checked;null!=b&&ta(a,"checked",b,!1)}\nfunction bb(a,b){ab(a,b);var c=Sa(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?cb(a,b.type,c):b.hasOwnProperty("defaultValue")&&cb(a,b.type,Sa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}\nfunction db(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d=b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)}\nfunction cb(a,b,c){if("number"!==b||Xa(a.ownerDocument)!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}var eb=Array.isArray;\nfunction fb(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e<c.length;e++)b["$"+c[e]]=!0;for(c=0;c<a.length;c++)e=b.hasOwnProperty("$"+a[c].value),a[c].selected!==e&&(a[c].selected=e),e&&d&&(a[c].defaultSelected=!0)}else{c=""+Sa(c);b=null;for(e=0;e<a.length;e++){if(a[e].value===c){a[e].selected=!0;d&&(a[e].defaultSelected=!0);return}null!==b||a[e].disabled||(b=a[e])}null!==b&&(b.selected=!0)}}\nfunction gb(a,b){if(null!=b.dangerouslySetInnerHTML)throw Error(p(91));return A({},b,{value:void 0,defaultValue:void 0,children:""+a._wrapperState.initialValue})}function hb(a,b){var c=b.value;if(null==c){c=b.children;b=b.defaultValue;if(null!=c){if(null!=b)throw Error(p(92));if(eb(c)){if(1<c.length)throw Error(p(93));c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:Sa(c)}}\nfunction ib(a,b){var c=Sa(b.value),d=Sa(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function jb(a){var b=a.textContent;b===a._wrapperState.initialValue&&""!==b&&null!==b&&(a.value=b)}function kb(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}\nfunction lb(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?kb(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}\nvar mb,nb=function(a){return"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if("http://www.w3.org/2000/svg"!==a.namespaceURI||"innerHTML"in a)a.innerHTML=b;else{mb=mb||document.createElement("div");mb.innerHTML="<svg>"+b.valueOf().toString()+"</svg>";for(b=mb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction ob(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}\nvar pb={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,\nzoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qb=["Webkit","ms","Moz","O"];Object.keys(pb).forEach(function(a){qb.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);pb[b]=pb[a]})});function rb(a,b,c){return null==b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||pb.hasOwnProperty(a)&&pb[a]?(""+b).trim():b+"px"}\nfunction sb(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=rb(c,b[c],d);"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}var tb=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});\nfunction ub(a,b){if(b){if(tb[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(p(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(p(60));if("object"!==typeof b.dangerouslySetInnerHTML||!("__html"in b.dangerouslySetInnerHTML))throw Error(p(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(p(62));}}\nfunction vb(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;default:return!0}}var wb=null;function xb(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}var yb=null,zb=null,Ab=null;\nfunction Bb(a){if(a=Cb(a)){if("function"!==typeof yb)throw Error(p(280));var b=a.stateNode;b&&(b=Db(b),yb(a.stateNode,a.type,b))}}function Eb(a){zb?Ab?Ab.push(a):Ab=[a]:zb=a}function Fb(){if(zb){var a=zb,b=Ab;Ab=zb=null;Bb(a);if(b)for(a=0;a<b.length;a++)Bb(b[a])}}function Gb(a,b){return a(b)}function Hb(){}var Ib=!1;function Jb(a,b,c){if(Ib)return a(b,c);Ib=!0;try{return Gb(a,b,c)}finally{if(Ib=!1,null!==zb||null!==Ab)Hb(),Fb()}}\nfunction Kb(a,b){var c=a.stateNode;if(null===c)return null;var d=Db(c);if(null===d)return null;c=d[b];a:switch(b){case "onClick":case "onClickCapture":case "onDoubleClick":case "onDoubleClickCapture":case "onMouseDown":case "onMouseDownCapture":case "onMouseMove":case "onMouseMoveCapture":case "onMouseUp":case "onMouseUpCapture":case "onMouseEnter":(d=!d.disabled)||(a=a.type,d=!("button"===a||"input"===a||"select"===a||"textarea"===a));a=!d;break a;default:a=!1}if(a)return null;if(c&&"function"!==\ntypeof c)throw Error(p(231,b,typeof c));return c}var Lb=!1;if(ia)try{var Mb={};Object.defineProperty(Mb,"passive",{get:function(){Lb=!0}});window.addEventListener("test",Mb,Mb);window.removeEventListener("test",Mb,Mb)}catch(a){Lb=!1}function Nb(a,b,c,d,e,f,g,h,k){var l=Array.prototype.slice.call(arguments,3);try{b.apply(c,l)}catch(m){this.onError(m)}}var Ob=!1,Pb=null,Qb=!1,Rb=null,Sb={onError:function(a){Ob=!0;Pb=a}};function Tb(a,b,c,d,e,f,g,h,k){Ob=!1;Pb=null;Nb.apply(Sb,arguments)}\nfunction Ub(a,b,c,d,e,f,g,h,k){Tb.apply(this,arguments);if(Ob){if(Ob){var l=Pb;Ob=!1;Pb=null}else throw Error(p(198));Qb||(Qb=!0,Rb=l)}}function Vb(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.flags&4098)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function Wb(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function Xb(a){if(Vb(a)!==a)throw Error(p(188));}\nfunction Yb(a){var b=a.alternate;if(!b){b=Vb(a);if(null===b)throw Error(p(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return Xb(e),a;if(f===d)return Xb(e),b;f=f.sibling}throw Error(p(188));}if(c.return!==d.return)c=e,d=f;else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h=f.child;h;){if(h===\nc){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(p(189));}}if(c.alternate!==d)throw Error(p(190));}if(3!==c.tag)throw Error(p(188));return c.stateNode.current===c?a:b}function Zb(a){a=Yb(a);return null!==a?$b(a):null}function $b(a){if(5===a.tag||6===a.tag)return a;for(a=a.child;null!==a;){var b=$b(a);if(null!==b)return b;a=a.sibling}return null}\nvar ac=ca.unstable_scheduleCallback,bc=ca.unstable_cancelCallback,cc=ca.unstable_shouldYield,dc=ca.unstable_requestPaint,B=ca.unstable_now,ec=ca.unstable_getCurrentPriorityLevel,fc=ca.unstable_ImmediatePriority,gc=ca.unstable_UserBlockingPriority,hc=ca.unstable_NormalPriority,ic=ca.unstable_LowPriority,jc=ca.unstable_IdlePriority,kc=null,lc=null;function mc(a){if(lc&&"function"===typeof lc.onCommitFiberRoot)try{lc.onCommitFiberRoot(kc,a,void 0,128===(a.current.flags&128))}catch(b){}}\nvar oc=Math.clz32?Math.clz32:nc,pc=Math.log,qc=Math.LN2;function nc(a){a>>>=0;return 0===a?32:31-(pc(a)/qc|0)|0}var rc=64,sc=4194304;\nfunction tc(a){switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;\ndefault:return a}}function uc(a,b){var c=a.pendingLanes;if(0===c)return 0;var d=0,e=a.suspendedLanes,f=a.pingedLanes,g=c&268435455;if(0!==g){var h=g&~e;0!==h?d=tc(h):(f&=g,0!==f&&(d=tc(f)))}else g=c&~e,0!==g?d=tc(g):0!==f&&(d=tc(f));if(0===d)return 0;if(0!==b&&b!==d&&0===(b&e)&&(e=d&-d,f=b&-b,e>=f||16===e&&0!==(f&4194240)))return b;0!==(d&4)&&(d|=c&16);b=a.entangledLanes;if(0!==b)for(a=a.entanglements,b&=d;0<b;)c=31-oc(b),e=1<<c,d|=a[c],b&=~e;return d}\nfunction vc(a,b){switch(a){case 1:case 2:case 4:return b+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return b+5E3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}\nfunction wc(a,b){for(var c=a.suspendedLanes,d=a.pingedLanes,e=a.expirationTimes,f=a.pendingLanes;0<f;){var g=31-oc(f),h=1<<g,k=e[g];if(-1===k){if(0===(h&c)||0!==(h&d))e[g]=vc(h,b)}else k<=b&&(a.expiredLanes|=h);f&=~h}}function xc(a){a=a.pendingLanes&-1073741825;return 0!==a?a:a&1073741824?1073741824:0}function yc(){var a=rc;rc<<=1;0===(rc&4194240)&&(rc=64);return a}function zc(a){for(var b=[],c=0;31>c;c++)b.push(a);return b}\nfunction Ac(a,b,c){a.pendingLanes|=b;536870912!==b&&(a.suspendedLanes=0,a.pingedLanes=0);a=a.eventTimes;b=31-oc(b);a[b]=c}function Bc(a,b){var c=a.pendingLanes&~b;a.pendingLanes=b;a.suspendedLanes=0;a.pingedLanes=0;a.expiredLanes&=b;a.mutableReadLanes&=b;a.entangledLanes&=b;b=a.entanglements;var d=a.eventTimes;for(a=a.expirationTimes;0<c;){var e=31-oc(c),f=1<<e;b[e]=0;d[e]=-1;a[e]=-1;c&=~f}}\nfunction Cc(a,b){var c=a.entangledLanes|=b;for(a=a.entanglements;c;){var d=31-oc(c),e=1<<d;e&b|a[d]&b&&(a[d]|=b);c&=~e}}var C=0;function Dc(a){a&=-a;return 1<a?4<a?0!==(a&268435455)?16:536870912:4:1}var Ec,Fc,Gc,Hc,Ic,Jc=!1,Kc=[],Lc=null,Mc=null,Nc=null,Oc=new Map,Pc=new Map,Qc=[],Rc="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");\nfunction Sc(a,b){switch(a){case "focusin":case "focusout":Lc=null;break;case "dragenter":case "dragleave":Mc=null;break;case "mouseover":case "mouseout":Nc=null;break;case "pointerover":case "pointerout":Oc.delete(b.pointerId);break;case "gotpointercapture":case "lostpointercapture":Pc.delete(b.pointerId)}}\nfunction Tc(a,b,c,d,e,f){if(null===a||a.nativeEvent!==f)return a={blockedOn:b,domEventName:c,eventSystemFlags:d,nativeEvent:f,targetContainers:[e]},null!==b&&(b=Cb(b),null!==b&&Fc(b)),a;a.eventSystemFlags|=d;b=a.targetContainers;null!==e&&-1===b.indexOf(e)&&b.push(e);return a}\nfunction Uc(a,b,c,d,e){switch(b){case "focusin":return Lc=Tc(Lc,a,b,c,d,e),!0;case "dragenter":return Mc=Tc(Mc,a,b,c,d,e),!0;case "mouseover":return Nc=Tc(Nc,a,b,c,d,e),!0;case "pointerover":var f=e.pointerId;Oc.set(f,Tc(Oc.get(f)||null,a,b,c,d,e));return!0;case "gotpointercapture":return f=e.pointerId,Pc.set(f,Tc(Pc.get(f)||null,a,b,c,d,e)),!0}return!1}\nfunction Vc(a){var b=Wc(a.target);if(null!==b){var c=Vb(b);if(null!==c)if(b=c.tag,13===b){if(b=Wb(c),null!==b){a.blockedOn=b;Ic(a.priority,function(){Gc(c)});return}}else if(3===b&&c.stateNode.current.memoizedState.isDehydrated){a.blockedOn=3===c.tag?c.stateNode.containerInfo:null;return}}a.blockedOn=null}\nfunction Xc(a){if(null!==a.blockedOn)return!1;for(var b=a.targetContainers;0<b.length;){var c=Yc(a.domEventName,a.eventSystemFlags,b[0],a.nativeEvent);if(null===c){c=a.nativeEvent;var d=new c.constructor(c.type,c);wb=d;c.target.dispatchEvent(d);wb=null}else return b=Cb(c),null!==b&&Fc(b),a.blockedOn=c,!1;b.shift()}return!0}function Zc(a,b,c){Xc(a)&&c.delete(b)}function $c(){Jc=!1;null!==Lc&&Xc(Lc)&&(Lc=null);null!==Mc&&Xc(Mc)&&(Mc=null);null!==Nc&&Xc(Nc)&&(Nc=null);Oc.forEach(Zc);Pc.forEach(Zc)}\nfunction ad(a,b){a.blockedOn===b&&(a.blockedOn=null,Jc||(Jc=!0,ca.unstable_scheduleCallback(ca.unstable_NormalPriority,$c)))}\nfunction bd(a){function b(b){return ad(b,a)}if(0<Kc.length){ad(Kc[0],a);for(var c=1;c<Kc.length;c++){var d=Kc[c];d.blockedOn===a&&(d.blockedOn=null)}}null!==Lc&&ad(Lc,a);null!==Mc&&ad(Mc,a);null!==Nc&&ad(Nc,a);Oc.forEach(b);Pc.forEach(b);for(c=0;c<Qc.length;c++)d=Qc[c],d.blockedOn===a&&(d.blockedOn=null);for(;0<Qc.length&&(c=Qc[0],null===c.blockedOn);)Vc(c),null===c.blockedOn&&Qc.shift()}var cd=ua.ReactCurrentBatchConfig,dd=!0;\nfunction ed(a,b,c,d){var e=C,f=cd.transition;cd.transition=null;try{C=1,fd(a,b,c,d)}finally{C=e,cd.transition=f}}function gd(a,b,c,d){var e=C,f=cd.transition;cd.transition=null;try{C=4,fd(a,b,c,d)}finally{C=e,cd.transition=f}}\nfunction fd(a,b,c,d){if(dd){var e=Yc(a,b,c,d);if(null===e)hd(a,b,d,id,c),Sc(a,d);else if(Uc(e,a,b,c,d))d.stopPropagation();else if(Sc(a,d),b&4&&-1<Rc.indexOf(a)){for(;null!==e;){var f=Cb(e);null!==f&&Ec(f);f=Yc(a,b,c,d);null===f&&hd(a,b,d,id,c);if(f===e)break;e=f}null!==e&&d.stopPropagation()}else hd(a,b,d,null,c)}}var id=null;\nfunction Yc(a,b,c,d){id=null;a=xb(d);a=Wc(a);if(null!==a)if(b=Vb(a),null===b)a=null;else if(c=b.tag,13===c){a=Wb(b);if(null!==a)return a;a=null}else if(3===c){if(b.stateNode.current.memoizedState.isDehydrated)return 3===b.tag?b.stateNode.containerInfo:null;a=null}else b!==a&&(a=null);id=a;return null}\nfunction jd(a){switch(a){case "cancel":case "click":case "close":case "contextmenu":case "copy":case "cut":case "auxclick":case "dblclick":case "dragend":case "dragstart":case "drop":case "focusin":case "focusout":case "input":case "invalid":case "keydown":case "keypress":case "keyup":case "mousedown":case "mouseup":case "paste":case "pause":case "play":case "pointercancel":case "pointerdown":case "pointerup":case "ratechange":case "reset":case "resize":case "seeked":case "submit":case "touchcancel":case "touchend":case "touchstart":case "volumechange":case "change":case "selectionchange":case "textInput":case "compositionstart":case "compositionend":case "compositionupdate":case "beforeblur":case "afterblur":case "beforeinput":case "blur":case "fullscreenchange":case "focus":case "hashchange":case "popstate":case "select":case "selectstart":return 1;case "drag":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "mousemove":case "mouseout":case "mouseover":case "pointermove":case "pointerout":case "pointerover":case "scroll":case "toggle":case "touchmove":case "wheel":case "mouseenter":case "mouseleave":case "pointerenter":case "pointerleave":return 4;\ncase "message":switch(ec()){case fc:return 1;case gc:return 4;case hc:case ic:return 16;case jc:return 536870912;default:return 16}default:return 16}}var kd=null,ld=null,md=null;function nd(){if(md)return md;var a,b=ld,c=b.length,d,e="value"in kd?kd.value:kd.textContent,f=e.length;for(a=0;a<c&&b[a]===e[a];a++);var g=c-a;for(d=1;d<=g&&b[c-d]===e[f-d];d++);return md=e.slice(a,1<d?1-d:void 0)}\nfunction od(a){var b=a.keyCode;"charCode"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}function pd(){return!0}function qd(){return!1}\nfunction rd(a){function b(b,d,e,f,g){this._reactName=b;this._targetInst=e;this.type=d;this.nativeEvent=f;this.target=g;this.currentTarget=null;for(var c in a)a.hasOwnProperty(c)&&(b=a[c],this[c]=b?b(f):f[c]);this.isDefaultPrevented=(null!=f.defaultPrevented?f.defaultPrevented:!1===f.returnValue)?pd:qd;this.isPropagationStopped=qd;return this}A(b.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():"unknown"!==typeof a.returnValue&&\n(a.returnValue=!1),this.isDefaultPrevented=pd)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():"unknown"!==typeof a.cancelBubble&&(a.cancelBubble=!0),this.isPropagationStopped=pd)},persist:function(){},isPersistent:pd});return b}\nvar sd={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(a){return a.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},td=rd(sd),ud=A({},sd,{view:0,detail:0}),vd=rd(ud),wd,xd,yd,Ad=A({},ud,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:zd,button:0,buttons:0,relatedTarget:function(a){return void 0===a.relatedTarget?a.fromElement===a.srcElement?a.toElement:a.fromElement:a.relatedTarget},movementX:function(a){if("movementX"in\na)return a.movementX;a!==yd&&(yd&&"mousemove"===a.type?(wd=a.screenX-yd.screenX,xd=a.screenY-yd.screenY):xd=wd=0,yd=a);return wd},movementY:function(a){return"movementY"in a?a.movementY:xd}}),Bd=rd(Ad),Cd=A({},Ad,{dataTransfer:0}),Dd=rd(Cd),Ed=A({},ud,{relatedTarget:0}),Fd=rd(Ed),Gd=A({},sd,{animationName:0,elapsedTime:0,pseudoElement:0}),Hd=rd(Gd),Id=A({},sd,{clipboardData:function(a){return"clipboardData"in a?a.clipboardData:window.clipboardData}}),Jd=rd(Id),Kd=A({},sd,{data:0}),Ld=rd(Kd),Md={Esc:"Escape",\nSpacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Nd={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",\n119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Od={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Pd(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=Od[a])?!!b[a]:!1}function zd(){return Pd}\nvar Qd=A({},ud,{key:function(a){if(a.key){var b=Md[a.key]||a.key;if("Unidentified"!==b)return b}return"keypress"===a.type?(a=od(a),13===a?"Enter":String.fromCharCode(a)):"keydown"===a.type||"keyup"===a.type?Nd[a.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:zd,charCode:function(a){return"keypress"===a.type?od(a):0},keyCode:function(a){return"keydown"===a.type||"keyup"===a.type?a.keyCode:0},which:function(a){return"keypress"===\na.type?od(a):"keydown"===a.type||"keyup"===a.type?a.keyCode:0}}),Rd=rd(Qd),Sd=A({},Ad,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),Td=rd(Sd),Ud=A({},ud,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:zd}),Vd=rd(Ud),Wd=A({},sd,{propertyName:0,elapsedTime:0,pseudoElement:0}),Xd=rd(Wd),Yd=A({},Ad,{deltaX:function(a){return"deltaX"in a?a.deltaX:"wheelDeltaX"in a?-a.wheelDeltaX:0},\ndeltaY:function(a){return"deltaY"in a?a.deltaY:"wheelDeltaY"in a?-a.wheelDeltaY:"wheelDelta"in a?-a.wheelDelta:0},deltaZ:0,deltaMode:0}),Zd=rd(Yd),$d=[9,13,27,32],ae=ia&&"CompositionEvent"in window,be=null;ia&&"documentMode"in document&&(be=document.documentMode);var ce=ia&&"TextEvent"in window&&!be,de=ia&&(!ae||be&&8<be&&11>=be),ee=String.fromCharCode(32),fe=!1;\nfunction ge(a,b){switch(a){case "keyup":return-1!==$d.indexOf(b.keyCode);case "keydown":return 229!==b.keyCode;case "keypress":case "mousedown":case "focusout":return!0;default:return!1}}function he(a){a=a.detail;return"object"===typeof a&&"data"in a?a.data:null}var ie=!1;function je(a,b){switch(a){case "compositionend":return he(b);case "keypress":if(32!==b.which)return null;fe=!0;return ee;case "textInput":return a=b.data,a===ee&&fe?null:a;default:return null}}\nfunction ke(a,b){if(ie)return"compositionend"===a||!ae&&ge(a,b)?(a=nd(),md=ld=kd=null,ie=!1,a):null;switch(a){case "paste":return null;case "keypress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1<b.char.length)return b.char;if(b.which)return String.fromCharCode(b.which)}return null;case "compositionend":return de&&"ko"!==b.locale?null:b.data;default:return null}}\nvar le={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function me(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return"input"===b?!!le[a.type]:"textarea"===b?!0:!1}function ne(a,b,c,d){Eb(d);b=oe(b,"onChange");0<b.length&&(c=new td("onChange","change",null,c,d),a.push({event:c,listeners:b}))}var pe=null,qe=null;function re(a){se(a,0)}function te(a){var b=ue(a);if(Wa(b))return a}\nfunction ve(a,b){if("change"===a)return b}var we=!1;if(ia){var xe;if(ia){var ye="oninput"in document;if(!ye){var ze=document.createElement("div");ze.setAttribute("oninput","return;");ye="function"===typeof ze.oninput}xe=ye}else xe=!1;we=xe&&(!document.documentMode||9<document.documentMode)}function Ae(){pe&&(pe.detachEvent("onpropertychange",Be),qe=pe=null)}function Be(a){if("value"===a.propertyName&&te(qe)){var b=[];ne(b,qe,a,xb(a));Jb(re,b)}}\nfunction Ce(a,b,c){"focusin"===a?(Ae(),pe=b,qe=c,pe.attachEvent("onpropertychange",Be)):"focusout"===a&&Ae()}function De(a){if("selectionchange"===a||"keyup"===a||"keydown"===a)return te(qe)}function Ee(a,b){if("click"===a)return te(b)}function Fe(a,b){if("input"===a||"change"===a)return te(b)}function Ge(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var He="function"===typeof Object.is?Object.is:Ge;\nfunction Ie(a,b){if(He(a,b))return!0;if("object"!==typeof a||null===a||"object"!==typeof b||null===b)return!1;var c=Object.keys(a),d=Object.keys(b);if(c.length!==d.length)return!1;for(d=0;d<c.length;d++){var e=c[d];if(!ja.call(b,e)||!He(a[e],b[e]))return!1}return!0}function Je(a){for(;a&&a.firstChild;)a=a.firstChild;return a}\nfunction Ke(a,b){var c=Je(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;if(a<=b&&d>=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Je(c)}}function Le(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?Le(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}\nfunction Me(){for(var a=window,b=Xa();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Xa(a.document)}return b}function Ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}\nfunction Oe(a){var b=Me(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&Le(c.ownerDocument.documentElement,c)){if(null!==d&&Ne(c))if(b=d.start,a=d.end,void 0===a&&(a=b),"selectionStart"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=Ke(c,f);var g=Ke(c,\nd);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});"function"===typeof c.focus&&c.focus();for(c=0;c<b.length;c++)a=b[c],a.element.scrollLeft=a.left,a.element.scrollTop=a.top}}\nvar Pe=ia&&"documentMode"in document&&11>=document.documentMode,Qe=null,Re=null,Se=null,Te=!1;\nfunction Ue(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;Te||null==Qe||Qe!==Xa(d)||(d=Qe,"selectionStart"in d&&Ne(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Se&&Ie(Se,d)||(Se=d,d=oe(Re,"onSelect"),0<d.length&&(b=new td("onSelect","select",null,b,c),a.push({event:b,listeners:d}),b.target=Qe)))}\nfunction Ve(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;return c}var We={animationend:Ve("Animation","AnimationEnd"),animationiteration:Ve("Animation","AnimationIteration"),animationstart:Ve("Animation","AnimationStart"),transitionend:Ve("Transition","TransitionEnd")},Xe={},Ye={};\nia&&(Ye=document.createElement("div").style,"AnimationEvent"in window||(delete We.animationend.animation,delete We.animationiteration.animation,delete We.animationstart.animation),"TransitionEvent"in window||delete We.transitionend.transition);function Ze(a){if(Xe[a])return Xe[a];if(!We[a])return a;var b=We[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Ye)return Xe[a]=b[c];return a}var $e=Ze("animationend"),af=Ze("animationiteration"),bf=Ze("animationstart"),cf=Ze("transitionend"),df=new Map,ef="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");\nfunction ff(a,b){df.set(a,b);fa(b,[a])}for(var gf=0;gf<ef.length;gf++){var hf=ef[gf],jf=hf.toLowerCase(),kf=hf[0].toUpperCase()+hf.slice(1);ff(jf,"on"+kf)}ff($e,"onAnimationEnd");ff(af,"onAnimationIteration");ff(bf,"onAnimationStart");ff("dblclick","onDoubleClick");ff("focusin","onFocus");ff("focusout","onBlur");ff(cf,"onTransitionEnd");ha("onMouseEnter",["mouseout","mouseover"]);ha("onMouseLeave",["mouseout","mouseover"]);ha("onPointerEnter",["pointerout","pointerover"]);\nha("onPointerLeave",["pointerout","pointerover"]);fa("onChange","change click focusin focusout input keydown keyup selectionchange".split(" "));fa("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" "));fa("onBeforeInput",["compositionend","keypress","textInput","paste"]);fa("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" "));fa("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" "));\nfa("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var lf="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),mf=new Set("cancel close invalid load scroll toggle".split(" ").concat(lf));\nfunction nf(a,b,c){var d=a.type||"unknown-event";a.currentTarget=c;Ub(d,b,void 0,a);a.currentTarget=null}\nfunction se(a,b){b=0!==(b&4);for(var c=0;c<a.length;c++){var d=a[c],e=d.event;d=d.listeners;a:{var f=void 0;if(b)for(var g=d.length-1;0<=g;g--){var h=d[g],k=h.instance,l=h.currentTarget;h=h.listener;if(k!==f&&e.isPropagationStopped())break a;nf(e,h,l);f=k}else for(g=0;g<d.length;g++){h=d[g];k=h.instance;l=h.currentTarget;h=h.listener;if(k!==f&&e.isPropagationStopped())break a;nf(e,h,l);f=k}}}if(Qb)throw a=Rb,Qb=!1,Rb=null,a;}\nfunction D(a,b){var c=b[of];void 0===c&&(c=b[of]=new Set);var d=a+"__bubble";c.has(d)||(pf(b,a,2,!1),c.add(d))}function qf(a,b,c){var d=0;b&&(d|=4);pf(c,a,d,b)}var rf="_reactListening"+Math.random().toString(36).slice(2);function sf(a){if(!a[rf]){a[rf]=!0;da.forEach(function(b){"selectionchange"!==b&&(mf.has(b)||qf(b,!1,a),qf(b,!0,a))});var b=9===a.nodeType?a:a.ownerDocument;null===b||b[rf]||(b[rf]=!0,qf("selectionchange",!1,b))}}\nfunction pf(a,b,c,d){switch(jd(b)){case 1:var e=ed;break;case 4:e=gd;break;default:e=fd}c=e.bind(null,b,c,a);e=void 0;!Lb||"touchstart"!==b&&"touchmove"!==b&&"wheel"!==b||(e=!0);d?void 0!==e?a.addEventListener(b,c,{capture:!0,passive:e}):a.addEventListener(b,c,!0):void 0!==e?a.addEventListener(b,c,{passive:e}):a.addEventListener(b,c,!1)}\nfunction hd(a,b,c,d,e){var f=d;if(0===(b&1)&&0===(b&2)&&null!==d)a:for(;;){if(null===d)return;var g=d.tag;if(3===g||4===g){var h=d.stateNode.containerInfo;if(h===e||8===h.nodeType&&h.parentNode===e)break;if(4===g)for(g=d.return;null!==g;){var k=g.tag;if(3===k||4===k)if(k=g.stateNode.containerInfo,k===e||8===k.nodeType&&k.parentNode===e)return;g=g.return}for(;null!==h;){g=Wc(h);if(null===g)return;k=g.tag;if(5===k||6===k){d=f=g;continue a}h=h.parentNode}}d=d.return}Jb(function(){var d=f,e=xb(c),g=[];\na:{var h=df.get(a);if(void 0!==h){var k=td,n=a;switch(a){case "keypress":if(0===od(c))break a;case "keydown":case "keyup":k=Rd;break;case "focusin":n="focus";k=Fd;break;case "focusout":n="blur";k=Fd;break;case "beforeblur":case "afterblur":k=Fd;break;case "click":if(2===c.button)break a;case "auxclick":case "dblclick":case "mousedown":case "mousemove":case "mouseup":case "mouseout":case "mouseover":case "contextmenu":k=Bd;break;case "drag":case "dragend":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "dragstart":case "drop":k=\nDd;break;case "touchcancel":case "touchend":case "touchmove":case "touchstart":k=Vd;break;case $e:case af:case bf:k=Hd;break;case cf:k=Xd;break;case "scroll":k=vd;break;case "wheel":k=Zd;break;case "copy":case "cut":case "paste":k=Jd;break;case "gotpointercapture":case "lostpointercapture":case "pointercancel":case "pointerdown":case "pointermove":case "pointerout":case "pointerover":case "pointerup":k=Td}var t=0!==(b&4),J=!t&&"scroll"===a,x=t?null!==h?h+"Capture":null:h;t=[];for(var w=d,u;null!==\nw;){u=w;var F=u.stateNode;5===u.tag&&null!==F&&(u=F,null!==x&&(F=Kb(w,x),null!=F&&t.push(tf(w,F,u))));if(J)break;w=w.return}0<t.length&&(h=new k(h,n,null,c,e),g.push({event:h,listeners:t}))}}if(0===(b&7)){a:{h="mouseover"===a||"pointerover"===a;k="mouseout"===a||"pointerout"===a;if(h&&c!==wb&&(n=c.relatedTarget||c.fromElement)&&(Wc(n)||n[uf]))break a;if(k||h){h=e.window===e?e:(h=e.ownerDocument)?h.defaultView||h.parentWindow:window;if(k){if(n=c.relatedTarget||c.toElement,k=d,n=n?Wc(n):null,null!==\nn&&(J=Vb(n),n!==J||5!==n.tag&&6!==n.tag))n=null}else k=null,n=d;if(k!==n){t=Bd;F="onMouseLeave";x="onMouseEnter";w="mouse";if("pointerout"===a||"pointerover"===a)t=Td,F="onPointerLeave",x="onPointerEnter",w="pointer";J=null==k?h:ue(k);u=null==n?h:ue(n);h=new t(F,w+"leave",k,c,e);h.target=J;h.relatedTarget=u;F=null;Wc(e)===d&&(t=new t(x,w+"enter",n,c,e),t.target=u,t.relatedTarget=J,F=t);J=F;if(k&&n)b:{t=k;x=n;w=0;for(u=t;u;u=vf(u))w++;u=0;for(F=x;F;F=vf(F))u++;for(;0<w-u;)t=vf(t),w--;for(;0<u-w;)x=\nvf(x),u--;for(;w--;){if(t===x||null!==x&&t===x.alternate)break b;t=vf(t);x=vf(x)}t=null}else t=null;null!==k&&wf(g,h,k,t,!1);null!==n&&null!==J&&wf(g,J,n,t,!0)}}}a:{h=d?ue(d):window;k=h.nodeName&&h.nodeName.toLowerCase();if("select"===k||"input"===k&&"file"===h.type)var na=ve;else if(me(h))if(we)na=Fe;else{na=De;var xa=Ce}else(k=h.nodeName)&&"input"===k.toLowerCase()&&("checkbox"===h.type||"radio"===h.type)&&(na=Ee);if(na&&(na=na(a,d))){ne(g,na,c,e);break a}xa&&xa(a,h,d);"focusout"===a&&(xa=h._wrapperState)&&\nxa.controlled&&"number"===h.type&&cb(h,"number",h.value)}xa=d?ue(d):window;switch(a){case "focusin":if(me(xa)||"true"===xa.contentEditable)Qe=xa,Re=d,Se=null;break;case "focusout":Se=Re=Qe=null;break;case "mousedown":Te=!0;break;case "contextmenu":case "mouseup":case "dragend":Te=!1;Ue(g,c,e);break;case "selectionchange":if(Pe)break;case "keydown":case "keyup":Ue(g,c,e)}var $a;if(ae)b:{switch(a){case "compositionstart":var ba="onCompositionStart";break b;case "compositionend":ba="onCompositionEnd";\nbreak b;case "compositionupdate":ba="onCompositionUpdate";break b}ba=void 0}else ie?ge(a,c)&&(ba="onCompositionEnd"):"keydown"===a&&229===c.keyCode&&(ba="onCompositionStart");ba&&(de&&"ko"!==c.locale&&(ie||"onCompositionStart"!==ba?"onCompositionEnd"===ba&&ie&&($a=nd()):(kd=e,ld="value"in kd?kd.value:kd.textContent,ie=!0)),xa=oe(d,ba),0<xa.length&&(ba=new Ld(ba,a,null,c,e),g.push({event:ba,listeners:xa}),$a?ba.data=$a:($a=he(c),null!==$a&&(ba.data=$a))));if($a=ce?je(a,c):ke(a,c))d=oe(d,"onBeforeInput"),\n0<d.length&&(e=new Ld("onBeforeInput","beforeinput",null,c,e),g.push({event:e,listeners:d}),e.data=$a)}se(g,b)})}function tf(a,b,c){return{instance:a,listener:b,currentTarget:c}}function oe(a,b){for(var c=b+"Capture",d=[];null!==a;){var e=a,f=e.stateNode;5===e.tag&&null!==f&&(e=f,f=Kb(a,c),null!=f&&d.unshift(tf(a,f,e)),f=Kb(a,b),null!=f&&d.push(tf(a,f,e)));a=a.return}return d}function vf(a){if(null===a)return null;do a=a.return;while(a&&5!==a.tag);return a?a:null}\nfunction wf(a,b,c,d,e){for(var f=b._reactName,g=[];null!==c&&c!==d;){var h=c,k=h.alternate,l=h.stateNode;if(null!==k&&k===d)break;5===h.tag&&null!==l&&(h=l,e?(k=Kb(c,f),null!=k&&g.unshift(tf(c,k,h))):e||(k=Kb(c,f),null!=k&&g.push(tf(c,k,h))));c=c.return}0!==g.length&&a.push({event:b,listeners:g})}var xf=/\\r\\n?/g,yf=/\\u0000|\\uFFFD/g;function zf(a){return("string"===typeof a?a:""+a).replace(xf,"\\n").replace(yf,"")}function Af(a,b,c){b=zf(b);if(zf(a)!==b&&c)throw Error(p(425));}function Bf(){}\nvar Cf=null,Df=null;function Ef(a,b){return"textarea"===a||"noscript"===a||"string"===typeof b.children||"number"===typeof b.children||"object"===typeof b.dangerouslySetInnerHTML&&null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}\nvar Ff="function"===typeof setTimeout?setTimeout:void 0,Gf="function"===typeof clearTimeout?clearTimeout:void 0,Hf="function"===typeof Promise?Promise:void 0,Jf="function"===typeof queueMicrotask?queueMicrotask:"undefined"!==typeof Hf?function(a){return Hf.resolve(null).then(a).catch(If)}:Ff;function If(a){setTimeout(function(){throw a;})}\nfunction Kf(a,b){var c=b,d=0;do{var e=c.nextSibling;a.removeChild(c);if(e&&8===e.nodeType)if(c=e.data,"/$"===c){if(0===d){a.removeChild(e);bd(b);return}d--}else"$"!==c&&"$?"!==c&&"$!"!==c||d++;c=e}while(c);bd(b)}function Lf(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break;if(8===b){b=a.data;if("$"===b||"$!"===b||"$?"===b)break;if("/$"===b)return null}}return a}\nfunction Mf(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if("$"===c||"$!"===c||"$?"===c){if(0===b)return a;b--}else"/$"===c&&b++}a=a.previousSibling}return null}var Nf=Math.random().toString(36).slice(2),Of="__reactFiber$"+Nf,Pf="__reactProps$"+Nf,uf="__reactContainer$"+Nf,of="__reactEvents$"+Nf,Qf="__reactListeners$"+Nf,Rf="__reactHandles$"+Nf;\nfunction Wc(a){var b=a[Of];if(b)return b;for(var c=a.parentNode;c;){if(b=c[uf]||c[Of]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=Mf(a);null!==a;){if(c=a[Of])return c;a=Mf(a)}return b}a=c;c=a.parentNode}return null}function Cb(a){a=a[Of]||a[uf];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function ue(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(p(33));}function Db(a){return a[Pf]||null}var Sf=[],Tf=-1;function Uf(a){return{current:a}}\nfunction E(a){0>Tf||(a.current=Sf[Tf],Sf[Tf]=null,Tf--)}function G(a,b){Tf++;Sf[Tf]=a.current;a.current=b}var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a,b){var c=a.type.contextTypes;if(!c)return Vf;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}\nfunction Zf(a){a=a.childContextTypes;return null!==a&&void 0!==a}function $f(){E(Wf);E(H)}function ag(a,b,c){if(H.current!==Vf)throw Error(p(168));G(H,b);G(Wf,c)}function bg(a,b,c){var d=a.stateNode;b=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in b))throw Error(p(108,Ra(a)||"Unknown",e));return A({},c,d)}\nfunction cg(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Vf;Xf=H.current;G(H,a);G(Wf,Wf.current);return!0}function dg(a,b,c){var d=a.stateNode;if(!d)throw Error(p(169));c?(a=bg(a,b,Xf),d.__reactInternalMemoizedMergedChildContext=a,E(Wf),E(H),G(H,a)):E(Wf);G(Wf,c)}var eg=null,fg=!1,gg=!1;function hg(a){null===eg?eg=[a]:eg.push(a)}function ig(a){fg=!0;hg(a)}\nfunction jg(){if(!gg&&null!==eg){gg=!0;var a=0,b=C;try{var c=eg;for(C=1;a<c.length;a++){var d=c[a];do d=d(!0);while(null!==d)}eg=null;fg=!1}catch(e){throw null!==eg&&(eg=eg.slice(a+1)),ac(fc,jg),e;}finally{C=b,gg=!1}}return null}var kg=[],lg=0,mg=null,ng=0,og=[],pg=0,qg=null,rg=1,sg="";function tg(a,b){kg[lg++]=ng;kg[lg++]=mg;mg=a;ng=b}\nfunction ug(a,b,c){og[pg++]=rg;og[pg++]=sg;og[pg++]=qg;qg=a;var d=rg;a=sg;var e=32-oc(d)-1;d&=~(1<<e);c+=1;var f=32-oc(b)+e;if(30<f){var g=e-e%5;f=(d&(1<<g)-1).toString(32);d>>=g;e-=g;rg=1<<32-oc(b)+e|c<<e|d;sg=f+a}else rg=1<<f|c<<e|d,sg=a}function vg(a){null!==a.return&&(tg(a,1),ug(a,1,0))}function wg(a){for(;a===mg;)mg=kg[--lg],kg[lg]=null,ng=kg[--lg],kg[lg]=null;for(;a===qg;)qg=og[--pg],og[pg]=null,sg=og[--pg],og[pg]=null,rg=og[--pg],og[pg]=null}var xg=null,yg=null,I=!1,zg=null;\nfunction Ag(a,b){var c=Bg(5,null,null,0);c.elementType="DELETED";c.stateNode=b;c.return=a;b=a.deletions;null===b?(a.deletions=[c],a.flags|=16):b.push(c)}\nfunction Cg(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,xg=a,yg=Lf(b.firstChild),!0):!1;case 6:return b=""===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,xg=a,yg=null,!0):!1;case 13:return b=8!==b.nodeType?null:b,null!==b?(c=null!==qg?{id:rg,overflow:sg}:null,a.memoizedState={dehydrated:b,treeContext:c,retryLane:1073741824},c=Bg(18,null,null,0),c.stateNode=b,c.return=a,a.child=c,xg=a,yg=\nnull,!0):!1;default:return!1}}function Dg(a){return 0!==(a.mode&1)&&0===(a.flags&128)}function Eg(a){if(I){var b=yg;if(b){var c=b;if(!Cg(a,b)){if(Dg(a))throw Error(p(418));b=Lf(c.nextSibling);var d=xg;b&&Cg(a,b)?Ag(d,c):(a.flags=a.flags&-4097|2,I=!1,xg=a)}}else{if(Dg(a))throw Error(p(418));a.flags=a.flags&-4097|2;I=!1;xg=a}}}function Fg(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;xg=a}\nfunction Gg(a){if(a!==xg)return!1;if(!I)return Fg(a),I=!0,!1;var b;(b=3!==a.tag)&&!(b=5!==a.tag)&&(b=a.type,b="head"!==b&&"body"!==b&&!Ef(a.type,a.memoizedProps));if(b&&(b=yg)){if(Dg(a))throw Hg(),Error(p(418));for(;b;)Ag(a,b),b=Lf(b.nextSibling)}Fg(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(p(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if("/$"===c){if(0===b){yg=Lf(a.nextSibling);break a}b--}else"$"!==c&&"$!"!==c&&"$?"!==c||b++}a=a.nextSibling}yg=\nnull}}else yg=xg?Lf(a.stateNode.nextSibling):null;return!0}function Hg(){for(var a=yg;a;)a=Lf(a.nextSibling)}function Ig(){yg=xg=null;I=!1}function Jg(a){null===zg?zg=[a]:zg.push(a)}var Kg=ua.ReactCurrentBatchConfig;function Lg(a,b){if(a&&a.defaultProps){b=A({},b);a=a.defaultProps;for(var c in a)void 0===b[c]&&(b[c]=a[c]);return b}return b}var Mg=Uf(null),Ng=null,Og=null,Pg=null;function Qg(){Pg=Og=Ng=null}function Rg(a){var b=Mg.current;E(Mg);a._currentValue=b}\nfunction Sg(a,b,c){for(;null!==a;){var d=a.alternate;(a.childLanes&b)!==b?(a.childLanes|=b,null!==d&&(d.childLanes|=b)):null!==d&&(d.childLanes&b)!==b&&(d.childLanes|=b);if(a===c)break;a=a.return}}function Tg(a,b){Ng=a;Pg=Og=null;a=a.dependencies;null!==a&&null!==a.firstContext&&(0!==(a.lanes&b)&&(Ug=!0),a.firstContext=null)}\nfunction Vg(a){var b=a._currentValue;if(Pg!==a)if(a={context:a,memoizedValue:b,next:null},null===Og){if(null===Ng)throw Error(p(308));Og=a;Ng.dependencies={lanes:0,firstContext:a}}else Og=Og.next=a;return b}var Wg=null;function Xg(a){null===Wg?Wg=[a]:Wg.push(a)}function Yg(a,b,c,d){var e=b.interleaved;null===e?(c.next=c,Xg(b)):(c.next=e.next,e.next=c);b.interleaved=c;return Zg(a,d)}\nfunction Zg(a,b){a.lanes|=b;var c=a.alternate;null!==c&&(c.lanes|=b);c=a;for(a=a.return;null!==a;)a.childLanes|=b,c=a.alternate,null!==c&&(c.childLanes|=b),c=a,a=a.return;return 3===c.tag?c.stateNode:null}var $g=!1;function ah(a){a.updateQueue={baseState:a.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}\nfunction bh(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,firstBaseUpdate:a.firstBaseUpdate,lastBaseUpdate:a.lastBaseUpdate,shared:a.shared,effects:a.effects})}function ch(a,b){return{eventTime:a,lane:b,tag:0,payload:null,callback:null,next:null}}\nfunction dh(a,b,c){var d=a.updateQueue;if(null===d)return null;d=d.shared;if(0!==(K&2)){var e=d.pending;null===e?b.next=b:(b.next=e.next,e.next=b);d.pending=b;return Zg(a,c)}e=d.interleaved;null===e?(b.next=b,Xg(d)):(b.next=e.next,e.next=b);d.interleaved=b;return Zg(a,c)}function eh(a,b,c){b=b.updateQueue;if(null!==b&&(b=b.shared,0!==(c&4194240))){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nfunction fh(a,b){var c=a.updateQueue,d=a.alternate;if(null!==d&&(d=d.updateQueue,c===d)){var e=null,f=null;c=c.firstBaseUpdate;if(null!==c){do{var g={eventTime:c.eventTime,lane:c.lane,tag:c.tag,payload:c.payload,callback:c.callback,next:null};null===f?e=f=g:f=f.next=g;c=c.next}while(null!==c);null===f?e=f=b:f=f.next=b}else e=f=b;c={baseState:d.baseState,firstBaseUpdate:e,lastBaseUpdate:f,shared:d.shared,effects:d.effects};a.updateQueue=c;return}a=c.lastBaseUpdate;null===a?c.firstBaseUpdate=b:a.next=\nb;c.lastBaseUpdate=b}\nfunction gh(a,b,c,d){var e=a.updateQueue;$g=!1;var f=e.firstBaseUpdate,g=e.lastBaseUpdate,h=e.shared.pending;if(null!==h){e.shared.pending=null;var k=h,l=k.next;k.next=null;null===g?f=l:g.next=l;g=k;var m=a.alternate;null!==m&&(m=m.updateQueue,h=m.lastBaseUpdate,h!==g&&(null===h?m.firstBaseUpdate=l:h.next=l,m.lastBaseUpdate=k))}if(null!==f){var q=e.baseState;g=0;m=l=k=null;h=f;do{var r=h.lane,y=h.eventTime;if((d&r)===r){null!==m&&(m=m.next={eventTime:y,lane:0,tag:h.tag,payload:h.payload,callback:h.callback,\nnext:null});a:{var n=a,t=h;r=b;y=c;switch(t.tag){case 1:n=t.payload;if("function"===typeof n){q=n.call(y,q,r);break a}q=n;break a;case 3:n.flags=n.flags&-65537|128;case 0:n=t.payload;r="function"===typeof n?n.call(y,q,r):n;if(null===r||void 0===r)break a;q=A({},q,r);break a;case 2:$g=!0}}null!==h.callback&&0!==h.lane&&(a.flags|=64,r=e.effects,null===r?e.effects=[h]:r.push(h))}else y={eventTime:y,lane:r,tag:h.tag,payload:h.payload,callback:h.callback,next:null},null===m?(l=m=y,k=q):m=m.next=y,g|=r;\nh=h.next;if(null===h)if(h=e.shared.pending,null===h)break;else r=h,h=r.next,r.next=null,e.lastBaseUpdate=r,e.shared.pending=null}while(1);null===m&&(k=q);e.baseState=k;e.firstBaseUpdate=l;e.lastBaseUpdate=m;b=e.shared.interleaved;if(null!==b){e=b;do g|=e.lane,e=e.next;while(e!==b)}else null===f&&(e.shared.lanes=0);hh|=g;a.lanes=g;a.memoizedState=q}}\nfunction ih(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;b<a.length;b++){var d=a[b],e=d.callback;if(null!==e){d.callback=null;d=c;if("function"!==typeof e)throw Error(p(191,e));e.call(d)}}}var jh=(new aa.Component).refs;function kh(a,b,c,d){b=a.memoizedState;c=c(d,b);c=null===c||void 0===c?b:A({},b,c);a.memoizedState=c;0===a.lanes&&(a.updateQueue.baseState=c)}\nvar nh={isMounted:function(a){return(a=a._reactInternals)?Vb(a)===a:!1},enqueueSetState:function(a,b,c){a=a._reactInternals;var d=L(),e=lh(a),f=ch(d,e);f.payload=b;void 0!==c&&null!==c&&(f.callback=c);b=dh(a,f,e);null!==b&&(mh(b,a,e,d),eh(b,a,e))},enqueueReplaceState:function(a,b,c){a=a._reactInternals;var d=L(),e=lh(a),f=ch(d,e);f.tag=1;f.payload=b;void 0!==c&&null!==c&&(f.callback=c);b=dh(a,f,e);null!==b&&(mh(b,a,e,d),eh(b,a,e))},enqueueForceUpdate:function(a,b){a=a._reactInternals;var c=L(),d=\nlh(a),e=ch(c,d);e.tag=2;void 0!==b&&null!==b&&(e.callback=b);b=dh(a,e,d);null!==b&&(mh(b,a,d,c),eh(b,a,d))}};function oh(a,b,c,d,e,f,g){a=a.stateNode;return"function"===typeof a.shouldComponentUpdate?a.shouldComponentUpdate(d,f,g):b.prototype&&b.prototype.isPureReactComponent?!Ie(c,d)||!Ie(e,f):!0}\nfunction ph(a,b,c){var d=!1,e=Vf;var f=b.contextType;"object"===typeof f&&null!==f?f=Vg(f):(e=Zf(b)?Xf:H.current,d=b.contextTypes,f=(d=null!==d&&void 0!==d)?Yf(a,e):Vf);b=new b(c,f);a.memoizedState=null!==b.state&&void 0!==b.state?b.state:null;b.updater=nh;a.stateNode=b;b._reactInternals=a;d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=e,a.__reactInternalMemoizedMaskedChildContext=f);return b}\nfunction qh(a,b,c,d){a=b.state;"function"===typeof b.componentWillReceiveProps&&b.componentWillReceiveProps(c,d);"function"===typeof b.UNSAFE_componentWillReceiveProps&&b.UNSAFE_componentWillReceiveProps(c,d);b.state!==a&&nh.enqueueReplaceState(b,b.state,null)}\nfunction rh(a,b,c,d){var e=a.stateNode;e.props=c;e.state=a.memoizedState;e.refs=jh;ah(a);var f=b.contextType;"object"===typeof f&&null!==f?e.context=Vg(f):(f=Zf(b)?Xf:H.current,e.context=Yf(a,f));e.state=a.memoizedState;f=b.getDerivedStateFromProps;"function"===typeof f&&(kh(a,b,f,c),e.state=a.memoizedState);"function"===typeof b.getDerivedStateFromProps||"function"===typeof e.getSnapshotBeforeUpdate||"function"!==typeof e.UNSAFE_componentWillMount&&"function"!==typeof e.componentWillMount||(b=e.state,\n"function"===typeof e.componentWillMount&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&e.UNSAFE_componentWillMount(),b!==e.state&&nh.enqueueReplaceState(e,e.state,null),gh(a,c,e,d),e.state=a.memoizedState);"function"===typeof e.componentDidMount&&(a.flags|=4194308)}\nfunction sh(a,b,c){a=c.ref;if(null!==a&&"function"!==typeof a&&"object"!==typeof a){if(c._owner){c=c._owner;if(c){if(1!==c.tag)throw Error(p(309));var d=c.stateNode}if(!d)throw Error(p(147,a));var e=d,f=""+a;if(null!==b&&null!==b.ref&&"function"===typeof b.ref&&b.ref._stringRef===f)return b.ref;b=function(a){var b=e.refs;b===jh&&(b=e.refs={});null===a?delete b[f]:b[f]=a};b._stringRef=f;return b}if("string"!==typeof a)throw Error(p(284));if(!c._owner)throw Error(p(290,a));}return a}\nfunction th(a,b){a=Object.prototype.toString.call(b);throw Error(p(31,"[object Object]"===a?"object with keys {"+Object.keys(b).join(", ")+"}":a));}function uh(a){var b=a._init;return b(a._payload)}\nfunction vh(a){function b(b,c){if(a){var d=b.deletions;null===d?(b.deletions=[c],b.flags|=16):d.push(c)}}function c(c,d){if(!a)return null;for(;null!==d;)b(c,d),d=d.sibling;return null}function d(a,b){for(a=new Map;null!==b;)null!==b.key?a.set(b.key,b):a.set(b.index,b),b=b.sibling;return a}function e(a,b){a=wh(a,b);a.index=0;a.sibling=null;return a}function f(b,c,d){b.index=d;if(!a)return b.flags|=1048576,c;d=b.alternate;if(null!==d)return d=d.index,d<c?(b.flags|=2,c):d;b.flags|=2;return c}function g(b){a&&\nnull===b.alternate&&(b.flags|=2);return b}function h(a,b,c,d){if(null===b||6!==b.tag)return b=xh(c,a.mode,d),b.return=a,b;b=e(b,c);b.return=a;return b}function k(a,b,c,d){var f=c.type;if(f===ya)return m(a,b,c.props.children,d,c.key);if(null!==b&&(b.elementType===f||"object"===typeof f&&null!==f&&f.$$typeof===Ha&&uh(f)===b.type))return d=e(b,c.props),d.ref=sh(a,b,c),d.return=a,d;d=yh(c.type,c.key,c.props,null,a.mode,d);d.ref=sh(a,b,c);d.return=a;return d}function l(a,b,c,d){if(null===b||4!==b.tag||\nb.stateNode.containerInfo!==c.containerInfo||b.stateNode.implementation!==c.implementation)return b=zh(c,a.mode,d),b.return=a,b;b=e(b,c.children||[]);b.return=a;return b}function m(a,b,c,d,f){if(null===b||7!==b.tag)return b=Ah(c,a.mode,d,f),b.return=a,b;b=e(b,c);b.return=a;return b}function q(a,b,c){if("string"===typeof b&&""!==b||"number"===typeof b)return b=xh(""+b,a.mode,c),b.return=a,b;if("object"===typeof b&&null!==b){switch(b.$$typeof){case va:return c=yh(b.type,b.key,b.props,null,a.mode,c),\nc.ref=sh(a,null,b),c.return=a,c;case wa:return b=zh(b,a.mode,c),b.return=a,b;case Ha:var d=b._init;return q(a,d(b._payload),c)}if(eb(b)||Ka(b))return b=Ah(b,a.mode,c,null),b.return=a,b;th(a,b)}return null}function r(a,b,c,d){var e=null!==b?b.key:null;if("string"===typeof c&&""!==c||"number"===typeof c)return null!==e?null:h(a,b,""+c,d);if("object"===typeof c&&null!==c){switch(c.$$typeof){case va:return c.key===e?k(a,b,c,d):null;case wa:return c.key===e?l(a,b,c,d):null;case Ha:return e=c._init,r(a,\nb,e(c._payload),d)}if(eb(c)||Ka(c))return null!==e?null:m(a,b,c,d,null);th(a,c)}return null}function y(a,b,c,d,e){if("string"===typeof d&&""!==d||"number"===typeof d)return a=a.get(c)||null,h(b,a,""+d,e);if("object"===typeof d&&null!==d){switch(d.$$typeof){case va:return a=a.get(null===d.key?c:d.key)||null,k(b,a,d,e);case wa:return a=a.get(null===d.key?c:d.key)||null,l(b,a,d,e);case Ha:var f=d._init;return y(a,b,c,f(d._payload),e)}if(eb(d)||Ka(d))return a=a.get(c)||null,m(b,a,d,e,null);th(b,d)}return null}\nfunction n(e,g,h,k){for(var l=null,m=null,u=g,w=g=0,x=null;null!==u&&w<h.length;w++){u.index>w?(x=u,u=null):x=u.sibling;var n=r(e,u,h[w],k);if(null===n){null===u&&(u=x);break}a&&u&&null===n.alternate&&b(e,u);g=f(n,g,w);null===m?l=n:m.sibling=n;m=n;u=x}if(w===h.length)return c(e,u),I&&tg(e,w),l;if(null===u){for(;w<h.length;w++)u=q(e,h[w],k),null!==u&&(g=f(u,g,w),null===m?l=u:m.sibling=u,m=u);I&&tg(e,w);return l}for(u=d(e,u);w<h.length;w++)x=y(u,e,w,h[w],k),null!==x&&(a&&null!==x.alternate&&u.delete(null===\nx.key?w:x.key),g=f(x,g,w),null===m?l=x:m.sibling=x,m=x);a&&u.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function t(e,g,h,k){var l=Ka(h);if("function"!==typeof l)throw Error(p(150));h=l.call(h);if(null==h)throw Error(p(151));for(var u=l=null,m=g,w=g=0,x=null,n=h.next();null!==m&&!n.done;w++,n=h.next()){m.index>w?(x=m,m=null):x=m.sibling;var t=r(e,m,n.value,k);if(null===t){null===m&&(m=x);break}a&&m&&null===t.alternate&&b(e,m);g=f(t,g,w);null===u?l=t:u.sibling=t;u=t;m=x}if(n.done)return c(e,\nm),I&&tg(e,w),l;if(null===m){for(;!n.done;w++,n=h.next())n=q(e,n.value,k),null!==n&&(g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);I&&tg(e,w);return l}for(m=d(e,m);!n.done;w++,n=h.next())n=y(m,e,w,n.value,k),null!==n&&(a&&null!==n.alternate&&m.delete(null===n.key?w:n.key),g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);a&&m.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function J(a,d,f,h){"object"===typeof f&&null!==f&&f.type===ya&&null===f.key&&(f=f.props.children);if("object"===typeof f&&null!==f){switch(f.$$typeof){case va:a:{for(var k=\nf.key,l=d;null!==l;){if(l.key===k){k=f.type;if(k===ya){if(7===l.tag){c(a,l.sibling);d=e(l,f.props.children);d.return=a;a=d;break a}}else if(l.elementType===k||"object"===typeof k&&null!==k&&k.$$typeof===Ha&&uh(k)===l.type){c(a,l.sibling);d=e(l,f.props);d.ref=sh(a,l,f);d.return=a;a=d;break a}c(a,l);break}else b(a,l);l=l.sibling}f.type===ya?(d=Ah(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=yh(f.type,f.key,f.props,null,a.mode,h),h.ref=sh(a,d,f),h.return=a,a=h)}return g(a);case wa:a:{for(l=f.key;null!==\nd;){if(d.key===l)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=zh(f,a.mode,h);d.return=a;a=d}return g(a);case Ha:return l=f._init,J(a,d,l(f._payload),h)}if(eb(f))return n(a,d,f,h);if(Ka(f))return t(a,d,f,h);th(a,f)}return"string"===typeof f&&""!==f||"number"===typeof f?(f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):\n(c(a,d),d=xh(f,a.mode,h),d.return=a,a=d),g(a)):c(a,d)}return J}var Bh=vh(!0),Ch=vh(!1),Dh={},Eh=Uf(Dh),Fh=Uf(Dh),Gh=Uf(Dh);function Hh(a){if(a===Dh)throw Error(p(174));return a}function Ih(a,b){G(Gh,b);G(Fh,a);G(Eh,Dh);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:lb(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=lb(b,a)}E(Eh);G(Eh,b)}function Jh(){E(Eh);E(Fh);E(Gh)}\nfunction Kh(a){Hh(Gh.current);var b=Hh(Eh.current);var c=lb(b,a.type);b!==c&&(G(Fh,a),G(Eh,c))}function Lh(a){Fh.current===a&&(E(Eh),E(Fh))}var M=Uf(0);\nfunction Mh(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||"$?"===c.data||"$!"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&128))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}var Nh=[];\nfunction Oh(){for(var a=0;a<Nh.length;a++)Nh[a]._workInProgressVersionPrimary=null;Nh.length=0}var Ph=ua.ReactCurrentDispatcher,Qh=ua.ReactCurrentBatchConfig,Rh=0,N=null,O=null,P=null,Sh=!1,Th=!1,Uh=0,Vh=0;function Q(){throw Error(p(321));}function Wh(a,b){if(null===b)return!1;for(var c=0;c<b.length&&c<a.length;c++)if(!He(a[c],b[c]))return!1;return!0}\nfunction Xh(a,b,c,d,e,f){Rh=f;N=b;b.memoizedState=null;b.updateQueue=null;b.lanes=0;Ph.current=null===a||null===a.memoizedState?Yh:Zh;a=c(d,e);if(Th){f=0;do{Th=!1;Uh=0;if(25<=f)throw Error(p(301));f+=1;P=O=null;b.updateQueue=null;Ph.current=$h;a=c(d,e)}while(Th)}Ph.current=ai;b=null!==O&&null!==O.next;Rh=0;P=O=N=null;Sh=!1;if(b)throw Error(p(300));return a}function bi(){var a=0!==Uh;Uh=0;return a}\nfunction ci(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===P?N.memoizedState=P=a:P=P.next=a;return P}function di(){if(null===O){var a=N.alternate;a=null!==a?a.memoizedState:null}else a=O.next;var b=null===P?N.memoizedState:P.next;if(null!==b)P=b,O=a;else{if(null===a)throw Error(p(310));O=a;a={memoizedState:O.memoizedState,baseState:O.baseState,baseQueue:O.baseQueue,queue:O.queue,next:null};null===P?N.memoizedState=P=a:P=P.next=a}return P}\nfunction ei(a,b){return"function"===typeof b?b(a):b}\nfunction fi(a){var b=di(),c=b.queue;if(null===c)throw Error(p(311));c.lastRenderedReducer=a;var d=O,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){f=e.next;d=d.baseState;var h=g=null,k=null,l=f;do{var m=l.lane;if((Rh&m)===m)null!==k&&(k=k.next={lane:0,action:l.action,hasEagerState:l.hasEagerState,eagerState:l.eagerState,next:null}),d=l.hasEagerState?l.eagerState:a(d,l.action);else{var q={lane:m,action:l.action,hasEagerState:l.hasEagerState,\neagerState:l.eagerState,next:null};null===k?(h=k=q,g=d):k=k.next=q;N.lanes|=m;hh|=m}l=l.next}while(null!==l&&l!==f);null===k?g=d:k.next=h;He(d,b.memoizedState)||(Ug=!0);b.memoizedState=d;b.baseState=g;b.baseQueue=k;c.lastRenderedState=d}a=c.interleaved;if(null!==a){e=a;do f=e.lane,N.lanes|=f,hh|=f,e=e.next;while(e!==a)}else null===e&&(c.lanes=0);return[b.memoizedState,c.dispatch]}\nfunction gi(a){var b=di(),c=b.queue;if(null===c)throw Error(p(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);He(f,b.memoizedState)||(Ug=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function hi(){}\nfunction ii(a,b){var c=N,d=di(),e=b(),f=!He(d.memoizedState,e);f&&(d.memoizedState=e,Ug=!0);d=d.queue;ji(ki.bind(null,c,d,a),[a]);if(d.getSnapshot!==b||f||null!==P&&P.memoizedState.tag&1){c.flags|=2048;li(9,mi.bind(null,c,d,e,b),void 0,null);if(null===R)throw Error(p(349));0!==(Rh&30)||ni(c,b,e)}return e}function ni(a,b,c){a.flags|=16384;a={getSnapshot:b,value:c};b=N.updateQueue;null===b?(b={lastEffect:null,stores:null},N.updateQueue=b,b.stores=[a]):(c=b.stores,null===c?b.stores=[a]:c.push(a))}\nfunction mi(a,b,c,d){b.value=c;b.getSnapshot=d;oi(b)&&pi(a)}function ki(a,b,c){return c(function(){oi(b)&&pi(a)})}function oi(a){var b=a.getSnapshot;a=a.value;try{var c=b();return!He(a,c)}catch(d){return!0}}function pi(a){var b=Zg(a,1);null!==b&&mh(b,a,1,-1)}\nfunction qi(a){var b=ci();"function"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:ei,lastRenderedState:a};b.queue=a;a=a.dispatch=ri.bind(null,N,a);return[b.memoizedState,a]}\nfunction li(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};b=N.updateQueue;null===b?(b={lastEffect:null,stores:null},N.updateQueue=b,b.lastEffect=a.next=a):(c=b.lastEffect,null===c?b.lastEffect=a.next=a:(d=c.next,c.next=a,a.next=d,b.lastEffect=a));return a}function si(){return di().memoizedState}function ti(a,b,c,d){var e=ci();N.flags|=a;e.memoizedState=li(1|b,c,void 0,void 0===d?null:d)}\nfunction ui(a,b,c,d){var e=di();d=void 0===d?null:d;var f=void 0;if(null!==O){var g=O.memoizedState;f=g.destroy;if(null!==d&&Wh(d,g.deps)){e.memoizedState=li(b,c,f,d);return}}N.flags|=a;e.memoizedState=li(1|b,c,f,d)}function vi(a,b){return ti(8390656,8,a,b)}function ji(a,b){return ui(2048,8,a,b)}function wi(a,b){return ui(4,2,a,b)}function xi(a,b){return ui(4,4,a,b)}\nfunction yi(a,b){if("function"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function zi(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ui(4,4,yi.bind(null,b,a),c)}function Ai(){}function Bi(a,b){var c=di();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&Wh(b,d[1]))return d[0];c.memoizedState=[a,b];return a}\nfunction Ci(a,b){var c=di();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&Wh(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a}function Di(a,b,c){if(0===(Rh&21))return a.baseState&&(a.baseState=!1,Ug=!0),a.memoizedState=c;He(c,b)||(c=yc(),N.lanes|=c,hh|=c,a.baseState=!0);return b}function Ei(a,b){var c=C;C=0!==c&&4>c?c:4;a(!0);var d=Qh.transition;Qh.transition={};try{a(!1),b()}finally{C=c,Qh.transition=d}}function Fi(){return di().memoizedState}\nfunction Gi(a,b,c){var d=lh(a);c={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,c);else if(c=Yg(a,b,c,d),null!==c){var e=L();mh(c,a,d,e);Ji(c,b,d)}}\nfunction ri(a,b,c){var d=lh(a),e={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,e);else{var f=a.alternate;if(0===a.lanes&&(null===f||0===f.lanes)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,h=f(g,c);e.hasEagerState=!0;e.eagerState=h;if(He(h,g)){var k=b.interleaved;null===k?(e.next=e,Xg(b)):(e.next=k.next,k.next=e);b.interleaved=e;return}}catch(l){}finally{}c=Yg(a,b,e,d);null!==c&&(e=L(),mh(c,a,d,e),Ji(c,b,d))}}\nfunction Hi(a){var b=a.alternate;return a===N||null!==b&&b===N}function Ii(a,b){Th=Sh=!0;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}function Ji(a,b,c){if(0!==(c&4194240)){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nvar ai={readContext:Vg,useCallback:Q,useContext:Q,useEffect:Q,useImperativeHandle:Q,useInsertionEffect:Q,useLayoutEffect:Q,useMemo:Q,useReducer:Q,useRef:Q,useState:Q,useDebugValue:Q,useDeferredValue:Q,useTransition:Q,useMutableSource:Q,useSyncExternalStore:Q,useId:Q,unstable_isNewReconciler:!1},Yh={readContext:Vg,useCallback:function(a,b){ci().memoizedState=[a,void 0===b?null:b];return a},useContext:Vg,useEffect:vi,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ti(4194308,\n4,yi.bind(null,b,a),c)},useLayoutEffect:function(a,b){return ti(4194308,4,a,b)},useInsertionEffect:function(a,b){return ti(4,2,a,b)},useMemo:function(a,b){var c=ci();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=ci();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};d.queue=a;a=a.dispatch=Gi.bind(null,N,a);return[d.memoizedState,a]},useRef:function(a){var b=\nci();a={current:a};return b.memoizedState=a},useState:qi,useDebugValue:Ai,useDeferredValue:function(a){return ci().memoizedState=a},useTransition:function(){var a=qi(!1),b=a[0];a=Ei.bind(null,a[1]);ci().memoizedState=a;return[b,a]},useMutableSource:function(){},useSyncExternalStore:function(a,b,c){var d=N,e=ci();if(I){if(void 0===c)throw Error(p(407));c=c()}else{c=b();if(null===R)throw Error(p(349));0!==(Rh&30)||ni(d,b,c)}e.memoizedState=c;var f={value:c,getSnapshot:b};e.queue=f;vi(ki.bind(null,d,\nf,a),[a]);d.flags|=2048;li(9,mi.bind(null,d,f,c,b),void 0,null);return c},useId:function(){var a=ci(),b=R.identifierPrefix;if(I){var c=sg;var d=rg;c=(d&~(1<<32-oc(d)-1)).toString(32)+c;b=":"+b+"R"+c;c=Uh++;0<c&&(b+="H"+c.toString(32));b+=":"}else c=Vh++,b=":"+b+"r"+c.toString(32)+":";return a.memoizedState=b},unstable_isNewReconciler:!1},Zh={readContext:Vg,useCallback:Bi,useContext:Vg,useEffect:ji,useImperativeHandle:zi,useInsertionEffect:wi,useLayoutEffect:xi,useMemo:Ci,useReducer:fi,useRef:si,useState:function(){return fi(ei)},\nuseDebugValue:Ai,useDeferredValue:function(a){var b=di();return Di(b,O.memoizedState,a)},useTransition:function(){var a=fi(ei)[0],b=di().memoizedState;return[a,b]},useMutableSource:hi,useSyncExternalStore:ii,useId:Fi,unstable_isNewReconciler:!1},$h={readContext:Vg,useCallback:Bi,useContext:Vg,useEffect:ji,useImperativeHandle:zi,useInsertionEffect:wi,useLayoutEffect:xi,useMemo:Ci,useReducer:gi,useRef:si,useState:function(){return gi(ei)},useDebugValue:Ai,useDeferredValue:function(a){var b=di();return null===\nO?b.memoizedState=a:Di(b,O.memoizedState,a)},useTransition:function(){var a=gi(ei)[0],b=di().memoizedState;return[a,b]},useMutableSource:hi,useSyncExternalStore:ii,useId:Fi,unstable_isNewReconciler:!1};function Ki(a,b){try{var c="",d=b;do c+=Pa(d),d=d.return;while(d);var e=c}catch(f){e="\\nError generating stack: "+f.message+"\\n"+f.stack}return{value:a,source:b,stack:e,digest:null}}function Li(a,b,c){return{value:a,source:null,stack:null!=c?c:null,digest:null!=b?b:null}}\nfunction Mi(a,b){try{console.error(b.value)}catch(c){setTimeout(function(){throw c;})}}var Ni="function"===typeof WeakMap?WeakMap:Map;function Oi(a,b,c){c=ch(-1,c);c.tag=3;c.payload={element:null};var d=b.value;c.callback=function(){Pi||(Pi=!0,Qi=d);Mi(a,b)};return c}\nfunction Ri(a,b,c){c=ch(-1,c);c.tag=3;var d=a.type.getDerivedStateFromError;if("function"===typeof d){var e=b.value;c.payload=function(){return d(e)};c.callback=function(){Mi(a,b)}}var f=a.stateNode;null!==f&&"function"===typeof f.componentDidCatch&&(c.callback=function(){Mi(a,b);"function"!==typeof d&&(null===Si?Si=new Set([this]):Si.add(this));var c=b.stack;this.componentDidCatch(b.value,{componentStack:null!==c?c:""})});return c}\nfunction Ti(a,b,c){var d=a.pingCache;if(null===d){d=a.pingCache=new Ni;var e=new Set;d.set(b,e)}else e=d.get(b),void 0===e&&(e=new Set,d.set(b,e));e.has(c)||(e.add(c),a=Ui.bind(null,a,b,c),b.then(a,a))}function Vi(a){do{var b;if(b=13===a.tag)b=a.memoizedState,b=null!==b?null!==b.dehydrated?!0:!1:!0;if(b)return a;a=a.return}while(null!==a);return null}\nfunction Wi(a,b,c,d,e){if(0===(a.mode&1))return a===b?a.flags|=65536:(a.flags|=128,c.flags|=131072,c.flags&=-52805,1===c.tag&&(null===c.alternate?c.tag=17:(b=ch(-1,1),b.tag=2,dh(c,b,1))),c.lanes|=1),a;a.flags|=65536;a.lanes=e;return a}var Xi=ua.ReactCurrentOwner,Ug=!1;function Yi(a,b,c,d){b.child=null===a?Ch(b,null,c,d):Bh(b,a.child,c,d)}\nfunction Zi(a,b,c,d,e){c=c.render;var f=b.ref;Tg(b,e);d=Xh(a,b,c,d,f,e);c=bi();if(null!==a&&!Ug)return b.updateQueue=a.updateQueue,b.flags&=-2053,a.lanes&=~e,$i(a,b,e);I&&c&&vg(b);b.flags|=1;Yi(a,b,d,e);return b.child}\nfunction aj(a,b,c,d,e){if(null===a){var f=c.type;if("function"===typeof f&&!bj(f)&&void 0===f.defaultProps&&null===c.compare&&void 0===c.defaultProps)return b.tag=15,b.type=f,cj(a,b,f,d,e);a=yh(c.type,null,d,b,b.mode,e);a.ref=b.ref;a.return=b;return b.child=a}f=a.child;if(0===(a.lanes&e)){var g=f.memoizedProps;c=c.compare;c=null!==c?c:Ie;if(c(g,d)&&a.ref===b.ref)return $i(a,b,e)}b.flags|=1;a=wh(f,d);a.ref=b.ref;a.return=b;return b.child=a}\nfunction cj(a,b,c,d,e){if(null!==a){var f=a.memoizedProps;if(Ie(f,d)&&a.ref===b.ref)if(Ug=!1,b.pendingProps=d=f,0!==(a.lanes&e))0!==(a.flags&131072)&&(Ug=!0);else return b.lanes=a.lanes,$i(a,b,e)}return dj(a,b,c,d,e)}\nfunction ej(a,b,c){var d=b.pendingProps,e=d.children,f=null!==a?a.memoizedState:null;if("hidden"===d.mode)if(0===(b.mode&1))b.memoizedState={baseLanes:0,cachePool:null,transitions:null},G(fj,gj),gj|=c;else{if(0===(c&1073741824))return a=null!==f?f.baseLanes|c:c,b.lanes=b.childLanes=1073741824,b.memoizedState={baseLanes:a,cachePool:null,transitions:null},b.updateQueue=null,G(fj,gj),gj|=a,null;b.memoizedState={baseLanes:0,cachePool:null,transitions:null};d=null!==f?f.baseLanes:c;G(fj,gj);gj|=d}else null!==\nf?(d=f.baseLanes|c,b.memoizedState=null):d=c,G(fj,gj),gj|=d;Yi(a,b,e,c);return b.child}function hj(a,b){var c=b.ref;if(null===a&&null!==c||null!==a&&a.ref!==c)b.flags|=512,b.flags|=2097152}function dj(a,b,c,d,e){var f=Zf(c)?Xf:H.current;f=Yf(b,f);Tg(b,e);c=Xh(a,b,c,d,f,e);d=bi();if(null!==a&&!Ug)return b.updateQueue=a.updateQueue,b.flags&=-2053,a.lanes&=~e,$i(a,b,e);I&&d&&vg(b);b.flags|=1;Yi(a,b,c,e);return b.child}\nfunction ij(a,b,c,d,e){if(Zf(c)){var f=!0;cg(b)}else f=!1;Tg(b,e);if(null===b.stateNode)jj(a,b),ph(b,c,d),rh(b,c,d,e),d=!0;else if(null===a){var g=b.stateNode,h=b.memoizedProps;g.props=h;var k=g.context,l=c.contextType;"object"===typeof l&&null!==l?l=Vg(l):(l=Zf(c)?Xf:H.current,l=Yf(b,l));var m=c.getDerivedStateFromProps,q="function"===typeof m||"function"===typeof g.getSnapshotBeforeUpdate;q||"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||\n(h!==d||k!==l)&&qh(b,g,d,l);$g=!1;var r=b.memoizedState;g.state=r;gh(b,d,g,e);k=b.memoizedState;h!==d||r!==k||Wf.current||$g?("function"===typeof m&&(kh(b,c,m,d),k=b.memoizedState),(h=$g||oh(b,c,h,d,r,k,l))?(q||"function"!==typeof g.UNSAFE_componentWillMount&&"function"!==typeof g.componentWillMount||("function"===typeof g.componentWillMount&&g.componentWillMount(),"function"===typeof g.UNSAFE_componentWillMount&&g.UNSAFE_componentWillMount()),"function"===typeof g.componentDidMount&&(b.flags|=4194308)):\n("function"===typeof g.componentDidMount&&(b.flags|=4194308),b.memoizedProps=d,b.memoizedState=k),g.props=d,g.state=k,g.context=l,d=h):("function"===typeof g.componentDidMount&&(b.flags|=4194308),d=!1)}else{g=b.stateNode;bh(a,b);h=b.memoizedProps;l=b.type===b.elementType?h:Lg(b.type,h);g.props=l;q=b.pendingProps;r=g.context;k=c.contextType;"object"===typeof k&&null!==k?k=Vg(k):(k=Zf(c)?Xf:H.current,k=Yf(b,k));var y=c.getDerivedStateFromProps;(m="function"===typeof y||"function"===typeof g.getSnapshotBeforeUpdate)||\n"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||(h!==q||r!==k)&&qh(b,g,d,k);$g=!1;r=b.memoizedState;g.state=r;gh(b,d,g,e);var n=b.memoizedState;h!==q||r!==n||Wf.current||$g?("function"===typeof y&&(kh(b,c,y,d),n=b.memoizedState),(l=$g||oh(b,c,l,d,r,n,k)||!1)?(m||"function"!==typeof g.UNSAFE_componentWillUpdate&&"function"!==typeof g.componentWillUpdate||("function"===typeof g.componentWillUpdate&&g.componentWillUpdate(d,n,k),"function"===typeof g.UNSAFE_componentWillUpdate&&\ng.UNSAFE_componentWillUpdate(d,n,k)),"function"===typeof g.componentDidUpdate&&(b.flags|=4),"function"===typeof g.getSnapshotBeforeUpdate&&(b.flags|=1024)):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=1024),b.memoizedProps=d,b.memoizedState=n),g.props=d,g.state=n,g.context=k,d=l):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&r===\na.memoizedState||(b.flags|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=1024),d=!1)}return kj(a,b,c,d,f,e)}\nfunction kj(a,b,c,d,e,f){hj(a,b);var g=0!==(b.flags&128);if(!d&&!g)return e&&dg(b,c,!1),$i(a,b,f);d=b.stateNode;Xi.current=b;var h=g&&"function"!==typeof c.getDerivedStateFromError?null:d.render();b.flags|=1;null!==a&&g?(b.child=Bh(b,a.child,null,f),b.child=Bh(b,null,h,f)):Yi(a,b,h,f);b.memoizedState=d.state;e&&dg(b,c,!0);return b.child}function lj(a){var b=a.stateNode;b.pendingContext?ag(a,b.pendingContext,b.pendingContext!==b.context):b.context&&ag(a,b.context,!1);Ih(a,b.containerInfo)}\nfunction mj(a,b,c,d,e){Ig();Jg(e);b.flags|=256;Yi(a,b,c,d);return b.child}var nj={dehydrated:null,treeContext:null,retryLane:0};function oj(a){return{baseLanes:a,cachePool:null,transitions:null}}\nfunction pj(a,b,c){var d=b.pendingProps,e=M.current,f=!1,g=0!==(b.flags&128),h;(h=g)||(h=null!==a&&null===a.memoizedState?!1:0!==(e&2));if(h)f=!0,b.flags&=-129;else if(null===a||null!==a.memoizedState)e|=1;G(M,e&1);if(null===a){Eg(b);a=b.memoizedState;if(null!==a&&(a=a.dehydrated,null!==a))return 0===(b.mode&1)?b.lanes=1:"$!"===a.data?b.lanes=8:b.lanes=1073741824,null;g=d.children;a=d.fallback;return f?(d=b.mode,f=b.child,g={mode:"hidden",children:g},0===(d&1)&&null!==f?(f.childLanes=0,f.pendingProps=\ng):f=qj(g,d,0,null),a=Ah(a,d,c,null),f.return=b,a.return=b,f.sibling=a,b.child=f,b.child.memoizedState=oj(c),b.memoizedState=nj,a):rj(b,g)}e=a.memoizedState;if(null!==e&&(h=e.dehydrated,null!==h))return sj(a,b,g,d,h,e,c);if(f){f=d.fallback;g=b.mode;e=a.child;h=e.sibling;var k={mode:"hidden",children:d.children};0===(g&1)&&b.child!==e?(d=b.child,d.childLanes=0,d.pendingProps=k,b.deletions=null):(d=wh(e,k),d.subtreeFlags=e.subtreeFlags&14680064);null!==h?f=wh(h,f):(f=Ah(f,g,c,null),f.flags|=2);f.return=\nb;d.return=b;d.sibling=f;b.child=d;d=f;f=b.child;g=a.child.memoizedState;g=null===g?oj(c):{baseLanes:g.baseLanes|c,cachePool:null,transitions:g.transitions};f.memoizedState=g;f.childLanes=a.childLanes&~c;b.memoizedState=nj;return d}f=a.child;a=f.sibling;d=wh(f,{mode:"visible",children:d.children});0===(b.mode&1)&&(d.lanes=c);d.return=b;d.sibling=null;null!==a&&(c=b.deletions,null===c?(b.deletions=[a],b.flags|=16):c.push(a));b.child=d;b.memoizedState=null;return d}\nfunction rj(a,b){b=qj({mode:"visible",children:b},a.mode,0,null);b.return=a;return a.child=b}function tj(a,b,c,d){null!==d&&Jg(d);Bh(b,a.child,null,c);a=rj(b,b.pendingProps.children);a.flags|=2;b.memoizedState=null;return a}\nfunction sj(a,b,c,d,e,f,g){if(c){if(b.flags&256)return b.flags&=-257,d=Li(Error(p(422))),tj(a,b,g,d);if(null!==b.memoizedState)return b.child=a.child,b.flags|=128,null;f=d.fallback;e=b.mode;d=qj({mode:"visible",children:d.children},e,0,null);f=Ah(f,e,g,null);f.flags|=2;d.return=b;f.return=b;d.sibling=f;b.child=d;0!==(b.mode&1)&&Bh(b,a.child,null,g);b.child.memoizedState=oj(g);b.memoizedState=nj;return f}if(0===(b.mode&1))return tj(a,b,g,null);if("$!"===e.data){d=e.nextSibling&&e.nextSibling.dataset;\nif(d)var h=d.dgst;d=h;f=Error(p(419));d=Li(f,d,void 0);return tj(a,b,g,d)}h=0!==(g&a.childLanes);if(Ug||h){d=R;if(null!==d){switch(g&-g){case 4:e=2;break;case 16:e=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:e=32;break;case 536870912:e=268435456;break;default:e=0}e=0!==(e&(d.suspendedLanes|g))?0:e;\n0!==e&&e!==f.retryLane&&(f.retryLane=e,Zg(a,e),mh(d,a,e,-1))}uj();d=Li(Error(p(421)));return tj(a,b,g,d)}if("$?"===e.data)return b.flags|=128,b.child=a.child,b=vj.bind(null,a),e._reactRetry=b,null;a=f.treeContext;yg=Lf(e.nextSibling);xg=b;I=!0;zg=null;null!==a&&(og[pg++]=rg,og[pg++]=sg,og[pg++]=qg,rg=a.id,sg=a.overflow,qg=b);b=rj(b,d.children);b.flags|=4096;return b}function wj(a,b,c){a.lanes|=b;var d=a.alternate;null!==d&&(d.lanes|=b);Sg(a.return,b,c)}\nfunction xj(a,b,c,d,e){var f=a.memoizedState;null===f?a.memoizedState={isBackwards:b,rendering:null,renderingStartTime:0,last:d,tail:c,tailMode:e}:(f.isBackwards=b,f.rendering=null,f.renderingStartTime=0,f.last=d,f.tail=c,f.tailMode=e)}\nfunction yj(a,b,c){var d=b.pendingProps,e=d.revealOrder,f=d.tail;Yi(a,b,d.children,c);d=M.current;if(0!==(d&2))d=d&1|2,b.flags|=128;else{if(null!==a&&0!==(a.flags&128))a:for(a=b.child;null!==a;){if(13===a.tag)null!==a.memoizedState&&wj(a,c,b);else if(19===a.tag)wj(a,c,b);else if(null!==a.child){a.child.return=a;a=a.child;continue}if(a===b)break a;for(;null===a.sibling;){if(null===a.return||a.return===b)break a;a=a.return}a.sibling.return=a.return;a=a.sibling}d&=1}G(M,d);if(0===(b.mode&1))b.memoizedState=\nnull;else switch(e){case "forwards":c=b.child;for(e=null;null!==c;)a=c.alternate,null!==a&&null===Mh(a)&&(e=c),c=c.sibling;c=e;null===c?(e=b.child,b.child=null):(e=c.sibling,c.sibling=null);xj(b,!1,e,c,f);break;case "backwards":c=null;e=b.child;for(b.child=null;null!==e;){a=e.alternate;if(null!==a&&null===Mh(a)){b.child=e;break}a=e.sibling;e.sibling=c;c=e;e=a}xj(b,!0,c,null,f);break;case "together":xj(b,!1,null,null,void 0);break;default:b.memoizedState=null}return b.child}\nfunction jj(a,b){0===(b.mode&1)&&null!==a&&(a.alternate=null,b.alternate=null,b.flags|=2)}function $i(a,b,c){null!==a&&(b.dependencies=a.dependencies);hh|=b.lanes;if(0===(c&b.childLanes))return null;if(null!==a&&b.child!==a.child)throw Error(p(153));if(null!==b.child){a=b.child;c=wh(a,a.pendingProps);b.child=c;for(c.return=b;null!==a.sibling;)a=a.sibling,c=c.sibling=wh(a,a.pendingProps),c.return=b;c.sibling=null}return b.child}\nfunction zj(a,b,c){switch(b.tag){case 3:lj(b);Ig();break;case 5:Kh(b);break;case 1:Zf(b.type)&&cg(b);break;case 4:Ih(b,b.stateNode.containerInfo);break;case 10:var d=b.type._context,e=b.memoizedProps.value;G(Mg,d._currentValue);d._currentValue=e;break;case 13:d=b.memoizedState;if(null!==d){if(null!==d.dehydrated)return G(M,M.current&1),b.flags|=128,null;if(0!==(c&b.child.childLanes))return pj(a,b,c);G(M,M.current&1);a=$i(a,b,c);return null!==a?a.sibling:null}G(M,M.current&1);break;case 19:d=0!==(c&\nb.childLanes);if(0!==(a.flags&128)){if(d)return yj(a,b,c);b.flags|=128}e=b.memoizedState;null!==e&&(e.rendering=null,e.tail=null,e.lastEffect=null);G(M,M.current);if(d)break;else return null;case 22:case 23:return b.lanes=0,ej(a,b,c)}return $i(a,b,c)}var Aj,Bj,Cj,Dj;\nAj=function(a,b){for(var c=b.child;null!==c;){if(5===c.tag||6===c.tag)a.appendChild(c.stateNode);else if(4!==c.tag&&null!==c.child){c.child.return=c;c=c.child;continue}if(c===b)break;for(;null===c.sibling;){if(null===c.return||c.return===b)return;c=c.return}c.sibling.return=c.return;c=c.sibling}};Bj=function(){};\nCj=function(a,b,c,d){var e=a.memoizedProps;if(e!==d){a=b.stateNode;Hh(Eh.current);var f=null;switch(c){case "input":e=Ya(a,e);d=Ya(a,d);f=[];break;case "select":e=A({},e,{value:void 0});d=A({},d,{value:void 0});f=[];break;case "textarea":e=gb(a,e);d=gb(a,d);f=[];break;default:"function"!==typeof e.onClick&&"function"===typeof d.onClick&&(a.onclick=Bf)}ub(c,d);var g;c=null;for(l in e)if(!d.hasOwnProperty(l)&&e.hasOwnProperty(l)&&null!=e[l])if("style"===l){var h=e[l];for(g in h)h.hasOwnProperty(g)&&\n(c||(c={}),c[g]="")}else"dangerouslySetInnerHTML"!==l&&"children"!==l&&"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(ea.hasOwnProperty(l)?f||(f=[]):(f=f||[]).push(l,null));for(l in d){var k=d[l];h=null!=e?e[l]:void 0;if(d.hasOwnProperty(l)&&k!==h&&(null!=k||null!=h))if("style"===l)if(h){for(g in h)!h.hasOwnProperty(g)||k&&k.hasOwnProperty(g)||(c||(c={}),c[g]="");for(g in k)k.hasOwnProperty(g)&&h[g]!==k[g]&&(c||(c={}),c[g]=k[g])}else c||(f||(f=[]),f.push(l,\nc)),c=k;else"dangerouslySetInnerHTML"===l?(k=k?k.__html:void 0,h=h?h.__html:void 0,null!=k&&h!==k&&(f=f||[]).push(l,k)):"children"===l?"string"!==typeof k&&"number"!==typeof k||(f=f||[]).push(l,""+k):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&(ea.hasOwnProperty(l)?(null!=k&&"onScroll"===l&&D("scroll",a),f||h===k||(f=[])):(f=f||[]).push(l,k))}c&&(f=f||[]).push("style",c);var l=f;if(b.updateQueue=l)b.flags|=4}};Dj=function(a,b,c,d){c!==d&&(b.flags|=4)};\nfunction Ej(a,b){if(!I)switch(a.tailMode){case "hidden":b=a.tail;for(var c=null;null!==b;)null!==b.alternate&&(c=b),b=b.sibling;null===c?a.tail=null:c.sibling=null;break;case "collapsed":c=a.tail;for(var d=null;null!==c;)null!==c.alternate&&(d=c),c=c.sibling;null===d?b||null===a.tail?a.tail=null:a.tail.sibling=null:d.sibling=null}}\nfunction S(a){var b=null!==a.alternate&&a.alternate.child===a.child,c=0,d=0;if(b)for(var e=a.child;null!==e;)c|=e.lanes|e.childLanes,d|=e.subtreeFlags&14680064,d|=e.flags&14680064,e.return=a,e=e.sibling;else for(e=a.child;null!==e;)c|=e.lanes|e.childLanes,d|=e.subtreeFlags,d|=e.flags,e.return=a,e=e.sibling;a.subtreeFlags|=d;a.childLanes=c;return b}\nfunction Fj(a,b,c){var d=b.pendingProps;wg(b);switch(b.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return S(b),null;case 1:return Zf(b.type)&&$f(),S(b),null;case 3:d=b.stateNode;Jh();E(Wf);E(H);Oh();d.pendingContext&&(d.context=d.pendingContext,d.pendingContext=null);if(null===a||null===a.child)Gg(b)?b.flags|=4:null===a||a.memoizedState.isDehydrated&&0===(b.flags&256)||(b.flags|=1024,null!==zg&&(Gj(zg),zg=null));Bj(a,b);S(b);return null;case 5:Lh(b);var e=Hh(Gh.current);\nc=b.type;if(null!==a&&null!=b.stateNode)Cj(a,b,c,d,e),a.ref!==b.ref&&(b.flags|=512,b.flags|=2097152);else{if(!d){if(null===b.stateNode)throw Error(p(166));S(b);return null}a=Hh(Eh.current);if(Gg(b)){d=b.stateNode;c=b.type;var f=b.memoizedProps;d[Of]=b;d[Pf]=f;a=0!==(b.mode&1);switch(c){case "dialog":D("cancel",d);D("close",d);break;case "iframe":case "object":case "embed":D("load",d);break;case "video":case "audio":for(e=0;e<lf.length;e++)D(lf[e],d);break;case "source":D("error",d);break;case "img":case "image":case "link":D("error",\nd);D("load",d);break;case "details":D("toggle",d);break;case "input":Za(d,f);D("invalid",d);break;case "select":d._wrapperState={wasMultiple:!!f.multiple};D("invalid",d);break;case "textarea":hb(d,f),D("invalid",d)}ub(c,f);e=null;for(var g in f)if(f.hasOwnProperty(g)){var h=f[g];"children"===g?"string"===typeof h?d.textContent!==h&&(!0!==f.suppressHydrationWarning&&Af(d.textContent,h,a),e=["children",h]):"number"===typeof h&&d.textContent!==""+h&&(!0!==f.suppressHydrationWarning&&Af(d.textContent,\nh,a),e=["children",""+h]):ea.hasOwnProperty(g)&&null!=h&&"onScroll"===g&&D("scroll",d)}switch(c){case "input":Va(d);db(d,f,!0);break;case "textarea":Va(d);jb(d);break;case "select":case "option":break;default:"function"===typeof f.onClick&&(d.onclick=Bf)}d=e;b.updateQueue=d;null!==d&&(b.flags|=4)}else{g=9===e.nodeType?e:e.ownerDocument;"http://www.w3.org/1999/xhtml"===a&&(a=kb(c));"http://www.w3.org/1999/xhtml"===a?"script"===c?(a=g.createElement("div"),a.innerHTML="<script>\\x3c/script>",a=a.removeChild(a.firstChild)):\n"string"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),"select"===c&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Of]=b;a[Pf]=d;Aj(a,b,!1,!1);b.stateNode=a;a:{g=vb(c,d);switch(c){case "dialog":D("cancel",a);D("close",a);e=d;break;case "iframe":case "object":case "embed":D("load",a);e=d;break;case "video":case "audio":for(e=0;e<lf.length;e++)D(lf[e],a);e=d;break;case "source":D("error",a);e=d;break;case "img":case "image":case "link":D("error",\na);D("load",a);e=d;break;case "details":D("toggle",a);e=d;break;case "input":Za(a,d);e=Ya(a,d);D("invalid",a);break;case "option":e=d;break;case "select":a._wrapperState={wasMultiple:!!d.multiple};e=A({},d,{value:void 0});D("invalid",a);break;case "textarea":hb(a,d);e=gb(a,d);D("invalid",a);break;default:e=d}ub(c,e);h=e;for(f in h)if(h.hasOwnProperty(f)){var k=h[f];"style"===f?sb(a,k):"dangerouslySetInnerHTML"===f?(k=k?k.__html:void 0,null!=k&&nb(a,k)):"children"===f?"string"===typeof k?("textarea"!==\nc||""!==k)&&ob(a,k):"number"===typeof k&&ob(a,""+k):"suppressContentEditableWarning"!==f&&"suppressHydrationWarning"!==f&&"autoFocus"!==f&&(ea.hasOwnProperty(f)?null!=k&&"onScroll"===f&&D("scroll",a):null!=k&&ta(a,f,k,g))}switch(c){case "input":Va(a);db(a,d,!1);break;case "textarea":Va(a);jb(a);break;case "option":null!=d.value&&a.setAttribute("value",""+Sa(d.value));break;case "select":a.multiple=!!d.multiple;f=d.value;null!=f?fb(a,!!d.multiple,f,!1):null!=d.defaultValue&&fb(a,!!d.multiple,d.defaultValue,\n!0);break;default:"function"===typeof e.onClick&&(a.onclick=Bf)}switch(c){case "button":case "input":case "select":case "textarea":d=!!d.autoFocus;break a;case "img":d=!0;break a;default:d=!1}}d&&(b.flags|=4)}null!==b.ref&&(b.flags|=512,b.flags|=2097152)}S(b);return null;case 6:if(a&&null!=b.stateNode)Dj(a,b,a.memoizedProps,d);else{if("string"!==typeof d&&null===b.stateNode)throw Error(p(166));c=Hh(Gh.current);Hh(Eh.current);if(Gg(b)){d=b.stateNode;c=b.memoizedProps;d[Of]=b;if(f=d.nodeValue!==c)if(a=\nxg,null!==a)switch(a.tag){case 3:Af(d.nodeValue,c,0!==(a.mode&1));break;case 5:!0!==a.memoizedProps.suppressHydrationWarning&&Af(d.nodeValue,c,0!==(a.mode&1))}f&&(b.flags|=4)}else d=(9===c.nodeType?c:c.ownerDocument).createTextNode(d),d[Of]=b,b.stateNode=d}S(b);return null;case 13:E(M);d=b.memoizedState;if(null===a||null!==a.memoizedState&&null!==a.memoizedState.dehydrated){if(I&&null!==yg&&0!==(b.mode&1)&&0===(b.flags&128))Hg(),Ig(),b.flags|=98560,f=!1;else if(f=Gg(b),null!==d&&null!==d.dehydrated){if(null===\na){if(!f)throw Error(p(318));f=b.memoizedState;f=null!==f?f.dehydrated:null;if(!f)throw Error(p(317));f[Of]=b}else Ig(),0===(b.flags&128)&&(b.memoizedState=null),b.flags|=4;S(b);f=!1}else null!==zg&&(Gj(zg),zg=null),f=!0;if(!f)return b.flags&65536?b:null}if(0!==(b.flags&128))return b.lanes=c,b;d=null!==d;d!==(null!==a&&null!==a.memoizedState)&&d&&(b.child.flags|=8192,0!==(b.mode&1)&&(null===a||0!==(M.current&1)?0===T&&(T=3):uj()));null!==b.updateQueue&&(b.flags|=4);S(b);return null;case 4:return Jh(),\nBj(a,b),null===a&&sf(b.stateNode.containerInfo),S(b),null;case 10:return Rg(b.type._context),S(b),null;case 17:return Zf(b.type)&&$f(),S(b),null;case 19:E(M);f=b.memoizedState;if(null===f)return S(b),null;d=0!==(b.flags&128);g=f.rendering;if(null===g)if(d)Ej(f,!1);else{if(0!==T||null!==a&&0!==(a.flags&128))for(a=b.child;null!==a;){g=Mh(a);if(null!==g){b.flags|=128;Ej(f,!1);d=g.updateQueue;null!==d&&(b.updateQueue=d,b.flags|=4);b.subtreeFlags=0;d=c;for(c=b.child;null!==c;)f=c,a=d,f.flags&=14680066,\ng=f.alternate,null===g?(f.childLanes=0,f.lanes=a,f.child=null,f.subtreeFlags=0,f.memoizedProps=null,f.memoizedState=null,f.updateQueue=null,f.dependencies=null,f.stateNode=null):(f.childLanes=g.childLanes,f.lanes=g.lanes,f.child=g.child,f.subtreeFlags=0,f.deletions=null,f.memoizedProps=g.memoizedProps,f.memoizedState=g.memoizedState,f.updateQueue=g.updateQueue,f.type=g.type,a=g.dependencies,f.dependencies=null===a?null:{lanes:a.lanes,firstContext:a.firstContext}),c=c.sibling;G(M,M.current&1|2);return b.child}a=\na.sibling}null!==f.tail&&B()>Hj&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304)}else{if(!d)if(a=Mh(g),null!==a){if(b.flags|=128,d=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),Ej(f,!0),null===f.tail&&"hidden"===f.tailMode&&!g.alternate&&!I)return S(b),null}else 2*B()-f.renderingStartTime>Hj&&1073741824!==c&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304);f.isBackwards?(g.sibling=b.child,b.child=g):(c=f.last,null!==c?c.sibling=g:b.child=g,f.last=g)}if(null!==f.tail)return b=f.tail,f.rendering=\nb,f.tail=b.sibling,f.renderingStartTime=B(),b.sibling=null,c=M.current,G(M,d?c&1|2:c&1),b;S(b);return null;case 22:case 23:return Ij(),d=null!==b.memoizedState,null!==a&&null!==a.memoizedState!==d&&(b.flags|=8192),d&&0!==(b.mode&1)?0!==(gj&1073741824)&&(S(b),b.subtreeFlags&6&&(b.flags|=8192)):S(b),null;case 24:return null;case 25:return null}throw Error(p(156,b.tag));}\nfunction Jj(a,b){wg(b);switch(b.tag){case 1:return Zf(b.type)&&$f(),a=b.flags,a&65536?(b.flags=a&-65537|128,b):null;case 3:return Jh(),E(Wf),E(H),Oh(),a=b.flags,0!==(a&65536)&&0===(a&128)?(b.flags=a&-65537|128,b):null;case 5:return Lh(b),null;case 13:E(M);a=b.memoizedState;if(null!==a&&null!==a.dehydrated){if(null===b.alternate)throw Error(p(340));Ig()}a=b.flags;return a&65536?(b.flags=a&-65537|128,b):null;case 19:return E(M),null;case 4:return Jh(),null;case 10:return Rg(b.type._context),null;case 22:case 23:return Ij(),\nnull;case 24:return null;default:return null}}var Kj=!1,U=!1,Lj="function"===typeof WeakSet?WeakSet:Set,V=null;function Mj(a,b){var c=a.ref;if(null!==c)if("function"===typeof c)try{c(null)}catch(d){W(a,b,d)}else c.current=null}function Nj(a,b,c){try{c()}catch(d){W(a,b,d)}}var Oj=!1;\nfunction Pj(a,b){Cf=dd;a=Me();if(Ne(a)){if("selectionStart"in a)var c={start:a.selectionStart,end:a.selectionEnd};else a:{c=(c=a.ownerDocument)&&c.defaultView||window;var d=c.getSelection&&c.getSelection();if(d&&0!==d.rangeCount){c=d.anchorNode;var e=d.anchorOffset,f=d.focusNode;d=d.focusOffset;try{c.nodeType,f.nodeType}catch(F){c=null;break a}var g=0,h=-1,k=-1,l=0,m=0,q=a,r=null;b:for(;;){for(var y;;){q!==c||0!==e&&3!==q.nodeType||(h=g+e);q!==f||0!==d&&3!==q.nodeType||(k=g+d);3===q.nodeType&&(g+=\nq.nodeValue.length);if(null===(y=q.firstChild))break;r=q;q=y}for(;;){if(q===a)break b;r===c&&++l===e&&(h=g);r===f&&++m===d&&(k=g);if(null!==(y=q.nextSibling))break;q=r;r=q.parentNode}q=y}c=-1===h||-1===k?null:{start:h,end:k}}else c=null}c=c||{start:0,end:0}}else c=null;Df={focusedElem:a,selectionRange:c};dd=!1;for(V=b;null!==V;)if(b=V,a=b.child,0!==(b.subtreeFlags&1028)&&null!==a)a.return=b,V=a;else for(;null!==V;){b=V;try{var n=b.alternate;if(0!==(b.flags&1024))switch(b.tag){case 0:case 11:case 15:break;\ncase 1:if(null!==n){var t=n.memoizedProps,J=n.memoizedState,x=b.stateNode,w=x.getSnapshotBeforeUpdate(b.elementType===b.type?t:Lg(b.type,t),J);x.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var u=b.stateNode.containerInfo;1===u.nodeType?u.textContent="":9===u.nodeType&&u.documentElement&&u.removeChild(u.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p(163));}}catch(F){W(b,b.return,F)}a=b.sibling;if(null!==a){a.return=b.return;V=a;break}V=b.return}n=Oj;Oj=!1;return n}\nfunction Qj(a,b,c){var d=b.updateQueue;d=null!==d?d.lastEffect:null;if(null!==d){var e=d=d.next;do{if((e.tag&a)===a){var f=e.destroy;e.destroy=void 0;void 0!==f&&Nj(b,c,f)}e=e.next}while(e!==d)}}function Rj(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function Sj(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=c;break;default:a=c}"function"===typeof b?b(a):b.current=a}}\nfunction Tj(a){var b=a.alternate;null!==b&&(a.alternate=null,Tj(b));a.child=null;a.deletions=null;a.sibling=null;5===a.tag&&(b=a.stateNode,null!==b&&(delete b[Of],delete b[Pf],delete b[of],delete b[Qf],delete b[Rf]));a.stateNode=null;a.return=null;a.dependencies=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.stateNode=null;a.updateQueue=null}function Uj(a){return 5===a.tag||3===a.tag||4===a.tag}\nfunction Vj(a){a:for(;;){for(;null===a.sibling;){if(null===a.return||Uj(a.return))return null;a=a.return}a.sibling.return=a.return;for(a=a.sibling;5!==a.tag&&6!==a.tag&&18!==a.tag;){if(a.flags&2)continue a;if(null===a.child||4===a.tag)continue a;else a.child.return=a,a=a.child}if(!(a.flags&2))return a.stateNode}}\nfunction Wj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Bf));else if(4!==d&&(a=a.child,null!==a))for(Wj(a,b,c),a=a.sibling;null!==a;)Wj(a,b,c),a=a.sibling}\nfunction Xj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?c.insertBefore(a,b):c.appendChild(a);else if(4!==d&&(a=a.child,null!==a))for(Xj(a,b,c),a=a.sibling;null!==a;)Xj(a,b,c),a=a.sibling}var X=null,Yj=!1;function Zj(a,b,c){for(c=c.child;null!==c;)ak(a,b,c),c=c.sibling}\nfunction ak(a,b,c){if(lc&&"function"===typeof lc.onCommitFiberUnmount)try{lc.onCommitFiberUnmount(kc,c)}catch(h){}switch(c.tag){case 5:U||Mj(c,b);case 6:var d=X,e=Yj;X=null;Zj(a,b,c);X=d;Yj=e;null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?a.parentNode.removeChild(c):a.removeChild(c)):X.removeChild(c.stateNode));break;case 18:null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?Kf(a.parentNode,c):1===a.nodeType&&Kf(a,c),bd(a)):Kf(X,c.stateNode));break;case 4:d=X;e=Yj;X=c.stateNode.containerInfo;Yj=!0;\nZj(a,b,c);X=d;Yj=e;break;case 0:case 11:case 14:case 15:if(!U&&(d=c.updateQueue,null!==d&&(d=d.lastEffect,null!==d))){e=d=d.next;do{var f=e,g=f.destroy;f=f.tag;void 0!==g&&(0!==(f&2)?Nj(c,b,g):0!==(f&4)&&Nj(c,b,g));e=e.next}while(e!==d)}Zj(a,b,c);break;case 1:if(!U&&(Mj(c,b),d=c.stateNode,"function"===typeof d.componentWillUnmount))try{d.props=c.memoizedProps,d.state=c.memoizedState,d.componentWillUnmount()}catch(h){W(c,b,h)}Zj(a,b,c);break;case 21:Zj(a,b,c);break;case 22:c.mode&1?(U=(d=U)||null!==\nc.memoizedState,Zj(a,b,c),U=d):Zj(a,b,c);break;default:Zj(a,b,c)}}function bk(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=new Lj);b.forEach(function(b){var d=ck.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}}\nfunction dk(a,b){var c=b.deletions;if(null!==c)for(var d=0;d<c.length;d++){var e=c[d];try{var f=a,g=b,h=g;a:for(;null!==h;){switch(h.tag){case 5:X=h.stateNode;Yj=!1;break a;case 3:X=h.stateNode.containerInfo;Yj=!0;break a;case 4:X=h.stateNode.containerInfo;Yj=!0;break a}h=h.return}if(null===X)throw Error(p(160));ak(f,g,e);X=null;Yj=!1;var k=e.alternate;null!==k&&(k.return=null);e.return=null}catch(l){W(e,b,l)}}if(b.subtreeFlags&12854)for(b=b.child;null!==b;)ek(b,a),b=b.sibling}\nfunction ek(a,b){var c=a.alternate,d=a.flags;switch(a.tag){case 0:case 11:case 14:case 15:dk(b,a);fk(a);if(d&4){try{Qj(3,a,a.return),Rj(3,a)}catch(t){W(a,a.return,t)}try{Qj(5,a,a.return)}catch(t){W(a,a.return,t)}}break;case 1:dk(b,a);fk(a);d&512&&null!==c&&Mj(c,c.return);break;case 5:dk(b,a);fk(a);d&512&&null!==c&&Mj(c,c.return);if(a.flags&32){var e=a.stateNode;try{ob(e,"")}catch(t){W(a,a.return,t)}}if(d&4&&(e=a.stateNode,null!=e)){var f=a.memoizedProps,g=null!==c?c.memoizedProps:f,h=a.type,k=a.updateQueue;\na.updateQueue=null;if(null!==k)try{"input"===h&&"radio"===f.type&&null!=f.name&&ab(e,f);vb(h,g);var l=vb(h,f);for(g=0;g<k.length;g+=2){var m=k[g],q=k[g+1];"style"===m?sb(e,q):"dangerouslySetInnerHTML"===m?nb(e,q):"children"===m?ob(e,q):ta(e,m,q,l)}switch(h){case "input":bb(e,f);break;case "textarea":ib(e,f);break;case "select":var r=e._wrapperState.wasMultiple;e._wrapperState.wasMultiple=!!f.multiple;var y=f.value;null!=y?fb(e,!!f.multiple,y,!1):r!==!!f.multiple&&(null!=f.defaultValue?fb(e,!!f.multiple,\nf.defaultValue,!0):fb(e,!!f.multiple,f.multiple?[]:"",!1))}e[Pf]=f}catch(t){W(a,a.return,t)}}break;case 6:dk(b,a);fk(a);if(d&4){if(null===a.stateNode)throw Error(p(162));e=a.stateNode;f=a.memoizedProps;try{e.nodeValue=f}catch(t){W(a,a.return,t)}}break;case 3:dk(b,a);fk(a);if(d&4&&null!==c&&c.memoizedState.isDehydrated)try{bd(b.containerInfo)}catch(t){W(a,a.return,t)}break;case 4:dk(b,a);fk(a);break;case 13:dk(b,a);fk(a);e=a.child;e.flags&8192&&(f=null!==e.memoizedState,e.stateNode.isHidden=f,!f||\nnull!==e.alternate&&null!==e.alternate.memoizedState||(gk=B()));d&4&&bk(a);break;case 22:m=null!==c&&null!==c.memoizedState;a.mode&1?(U=(l=U)||m,dk(b,a),U=l):dk(b,a);fk(a);if(d&8192){l=null!==a.memoizedState;if((a.stateNode.isHidden=l)&&!m&&0!==(a.mode&1))for(V=a,m=a.child;null!==m;){for(q=V=m;null!==V;){r=V;y=r.child;switch(r.tag){case 0:case 11:case 14:case 15:Qj(4,r,r.return);break;case 1:Mj(r,r.return);var n=r.stateNode;if("function"===typeof n.componentWillUnmount){d=r;c=r.return;try{b=d,n.props=\nb.memoizedProps,n.state=b.memoizedState,n.componentWillUnmount()}catch(t){W(d,c,t)}}break;case 5:Mj(r,r.return);break;case 22:if(null!==r.memoizedState){hk(q);continue}}null!==y?(y.return=r,V=y):hk(q)}m=m.sibling}a:for(m=null,q=a;;){if(5===q.tag){if(null===m){m=q;try{e=q.stateNode,l?(f=e.style,"function"===typeof f.setProperty?f.setProperty("display","none","important"):f.display="none"):(h=q.stateNode,k=q.memoizedProps.style,g=void 0!==k&&null!==k&&k.hasOwnProperty("display")?k.display:null,h.style.display=\nrb("display",g))}catch(t){W(a,a.return,t)}}}else if(6===q.tag){if(null===m)try{q.stateNode.nodeValue=l?"":q.memoizedProps}catch(t){W(a,a.return,t)}}else if((22!==q.tag&&23!==q.tag||null===q.memoizedState||q===a)&&null!==q.child){q.child.return=q;q=q.child;continue}if(q===a)break a;for(;null===q.sibling;){if(null===q.return||q.return===a)break a;m===q&&(m=null);q=q.return}m===q&&(m=null);q.sibling.return=q.return;q=q.sibling}}break;case 19:dk(b,a);fk(a);d&4&&bk(a);break;case 21:break;default:dk(b,\na),fk(a)}}function fk(a){var b=a.flags;if(b&2){try{a:{for(var c=a.return;null!==c;){if(Uj(c)){var d=c;break a}c=c.return}throw Error(p(160));}switch(d.tag){case 5:var e=d.stateNode;d.flags&32&&(ob(e,""),d.flags&=-33);var f=Vj(a);Xj(a,f,e);break;case 3:case 4:var g=d.stateNode.containerInfo,h=Vj(a);Wj(a,h,g);break;default:throw Error(p(161));}}catch(k){W(a,a.return,k)}a.flags&=-3}b&4096&&(a.flags&=-4097)}function ik(a,b,c){V=a;jk(a,b,c)}\nfunction jk(a,b,c){for(var d=0!==(a.mode&1);null!==V;){var e=V,f=e.child;if(22===e.tag&&d){var g=null!==e.memoizedState||Kj;if(!g){var h=e.alternate,k=null!==h&&null!==h.memoizedState||U;h=Kj;var l=U;Kj=g;if((U=k)&&!l)for(V=e;null!==V;)g=V,k=g.child,22===g.tag&&null!==g.memoizedState?kk(e):null!==k?(k.return=g,V=k):kk(e);for(;null!==f;)V=f,jk(f,b,c),f=f.sibling;V=e;Kj=h;U=l}lk(a,b,c)}else 0!==(e.subtreeFlags&8772)&&null!==f?(f.return=e,V=f):lk(a,b,c)}}\nfunction lk(a){for(;null!==V;){var b=V;if(0!==(b.flags&8772)){var c=b.alternate;try{if(0!==(b.flags&8772))switch(b.tag){case 0:case 11:case 15:U||Rj(5,b);break;case 1:var d=b.stateNode;if(b.flags&4&&!U)if(null===c)d.componentDidMount();else{var e=b.elementType===b.type?c.memoizedProps:Lg(b.type,c.memoizedProps);d.componentDidUpdate(e,c.memoizedState,d.__reactInternalSnapshotBeforeUpdate)}var f=b.updateQueue;null!==f&&ih(b,f,d);break;case 3:var g=b.updateQueue;if(null!==g){c=null;if(null!==b.child)switch(b.child.tag){case 5:c=\nb.child.stateNode;break;case 1:c=b.child.stateNode}ih(b,g,c)}break;case 5:var h=b.stateNode;if(null===c&&b.flags&4){c=h;var k=b.memoizedProps;switch(b.type){case "button":case "input":case "select":case "textarea":k.autoFocus&&c.focus();break;case "img":k.src&&(c.src=k.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(null===b.memoizedState){var l=b.alternate;if(null!==l){var m=l.memoizedState;if(null!==m){var q=m.dehydrated;null!==q&&bd(q)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;\ndefault:throw Error(p(163));}U||b.flags&512&&Sj(b)}catch(r){W(b,b.return,r)}}if(b===a){V=null;break}c=b.sibling;if(null!==c){c.return=b.return;V=c;break}V=b.return}}function hk(a){for(;null!==V;){var b=V;if(b===a){V=null;break}var c=b.sibling;if(null!==c){c.return=b.return;V=c;break}V=b.return}}\nfunction kk(a){for(;null!==V;){var b=V;try{switch(b.tag){case 0:case 11:case 15:var c=b.return;try{Rj(4,b)}catch(k){W(b,c,k)}break;case 1:var d=b.stateNode;if("function"===typeof d.componentDidMount){var e=b.return;try{d.componentDidMount()}catch(k){W(b,e,k)}}var f=b.return;try{Sj(b)}catch(k){W(b,f,k)}break;case 5:var g=b.return;try{Sj(b)}catch(k){W(b,g,k)}}}catch(k){W(b,b.return,k)}if(b===a){V=null;break}var h=b.sibling;if(null!==h){h.return=b.return;V=h;break}V=b.return}}\nvar mk=Math.ceil,nk=ua.ReactCurrentDispatcher,ok=ua.ReactCurrentOwner,pk=ua.ReactCurrentBatchConfig,K=0,R=null,Y=null,Z=0,gj=0,fj=Uf(0),T=0,qk=null,hh=0,rk=0,sk=0,tk=null,uk=null,gk=0,Hj=Infinity,vk=null,Pi=!1,Qi=null,Si=null,wk=!1,xk=null,yk=0,zk=0,Ak=null,Bk=-1,Ck=0;function L(){return 0!==(K&6)?B():-1!==Bk?Bk:Bk=B()}\nfunction lh(a){if(0===(a.mode&1))return 1;if(0!==(K&2)&&0!==Z)return Z&-Z;if(null!==Kg.transition)return 0===Ck&&(Ck=yc()),Ck;a=C;if(0!==a)return a;a=window.event;a=void 0===a?16:jd(a.type);return a}function mh(a,b,c,d){if(50<zk)throw zk=0,Ak=null,Error(p(185));Ac(a,c,d);if(0===(K&2)||a!==R)a===R&&(0===(K&2)&&(rk|=c),4===T&&Dk(a,Z)),Ek(a,d),1===c&&0===K&&0===(b.mode&1)&&(Hj=B()+500,fg&&jg())}\nfunction Ek(a,b){var c=a.callbackNode;wc(a,b);var d=uc(a,a===R?Z:0);if(0===d)null!==c&&bc(c),a.callbackNode=null,a.callbackPriority=0;else if(b=d&-d,a.callbackPriority!==b){null!=c&&bc(c);if(1===b)0===a.tag?ig(Fk.bind(null,a)):hg(Fk.bind(null,a)),Jf(function(){0===(K&6)&&jg()}),c=null;else{switch(Dc(d)){case 1:c=fc;break;case 4:c=gc;break;case 16:c=hc;break;case 536870912:c=jc;break;default:c=hc}c=Gk(c,Hk.bind(null,a))}a.callbackPriority=b;a.callbackNode=c}}\nfunction Hk(a,b){Bk=-1;Ck=0;if(0!==(K&6))throw Error(p(327));var c=a.callbackNode;if(Ik()&&a.callbackNode!==c)return null;var d=uc(a,a===R?Z:0);if(0===d)return null;if(0!==(d&30)||0!==(d&a.expiredLanes)||b)b=Jk(a,d);else{b=d;var e=K;K|=2;var f=Kk();if(R!==a||Z!==b)vk=null,Hj=B()+500,Lk(a,b);do try{Mk();break}catch(h){Nk(a,h)}while(1);Qg();nk.current=f;K=e;null!==Y?b=0:(R=null,Z=0,b=T)}if(0!==b){2===b&&(e=xc(a),0!==e&&(d=e,b=Ok(a,e)));if(1===b)throw c=qk,Lk(a,0),Dk(a,d),Ek(a,B()),c;if(6===b)Dk(a,d);\nelse{e=a.current.alternate;if(0===(d&30)&&!Pk(e)&&(b=Jk(a,d),2===b&&(f=xc(a),0!==f&&(d=f,b=Ok(a,f))),1===b))throw c=qk,Lk(a,0),Dk(a,d),Ek(a,B()),c;a.finishedWork=e;a.finishedLanes=d;switch(b){case 0:case 1:throw Error(p(345));case 2:Qk(a,uk,vk);break;case 3:Dk(a,d);if((d&130023424)===d&&(b=gk+500-B(),10<b)){if(0!==uc(a,0))break;e=a.suspendedLanes;if((e&d)!==d){L();a.pingedLanes|=a.suspendedLanes&e;break}a.timeoutHandle=Ff(Qk.bind(null,a,uk,vk),b);break}Qk(a,uk,vk);break;case 4:Dk(a,d);if((d&4194240)===\nd)break;b=a.eventTimes;for(e=-1;0<d;){var g=31-oc(d);f=1<<g;g=b[g];g>e&&(e=g);d&=~f}d=e;d=B()-d;d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*mk(d/1960))-d;if(10<d){a.timeoutHandle=Ff(Qk.bind(null,a,uk,vk),d);break}Qk(a,uk,vk);break;case 5:Qk(a,uk,vk);break;default:throw Error(p(329));}}}Ek(a,B());return a.callbackNode===c?Hk.bind(null,a):null}\nfunction Ok(a,b){var c=tk;a.current.memoizedState.isDehydrated&&(Lk(a,b).flags|=256);a=Jk(a,b);2!==a&&(b=uk,uk=c,null!==b&&Gj(b));return a}function Gj(a){null===uk?uk=a:uk.push.apply(uk,a)}\nfunction Pk(a){for(var b=a;;){if(b.flags&16384){var c=b.updateQueue;if(null!==c&&(c=c.stores,null!==c))for(var d=0;d<c.length;d++){var e=c[d],f=e.getSnapshot;e=e.value;try{if(!He(f(),e))return!1}catch(g){return!1}}}c=b.child;if(b.subtreeFlags&16384&&null!==c)c.return=b,b=c;else{if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return!0;b=b.return}b.sibling.return=b.return;b=b.sibling}}return!0}\nfunction Dk(a,b){b&=~sk;b&=~rk;a.suspendedLanes|=b;a.pingedLanes&=~b;for(a=a.expirationTimes;0<b;){var c=31-oc(b),d=1<<c;a[c]=-1;b&=~d}}function Fk(a){if(0!==(K&6))throw Error(p(327));Ik();var b=uc(a,0);if(0===(b&1))return Ek(a,B()),null;var c=Jk(a,b);if(0!==a.tag&&2===c){var d=xc(a);0!==d&&(b=d,c=Ok(a,d))}if(1===c)throw c=qk,Lk(a,0),Dk(a,b),Ek(a,B()),c;if(6===c)throw Error(p(345));a.finishedWork=a.current.alternate;a.finishedLanes=b;Qk(a,uk,vk);Ek(a,B());return null}\nfunction Rk(a,b){var c=K;K|=1;try{return a(b)}finally{K=c,0===K&&(Hj=B()+500,fg&&jg())}}function Sk(a){null!==xk&&0===xk.tag&&0===(K&6)&&Ik();var b=K;K|=1;var c=pk.transition,d=C;try{if(pk.transition=null,C=1,a)return a()}finally{C=d,pk.transition=c,K=b,0===(K&6)&&jg()}}function Ij(){gj=fj.current;E(fj)}\nfunction Lk(a,b){a.finishedWork=null;a.finishedLanes=0;var c=a.timeoutHandle;-1!==c&&(a.timeoutHandle=-1,Gf(c));if(null!==Y)for(c=Y.return;null!==c;){var d=c;wg(d);switch(d.tag){case 1:d=d.type.childContextTypes;null!==d&&void 0!==d&&$f();break;case 3:Jh();E(Wf);E(H);Oh();break;case 5:Lh(d);break;case 4:Jh();break;case 13:E(M);break;case 19:E(M);break;case 10:Rg(d.type._context);break;case 22:case 23:Ij()}c=c.return}R=a;Y=a=wh(a.current,null);Z=gj=b;T=0;qk=null;sk=rk=hh=0;uk=tk=null;if(null!==Wg){for(b=\n0;b<Wg.length;b++)if(c=Wg[b],d=c.interleaved,null!==d){c.interleaved=null;var e=d.next,f=c.pending;if(null!==f){var g=f.next;f.next=e;d.next=g}c.pending=d}Wg=null}return a}\nfunction Nk(a,b){do{var c=Y;try{Qg();Ph.current=ai;if(Sh){for(var d=N.memoizedState;null!==d;){var e=d.queue;null!==e&&(e.pending=null);d=d.next}Sh=!1}Rh=0;P=O=N=null;Th=!1;Uh=0;ok.current=null;if(null===c||null===c.return){T=1;qk=b;Y=null;break}a:{var f=a,g=c.return,h=c,k=b;b=Z;h.flags|=32768;if(null!==k&&"object"===typeof k&&"function"===typeof k.then){var l=k,m=h,q=m.tag;if(0===(m.mode&1)&&(0===q||11===q||15===q)){var r=m.alternate;r?(m.updateQueue=r.updateQueue,m.memoizedState=r.memoizedState,\nm.lanes=r.lanes):(m.updateQueue=null,m.memoizedState=null)}var y=Vi(g);if(null!==y){y.flags&=-257;Wi(y,g,h,f,b);y.mode&1&&Ti(f,l,b);b=y;k=l;var n=b.updateQueue;if(null===n){var t=new Set;t.add(k);b.updateQueue=t}else n.add(k);break a}else{if(0===(b&1)){Ti(f,l,b);uj();break a}k=Error(p(426))}}else if(I&&h.mode&1){var J=Vi(g);if(null!==J){0===(J.flags&65536)&&(J.flags|=256);Wi(J,g,h,f,b);Jg(Ki(k,h));break a}}f=k=Ki(k,h);4!==T&&(T=2);null===tk?tk=[f]:tk.push(f);f=g;do{switch(f.tag){case 3:f.flags|=65536;\nb&=-b;f.lanes|=b;var x=Oi(f,k,b);fh(f,x);break a;case 1:h=k;var w=f.type,u=f.stateNode;if(0===(f.flags&128)&&("function"===typeof w.getDerivedStateFromError||null!==u&&"function"===typeof u.componentDidCatch&&(null===Si||!Si.has(u)))){f.flags|=65536;b&=-b;f.lanes|=b;var F=Ri(f,h,b);fh(f,F);break a}}f=f.return}while(null!==f)}Tk(c)}catch(na){b=na;Y===c&&null!==c&&(Y=c=c.return);continue}break}while(1)}function Kk(){var a=nk.current;nk.current=ai;return null===a?ai:a}\nfunction uj(){if(0===T||3===T||2===T)T=4;null===R||0===(hh&268435455)&&0===(rk&268435455)||Dk(R,Z)}function Jk(a,b){var c=K;K|=2;var d=Kk();if(R!==a||Z!==b)vk=null,Lk(a,b);do try{Uk();break}catch(e){Nk(a,e)}while(1);Qg();K=c;nk.current=d;if(null!==Y)throw Error(p(261));R=null;Z=0;return T}function Uk(){for(;null!==Y;)Vk(Y)}function Mk(){for(;null!==Y&&!cc();)Vk(Y)}function Vk(a){var b=Wk(a.alternate,a,gj);a.memoizedProps=a.pendingProps;null===b?Tk(a):Y=b;ok.current=null}\nfunction Tk(a){var b=a;do{var c=b.alternate;a=b.return;if(0===(b.flags&32768)){if(c=Fj(c,b,gj),null!==c){Y=c;return}}else{c=Jj(c,b);if(null!==c){c.flags&=32767;Y=c;return}if(null!==a)a.flags|=32768,a.subtreeFlags=0,a.deletions=null;else{T=6;Y=null;return}}b=b.sibling;if(null!==b){Y=b;return}Y=b=a}while(null!==b);0===T&&(T=5)}function Qk(a,b,c){var d=C,e=pk.transition;try{pk.transition=null,C=1,Xk(a,b,c,d)}finally{pk.transition=e,C=d}return null}\nfunction Xk(a,b,c,d){do Ik();while(null!==xk);if(0!==(K&6))throw Error(p(327));c=a.finishedWork;var e=a.finishedLanes;if(null===c)return null;a.finishedWork=null;a.finishedLanes=0;if(c===a.current)throw Error(p(177));a.callbackNode=null;a.callbackPriority=0;var f=c.lanes|c.childLanes;Bc(a,f);a===R&&(Y=R=null,Z=0);0===(c.subtreeFlags&2064)&&0===(c.flags&2064)||wk||(wk=!0,Gk(hc,function(){Ik();return null}));f=0!==(c.flags&15990);if(0!==(c.subtreeFlags&15990)||f){f=pk.transition;pk.transition=null;\nvar g=C;C=1;var h=K;K|=4;ok.current=null;Pj(a,c);ek(c,a);Oe(Df);dd=!!Cf;Df=Cf=null;a.current=c;ik(c,a,e);dc();K=h;C=g;pk.transition=f}else a.current=c;wk&&(wk=!1,xk=a,yk=e);f=a.pendingLanes;0===f&&(Si=null);mc(c.stateNode,d);Ek(a,B());if(null!==b)for(d=a.onRecoverableError,c=0;c<b.length;c++)e=b[c],d(e.value,{componentStack:e.stack,digest:e.digest});if(Pi)throw Pi=!1,a=Qi,Qi=null,a;0!==(yk&1)&&0!==a.tag&&Ik();f=a.pendingLanes;0!==(f&1)?a===Ak?zk++:(zk=0,Ak=a):zk=0;jg();return null}\nfunction Ik(){if(null!==xk){var a=Dc(yk),b=pk.transition,c=C;try{pk.transition=null;C=16>a?16:a;if(null===xk)var d=!1;else{a=xk;xk=null;yk=0;if(0!==(K&6))throw Error(p(331));var e=K;K|=4;for(V=a.current;null!==V;){var f=V,g=f.child;if(0!==(V.flags&16)){var h=f.deletions;if(null!==h){for(var k=0;k<h.length;k++){var l=h[k];for(V=l;null!==V;){var m=V;switch(m.tag){case 0:case 11:case 15:Qj(8,m,f)}var q=m.child;if(null!==q)q.return=m,V=q;else for(;null!==V;){m=V;var r=m.sibling,y=m.return;Tj(m);if(m===\nl){V=null;break}if(null!==r){r.return=y;V=r;break}V=y}}}var n=f.alternate;if(null!==n){var t=n.child;if(null!==t){n.child=null;do{var J=t.sibling;t.sibling=null;t=J}while(null!==t)}}V=f}}if(0!==(f.subtreeFlags&2064)&&null!==g)g.return=f,V=g;else b:for(;null!==V;){f=V;if(0!==(f.flags&2048))switch(f.tag){case 0:case 11:case 15:Qj(9,f,f.return)}var x=f.sibling;if(null!==x){x.return=f.return;V=x;break b}V=f.return}}var w=a.current;for(V=w;null!==V;){g=V;var u=g.child;if(0!==(g.subtreeFlags&2064)&&null!==\nu)u.return=g,V=u;else b:for(g=w;null!==V;){h=V;if(0!==(h.flags&2048))try{switch(h.tag){case 0:case 11:case 15:Rj(9,h)}}catch(na){W(h,h.return,na)}if(h===g){V=null;break b}var F=h.sibling;if(null!==F){F.return=h.return;V=F;break b}V=h.return}}K=e;jg();if(lc&&"function"===typeof lc.onPostCommitFiberRoot)try{lc.onPostCommitFiberRoot(kc,a)}catch(na){}d=!0}return d}finally{C=c,pk.transition=b}}return!1}function Yk(a,b,c){b=Ki(c,b);b=Oi(a,b,1);a=dh(a,b,1);b=L();null!==a&&(Ac(a,1,b),Ek(a,b))}\nfunction W(a,b,c){if(3===a.tag)Yk(a,a,c);else for(;null!==b;){if(3===b.tag){Yk(b,a,c);break}else if(1===b.tag){var d=b.stateNode;if("function"===typeof b.type.getDerivedStateFromError||"function"===typeof d.componentDidCatch&&(null===Si||!Si.has(d))){a=Ki(c,a);a=Ri(b,a,1);b=dh(b,a,1);a=L();null!==b&&(Ac(b,1,a),Ek(b,a));break}}b=b.return}}\nfunction Ui(a,b,c){var d=a.pingCache;null!==d&&d.delete(b);b=L();a.pingedLanes|=a.suspendedLanes&c;R===a&&(Z&c)===c&&(4===T||3===T&&(Z&130023424)===Z&&500>B()-gk?Lk(a,0):sk|=c);Ek(a,b)}function Zk(a,b){0===b&&(0===(a.mode&1)?b=1:(b=sc,sc<<=1,0===(sc&130023424)&&(sc=4194304)));var c=L();a=Zg(a,b);null!==a&&(Ac(a,b,c),Ek(a,c))}function vj(a){var b=a.memoizedState,c=0;null!==b&&(c=b.retryLane);Zk(a,c)}\nfunction ck(a,b){var c=0;switch(a.tag){case 13:var d=a.stateNode;var e=a.memoizedState;null!==e&&(c=e.retryLane);break;case 19:d=a.stateNode;break;default:throw Error(p(314));}null!==d&&d.delete(b);Zk(a,c)}var Wk;\nWk=function(a,b,c){if(null!==a)if(a.memoizedProps!==b.pendingProps||Wf.current)Ug=!0;else{if(0===(a.lanes&c)&&0===(b.flags&128))return Ug=!1,zj(a,b,c);Ug=0!==(a.flags&131072)?!0:!1}else Ug=!1,I&&0!==(b.flags&1048576)&&ug(b,ng,b.index);b.lanes=0;switch(b.tag){case 2:var d=b.type;jj(a,b);a=b.pendingProps;var e=Yf(b,H.current);Tg(b,c);e=Xh(null,b,d,a,e,c);var f=bi();b.flags|=1;"object"===typeof e&&null!==e&&"function"===typeof e.render&&void 0===e.$$typeof?(b.tag=1,b.memoizedState=null,b.updateQueue=\nnull,Zf(d)?(f=!0,cg(b)):f=!1,b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null,ah(b),e.updater=nh,b.stateNode=e,e._reactInternals=b,rh(b,d,a,c),b=kj(null,b,d,!0,f,c)):(b.tag=0,I&&f&&vg(b),Yi(null,b,e,c),b=b.child);return b;case 16:d=b.elementType;a:{jj(a,b);a=b.pendingProps;e=d._init;d=e(d._payload);b.type=d;e=b.tag=$k(d);a=Lg(d,a);switch(e){case 0:b=dj(null,b,d,a,c);break a;case 1:b=ij(null,b,d,a,c);break a;case 11:b=Zi(null,b,d,a,c);break a;case 14:b=aj(null,b,d,Lg(d.type,a),c);break a}throw Error(p(306,\nd,""));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),dj(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),ij(a,b,d,e,c);case 3:a:{lj(b);if(null===a)throw Error(p(387));d=b.pendingProps;f=b.memoizedState;e=f.element;bh(a,b);gh(b,d,null,c);var g=b.memoizedState;d=g.element;if(f.isDehydrated)if(f={element:d,isDehydrated:!1,cache:g.cache,pendingSuspenseBoundaries:g.pendingSuspenseBoundaries,transitions:g.transitions},b.updateQueue.baseState=\nf,b.memoizedState=f,b.flags&256){e=Ki(Error(p(423)),b);b=mj(a,b,d,c,e);break a}else if(d!==e){e=Ki(Error(p(424)),b);b=mj(a,b,d,c,e);break a}else for(yg=Lf(b.stateNode.containerInfo.firstChild),xg=b,I=!0,zg=null,c=Ch(b,null,d,c),b.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{Ig();if(d===e){b=$i(a,b,c);break a}Yi(a,b,d,c)}b=b.child}return b;case 5:return Kh(b),null===a&&Eg(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,Ef(d,e)?g=null:null!==f&&Ef(d,f)&&(b.flags|=32),\nhj(a,b),Yi(a,b,g,c),b.child;case 6:return null===a&&Eg(b),null;case 13:return pj(a,b,c);case 4:return Ih(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Bh(b,null,d,c):Yi(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),Zi(a,b,d,e,c);case 7:return Yi(a,b,b.pendingProps,c),b.child;case 8:return Yi(a,b,b.pendingProps.children,c),b.child;case 12:return Yi(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;f=b.memoizedProps;\ng=e.value;G(Mg,d._currentValue);d._currentValue=g;if(null!==f)if(He(f.value,g)){if(f.children===e.children&&!Wf.current){b=$i(a,b,c);break a}}else for(f=b.child,null!==f&&(f.return=b);null!==f;){var h=f.dependencies;if(null!==h){g=f.child;for(var k=h.firstContext;null!==k;){if(k.context===d){if(1===f.tag){k=ch(-1,c&-c);k.tag=2;var l=f.updateQueue;if(null!==l){l=l.shared;var m=l.pending;null===m?k.next=k:(k.next=m.next,m.next=k);l.pending=k}}f.lanes|=c;k=f.alternate;null!==k&&(k.lanes|=c);Sg(f.return,\nc,b);h.lanes|=c;break}k=k.next}}else if(10===f.tag)g=f.type===b.type?null:f.child;else if(18===f.tag){g=f.return;if(null===g)throw Error(p(341));g.lanes|=c;h=g.alternate;null!==h&&(h.lanes|=c);Sg(g,c,b);g=f.sibling}else g=f.child;if(null!==g)g.return=f;else for(g=f;null!==g;){if(g===b){g=null;break}f=g.sibling;if(null!==f){f.return=g.return;g=f;break}g=g.return}f=g}Yi(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,d=b.pendingProps.children,Tg(b,c),e=Vg(e),d=d(e),b.flags|=1,Yi(a,b,d,c),\nb.child;case 14:return d=b.type,e=Lg(d,b.pendingProps),e=Lg(d.type,e),aj(a,b,d,e,c);case 15:return cj(a,b,b.type,b.pendingProps,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),jj(a,b),b.tag=1,Zf(d)?(a=!0,cg(b)):a=!1,Tg(b,c),ph(b,d,e),rh(b,d,e,c),kj(null,b,d,!0,a,c);case 19:return yj(a,b,c);case 22:return ej(a,b,c)}throw Error(p(156,b.tag));};function Gk(a,b){return ac(a,b)}\nfunction al(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.subtreeFlags=this.flags=0;this.deletions=null;this.childLanes=this.lanes=0;this.alternate=null}function Bg(a,b,c,d){return new al(a,b,c,d)}function bj(a){a=a.prototype;return!(!a||!a.isReactComponent)}\nfunction $k(a){if("function"===typeof a)return bj(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Da)return 11;if(a===Ga)return 14}return 2}\nfunction wh(a,b){var c=a.alternate;null===c?(c=Bg(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.subtreeFlags=0,c.deletions=null);c.flags=a.flags&14680064;c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};\nc.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}\nfunction yh(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)bj(a)&&(g=1);else if("string"===typeof a)g=5;else a:switch(a){case ya:return Ah(c.children,e,f,b);case za:g=8;e|=8;break;case Aa:return a=Bg(12,c,b,e|2),a.elementType=Aa,a.lanes=f,a;case Ea:return a=Bg(13,c,b,e),a.elementType=Ea,a.lanes=f,a;case Fa:return a=Bg(19,c,b,e),a.elementType=Fa,a.lanes=f,a;case Ia:return qj(c,e,f,b);default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case Ba:g=10;break a;case Ca:g=9;break a;case Da:g=11;\nbreak a;case Ga:g=14;break a;case Ha:g=16;d=null;break a}throw Error(p(130,null==a?a:typeof a,""));}b=Bg(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function Ah(a,b,c,d){a=Bg(7,a,d,b);a.lanes=c;return a}function qj(a,b,c,d){a=Bg(22,a,d,b);a.elementType=Ia;a.lanes=c;a.stateNode={isHidden:!1};return a}function xh(a,b,c){a=Bg(6,a,null,b);a.lanes=c;return a}\nfunction zh(a,b,c){b=Bg(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}\nfunction bl(a,b,c,d,e){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.callbackNode=this.pendingContext=this.context=null;this.callbackPriority=0;this.eventTimes=zc(0);this.expirationTimes=zc(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=zc(0);this.identifierPrefix=d;this.onRecoverableError=e;this.mutableSourceEagerHydrationData=\nnull}function cl(a,b,c,d,e,f,g,h,k){a=new bl(a,b,c,h,k);1===b?(b=1,!0===f&&(b|=8)):b=0;f=Bg(3,null,null,b);a.current=f;f.stateNode=a;f.memoizedState={element:d,isDehydrated:c,cache:null,transitions:null,pendingSuspenseBoundaries:null};ah(f);return a}function dl(a,b,c){var d=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:wa,key:null==d?null:""+d,children:a,containerInfo:b,implementation:c}}\nfunction el(a){if(!a)return Vf;a=a._reactInternals;a:{if(Vb(a)!==a||1!==a.tag)throw Error(p(170));var b=a;do{switch(b.tag){case 3:b=b.stateNode.context;break a;case 1:if(Zf(b.type)){b=b.stateNode.__reactInternalMemoizedMergedChildContext;break a}}b=b.return}while(null!==b);throw Error(p(171));}if(1===a.tag){var c=a.type;if(Zf(c))return bg(a,c,b)}return b}\nfunction fl(a,b,c,d,e,f,g,h,k){a=cl(c,d,!0,a,e,f,g,h,k);a.context=el(null);c=a.current;d=L();e=lh(c);f=ch(d,e);f.callback=void 0!==b&&null!==b?b:null;dh(c,f,e);a.current.lanes=e;Ac(a,e,d);Ek(a,d);return a}function gl(a,b,c,d){var e=b.current,f=L(),g=lh(e);c=el(c);null===b.context?b.context=c:b.pendingContext=c;b=ch(f,g);b.payload={element:a};d=void 0===d?null:d;null!==d&&(b.callback=d);a=dh(e,b,g);null!==a&&(mh(a,e,g,f),eh(a,e,g));return g}\nfunction hl(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function il(a,b){a=a.memoizedState;if(null!==a&&null!==a.dehydrated){var c=a.retryLane;a.retryLane=0!==c&&c<b?c:b}}function jl(a,b){il(a,b);(a=a.alternate)&&il(a,b)}function kl(){return null}var ll="function"===typeof reportError?reportError:function(a){console.error(a)};function ml(a){this._internalRoot=a}\nnl.prototype.render=ml.prototype.render=function(a){var b=this._internalRoot;if(null===b)throw Error(p(409));gl(a,b,null,null)};nl.prototype.unmount=ml.prototype.unmount=function(){var a=this._internalRoot;if(null!==a){this._internalRoot=null;var b=a.containerInfo;Sk(function(){gl(null,a,null,null)});b[uf]=null}};function nl(a){this._internalRoot=a}\nnl.prototype.unstable_scheduleHydration=function(a){if(a){var b=Hc();a={blockedOn:null,target:a,priority:b};for(var c=0;c<Qc.length&&0!==b&&b<Qc[c].priority;c++);Qc.splice(c,0,a);0===c&&Vc(a)}};function ol(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType)}function pl(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType&&(8!==a.nodeType||" react-mount-point-unstable "!==a.nodeValue))}function ql(){}\nfunction rl(a,b,c,d,e){if(e){if("function"===typeof d){var f=d;d=function(){var a=hl(g);f.call(a)}}var g=fl(b,d,a,0,null,!1,!1,"",ql);a._reactRootContainer=g;a[uf]=g.current;sf(8===a.nodeType?a.parentNode:a);Sk();return g}for(;e=a.lastChild;)a.removeChild(e);if("function"===typeof d){var h=d;d=function(){var a=hl(k);h.call(a)}}var k=cl(a,0,!1,null,null,!1,!1,"",ql);a._reactRootContainer=k;a[uf]=k.current;sf(8===a.nodeType?a.parentNode:a);Sk(function(){gl(b,k,c,d)});return k}\nfunction sl(a,b,c,d,e){var f=c._reactRootContainer;if(f){var g=f;if("function"===typeof e){var h=e;e=function(){var a=hl(g);h.call(a)}}gl(b,g,a,e)}else g=rl(c,b,a,e,d);return hl(g)}Ec=function(a){switch(a.tag){case 3:var b=a.stateNode;if(b.current.memoizedState.isDehydrated){var c=tc(b.pendingLanes);0!==c&&(Cc(b,c|1),Ek(b,B()),0===(K&6)&&(Hj=B()+500,jg()))}break;case 13:Sk(function(){var b=Zg(a,1);if(null!==b){var c=L();mh(b,a,1,c)}}),jl(a,1)}};\nFc=function(a){if(13===a.tag){var b=Zg(a,134217728);if(null!==b){var c=L();mh(b,a,134217728,c)}jl(a,134217728)}};Gc=function(a){if(13===a.tag){var b=lh(a),c=Zg(a,b);if(null!==c){var d=L();mh(c,a,b,d)}jl(a,b)}};Hc=function(){return C};Ic=function(a,b){var c=C;try{return C=a,b()}finally{C=c}};\nyb=function(a,b,c){switch(b){case "input":bb(a,c);b=c.name;if("radio"===c.type&&null!=b){for(c=a;c.parentNode;)c=c.parentNode;c=c.querySelectorAll("input[name="+JSON.stringify(""+b)+\'][type="radio"]\');for(b=0;b<c.length;b++){var d=c[b];if(d!==a&&d.form===a.form){var e=Db(d);if(!e)throw Error(p(90));Wa(d);bb(d,e)}}}break;case "textarea":ib(a,c);break;case "select":b=c.value,null!=b&&fb(a,!!c.multiple,b,!1)}};Gb=Rk;Hb=Sk;\nvar tl={usingClientEntryPoint:!1,Events:[Cb,ue,Db,Eb,Fb,Rk]},ul={findFiberByHostInstance:Wc,bundleType:0,version:"18.2.0",rendererPackageName:"react-dom"};\nvar vl={bundleType:ul.bundleType,version:ul.version,rendererPackageName:ul.rendererPackageName,rendererConfig:ul.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:ua.ReactCurrentDispatcher,findHostInstanceByFiber:function(a){a=Zb(a);return null===a?null:a.stateNode},findFiberByHostInstance:ul.findFiberByHostInstance||\nkl,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0-next-9e3b772b8-20220608"};if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var wl=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!wl.isDisabled&&wl.supportsFiber)try{kc=wl.inject(vl),lc=wl}catch(a){}}exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=tl;\nexports.createPortal=function(a,b){var c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!ol(b))throw Error(p(200));return dl(a,b,null,c)};exports.createRoot=function(a,b){if(!ol(a))throw Error(p(299));var c=!1,d="",e=ll;null!==b&&void 0!==b&&(!0===b.unstable_strictMode&&(c=!0),void 0!==b.identifierPrefix&&(d=b.identifierPrefix),void 0!==b.onRecoverableError&&(e=b.onRecoverableError));b=cl(a,1,!1,null,null,c,!1,d,e);a[uf]=b.current;sf(8===a.nodeType?a.parentNode:a);return new ml(b)};\nexports.findDOMNode=function(a){if(null==a)return null;if(1===a.nodeType)return a;var b=a._reactInternals;if(void 0===b){if("function"===typeof a.render)throw Error(p(188));a=Object.keys(a).join(",");throw Error(p(268,a));}a=Zb(b);a=null===a?null:a.stateNode;return a};exports.flushSync=function(a){return Sk(a)};exports.hydrate=function(a,b,c){if(!pl(b))throw Error(p(200));return sl(null,a,b,!0,c)};\nexports.hydrateRoot=function(a,b,c){if(!ol(a))throw Error(p(405));var d=null!=c&&c.hydratedSources||null,e=!1,f="",g=ll;null!==c&&void 0!==c&&(!0===c.unstable_strictMode&&(e=!0),void 0!==c.identifierPrefix&&(f=c.identifierPrefix),void 0!==c.onRecoverableError&&(g=c.onRecoverableError));b=fl(b,null,a,1,null!=c?c:null,e,!1,f,g);a[uf]=b.current;sf(a);if(d)for(a=0;a<d.length;a++)c=d[a],e=c._getVersion,e=e(c._source),null==b.mutableSourceEagerHydrationData?b.mutableSourceEagerHydrationData=[c,e]:b.mutableSourceEagerHydrationData.push(c,\ne);return new nl(b)};exports.render=function(a,b,c){if(!pl(b))throw Error(p(200));return sl(null,a,b,!1,c)};exports.unmountComponentAtNode=function(a){if(!pl(a))throw Error(p(40));return a._reactRootContainer?(Sk(function(){sl(null,null,a,!1,function(){a._reactRootContainer=null;a[uf]=null})}),!0):!1};exports.unstable_batchedUpdates=Rk;\nexports.unstable_renderSubtreeIntoContainer=function(a,b,c,d){if(!pl(c))throw Error(p(200));if(null==a||void 0===a._reactInternals)throw Error(p(38));return sl(a,b,c,!1,d)};exports.version="18.2.0-next-9e3b772b8-20220608";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QXNELHVLQUF1Syx5Q0FBeUMsZ0JBQWdCLE1BQU0sYUFBYSxXQUFXO0FBQ3RYLEdBQUcsa0JBQWtCLGNBQWMsaUJBQWlCLDhCQUE4QiwwQkFBMEIsOEJBQThCLGFBQWEsNkJBQTZCLDRDQUE0Qyw2QkFBNkIsMkJBQTJCLFdBQVcsRUFBRSxVQUFVLCtCQUErQjtBQUM5VSwyQ0FBMkMsbUJBQW1CLDhCQUE4QiwwREFBMEQsdUJBQXVCLGVBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVhY3QtZG9tL2Nqcy9yZWFjdC1kb20ucHJvZHVjdGlvbi5taW4uanM/Y2E1ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC1kb20ucHJvZHVjdGlvbi5taW4uanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuLypcbiBNb2Rlcm5penIgMy4wLjBwcmUgKEN1c3RvbSBCdWlsZCkgfCBNSVRcbiovXG4ndXNlIHN0cmljdCc7dmFyIGFhPXJlcXVpcmUoXCJyZWFjdFwiKSxjYT1yZXF1aXJlKFwic2NoZWR1bGVyXCIpO2Z1bmN0aW9uIHAoYSl7Zm9yKHZhciBiPVwiaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL2Vycm9yLWRlY29kZXIuaHRtbD9pbnZhcmlhbnQ9XCIrYSxjPTE7Yzxhcmd1bWVudHMubGVuZ3RoO2MrKyliKz1cIiZhcmdzW109XCIrZW5jb2RlVVJJQ29tcG9uZW50KGFyZ3VtZW50c1tjXSk7cmV0dXJuXCJNaW5pZmllZCBSZWFjdCBlcnJvciAjXCIrYStcIjsgdmlzaXQgXCIrYitcIiBmb3IgdGhlIGZ1bGwgbWVzc2FnZSBvciB1c2UgdGhlIG5vbi1taW5pZmllZCBkZXYgZW52aXJvbm1lbnQgZm9yIGZ1bGwgZXJyb3JzIGFuZCBhZGRpdGlvbmFsIGhlbHBmdWwgd2FybmluZ3MuXCJ9dmFyIGRhPW5ldyBTZXQsZWE9e307ZnVuY3Rpb24gZmEoYSxiKXtoYShhLGIpO2hhKGErXCJDYXB0dXJlXCIsYil9XG5mdW5jdGlvbiBoYShhLGIpe2VhW2FdPWI7Zm9yKGE9MDthPGIubGVuZ3RoO2ErKylkYS5hZGQoYlthXSl9XG52YXIgaWE9IShcInVuZGVmaW5lZFwiPT09dHlwZW9mIHdpbmRvd3x8XCJ1bmRlZmluZWRcIj09PXR5cGVvZiB3aW5kb3cuZG9jdW1lbnR8fFwidW5kZWZpbmVkXCI9PT10eXBlb2Ygd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpLGphPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksa2E9L15bOkEtWl9hLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDLVxcdTIwMERcXHUyMDcwLVxcdTIxOEZcXHUyQzAwLVxcdTJGRUZcXHUzMDAxLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRkRdWzpBLVpfYS16XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMkZGXFx1MDM3MC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXFwtLjAtOVxcdTAwQjdcXHUwMzAwLVxcdTAzNkZcXHUyMDNGLVxcdTIwNDBdKiQvLGxhPVxue30sbWE9e307ZnVuY3Rpb24gb2EoYSl7aWYoamEuY2FsbChtYSxhKSlyZXR1cm4hMDtpZihqYS5jYWxsKGxhLGEpKXJldHVybiExO2lmKGthLnRlc3QoYSkpcmV0dXJuIG1hW2FdPSEwO2xhW2FdPSEwO3JldHVybiExfWZ1bmN0aW9uIHBhKGEsYixjLGQpe2lmKG51bGwhPT1jJiYwPT09Yy50eXBlKXJldHVybiExO3N3aXRjaCh0eXBlb2YgYil7Y2FzZSBcImZ1bmN0aW9uXCI6Y2FzZSBcInN5bWJvbFwiOnJldHVybiEwO2Nhc2UgXCJib29sZWFuXCI6aWYoZClyZXR1cm4hMTtpZihudWxsIT09YylyZXR1cm4hYy5hY2NlcHRzQm9vbGVhbnM7YT1hLnRvTG93ZXJDYXNlKCkuc2xpY2UoMCw1KTtyZXR1cm5cImRhdGEtXCIhPT1hJiZcImFyaWEtXCIhPT1hO2RlZmF1bHQ6cmV0dXJuITF9fVxuZnVuY3Rpb24gcWEoYSxiLGMsZCl7aWYobnVsbD09PWJ8fFwidW5kZWZpbmVkXCI9PT10eXBlb2YgYnx8cGEoYSxiLGMsZCkpcmV0dXJuITA7aWYoZClyZXR1cm4hMTtpZihudWxsIT09Yylzd2l0Y2goYy50eXBlKXtjYXNlIDM6cmV0dXJuIWI7Y2FzZSA0OnJldHVybiExPT09YjtjYXNlIDU6cmV0dXJuIGlzTmFOKGIpO2Nhc2UgNjpyZXR1cm4gaXNOYU4oYil8fDE+Yn1yZXR1cm4hMX1mdW5jdGlvbiB2KGEsYixjLGQsZSxmLGcpe3RoaXMuYWNjZXB0c0Jvb2xlYW5zPTI9PT1ifHwzPT09Ynx8ND09PWI7dGhpcy5hdHRyaWJ1dGVOYW1lPWQ7dGhpcy5hdHRyaWJ1dGVOYW1lc3BhY2U9ZTt0aGlzLm11c3RVc2VQcm9wZXJ0eT1jO3RoaXMucHJvcGVydHlOYW1lPWE7dGhpcy50eXBlPWI7dGhpcy5zYW5pdGl6ZVVSTD1mO3RoaXMucmVtb3ZlRW1wdHlTdHJpbmc9Z312YXIgej17fTtcblwiY2hpbGRyZW4gZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgZGVmYXVsdFZhbHVlIGRlZmF1bHRDaGVja2VkIGlubmVySFRNTCBzdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmcgc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nIHN0eWxlXCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDAsITEsYSxudWxsLCExLCExKX0pO1tbXCJhY2NlcHRDaGFyc2V0XCIsXCJhY2NlcHQtY2hhcnNldFwiXSxbXCJjbGFzc05hbWVcIixcImNsYXNzXCJdLFtcImh0bWxGb3JcIixcImZvclwiXSxbXCJodHRwRXF1aXZcIixcImh0dHAtZXF1aXZcIl1dLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YVswXTt6W2JdPW5ldyB2KGIsMSwhMSxhWzFdLG51bGwsITEsITEpfSk7W1wiY29udGVudEVkaXRhYmxlXCIsXCJkcmFnZ2FibGVcIixcInNwZWxsQ2hlY2tcIixcInZhbHVlXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDIsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7XG5bXCJhdXRvUmV2ZXJzZVwiLFwiZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFwiLFwiZm9jdXNhYmxlXCIsXCJwcmVzZXJ2ZUFscGhhXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDIsITEsYSxudWxsLCExLCExKX0pO1wiYWxsb3dGdWxsU2NyZWVuIGFzeW5jIGF1dG9Gb2N1cyBhdXRvUGxheSBjb250cm9scyBkZWZhdWx0IGRlZmVyIGRpc2FibGVkIGRpc2FibGVQaWN0dXJlSW5QaWN0dXJlIGRpc2FibGVSZW1vdGVQbGF5YmFjayBmb3JtTm9WYWxpZGF0ZSBoaWRkZW4gbG9vcCBub01vZHVsZSBub1ZhbGlkYXRlIG9wZW4gcGxheXNJbmxpbmUgcmVhZE9ubHkgcmVxdWlyZWQgcmV2ZXJzZWQgc2NvcGVkIHNlYW1sZXNzIGl0ZW1TY29wZVwiLnNwbGl0KFwiIFwiKS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3pbYV09bmV3IHYoYSwzLCExLGEudG9Mb3dlckNhc2UoKSxudWxsLCExLCExKX0pO1xuW1wiY2hlY2tlZFwiLFwibXVsdGlwbGVcIixcIm11dGVkXCIsXCJzZWxlY3RlZFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3pbYV09bmV3IHYoYSwzLCEwLGEsbnVsbCwhMSwhMSl9KTtbXCJjYXB0dXJlXCIsXCJkb3dubG9hZFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3pbYV09bmV3IHYoYSw0LCExLGEsbnVsbCwhMSwhMSl9KTtbXCJjb2xzXCIsXCJyb3dzXCIsXCJzaXplXCIsXCJzcGFuXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDYsITEsYSxudWxsLCExLCExKX0pO1tcInJvd1NwYW5cIixcInN0YXJ0XCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDUsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7dmFyIHJhPS9bXFwtOl0oW2Etel0pL2c7ZnVuY3Rpb24gc2EoYSl7cmV0dXJuIGFbMV0udG9VcHBlckNhc2UoKX1cblwiYWNjZW50LWhlaWdodCBhbGlnbm1lbnQtYmFzZWxpbmUgYXJhYmljLWZvcm0gYmFzZWxpbmUtc2hpZnQgY2FwLWhlaWdodCBjbGlwLXBhdGggY2xpcC1ydWxlIGNvbG9yLWludGVycG9sYXRpb24gY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzIGNvbG9yLXByb2ZpbGUgY29sb3ItcmVuZGVyaW5nIGRvbWluYW50LWJhc2VsaW5lIGVuYWJsZS1iYWNrZ3JvdW5kIGZpbGwtb3BhY2l0eSBmaWxsLXJ1bGUgZmxvb2QtY29sb3IgZmxvb2Qtb3BhY2l0eSBmb250LWZhbWlseSBmb250LXNpemUgZm9udC1zaXplLWFkanVzdCBmb250LXN0cmV0Y2ggZm9udC1zdHlsZSBmb250LXZhcmlhbnQgZm9udC13ZWlnaHQgZ2x5cGgtbmFtZSBnbHlwaC1vcmllbnRhdGlvbi1ob3Jpem9udGFsIGdseXBoLW9yaWVudGF0aW9uLXZlcnRpY2FsIGhvcml6LWFkdi14IGhvcml6LW9yaWdpbi14IGltYWdlLXJlbmRlcmluZyBsZXR0ZXItc3BhY2luZyBsaWdodGluZy1jb2xvciBtYXJrZXItZW5kIG1hcmtlci1taWQgbWFya2VyLXN0YXJ0IG92ZXJsaW5lLXBvc2l0aW9uIG92ZXJsaW5lLXRoaWNrbmVzcyBwYWludC1vcmRlciBwYW5vc2UtMSBwb2ludGVyLWV2ZW50cyByZW5kZXJpbmctaW50ZW50IHNoYXBlLXJlbmRlcmluZyBzdG9wLWNvbG9yIHN0b3Atb3BhY2l0eSBzdHJpa2V0aHJvdWdoLXBvc2l0aW9uIHN0cmlrZXRocm91Z2gtdGhpY2tuZXNzIHN0cm9rZS1kYXNoYXJyYXkgc3Ryb2tlLWRhc2hvZmZzZXQgc3Ryb2tlLWxpbmVjYXAgc3Ryb2tlLWxpbmVqb2luIHN0cm9rZS1taXRlcmxpbWl0IHN0cm9rZS1vcGFjaXR5IHN0cm9rZS13aWR0aCB0ZXh0LWFuY2hvciB0ZXh0LWRlY29yYXRpb24gdGV4dC1yZW5kZXJpbmcgdW5kZXJsaW5lLXBvc2l0aW9uIHVuZGVybGluZS10aGlja25lc3MgdW5pY29kZS1iaWRpIHVuaWNvZGUtcmFuZ2UgdW5pdHMtcGVyLWVtIHYtYWxwaGFiZXRpYyB2LWhhbmdpbmcgdi1pZGVvZ3JhcGhpYyB2LW1hdGhlbWF0aWNhbCB2ZWN0b3ItZWZmZWN0IHZlcnQtYWR2LXkgdmVydC1vcmlnaW4teCB2ZXJ0LW9yaWdpbi15IHdvcmQtc3BhY2luZyB3cml0aW5nLW1vZGUgeG1sbnM6eGxpbmsgeC1oZWlnaHRcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UocmEsXG5zYSk7eltiXT1uZXcgdihiLDEsITEsYSxudWxsLCExLCExKX0pO1wieGxpbms6YWN0dWF0ZSB4bGluazphcmNyb2xlIHhsaW5rOnJvbGUgeGxpbms6c2hvdyB4bGluazp0aXRsZSB4bGluazp0eXBlXCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YS5yZXBsYWNlKHJhLHNhKTt6W2JdPW5ldyB2KGIsMSwhMSxhLFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiLCExLCExKX0pO1tcInhtbDpiYXNlXCIsXCJ4bWw6bGFuZ1wiLFwieG1sOnNwYWNlXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YS5yZXBsYWNlKHJhLHNhKTt6W2JdPW5ldyB2KGIsMSwhMSxhLFwiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlXCIsITEsITEpfSk7W1widGFiSW5kZXhcIixcImNyb3NzT3JpZ2luXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDEsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7XG56LnhsaW5rSHJlZj1uZXcgdihcInhsaW5rSHJlZlwiLDEsITEsXCJ4bGluazpocmVmXCIsXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIsITAsITEpO1tcInNyY1wiLFwiaHJlZlwiLFwiYWN0aW9uXCIsXCJmb3JtQWN0aW9uXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDEsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITAsITApfSk7XG5mdW5jdGlvbiB0YShhLGIsYyxkKXt2YXIgZT16Lmhhc093blByb3BlcnR5KGIpP3pbYl06bnVsbDtpZihudWxsIT09ZT8wIT09ZS50eXBlOmR8fCEoMjxiLmxlbmd0aCl8fFwib1wiIT09YlswXSYmXCJPXCIhPT1iWzBdfHxcIm5cIiE9PWJbMV0mJlwiTlwiIT09YlsxXSlxYShiLGMsZSxkKSYmKGM9bnVsbCksZHx8bnVsbD09PWU/b2EoYikmJihudWxsPT09Yz9hLnJlbW92ZUF0dHJpYnV0ZShiKTphLnNldEF0dHJpYnV0ZShiLFwiXCIrYykpOmUubXVzdFVzZVByb3BlcnR5P2FbZS5wcm9wZXJ0eU5hbWVdPW51bGw9PT1jPzM9PT1lLnR5cGU/ITE6XCJcIjpjOihiPWUuYXR0cmlidXRlTmFtZSxkPWUuYXR0cmlidXRlTmFtZXNwYWNlLG51bGw9PT1jP2EucmVtb3ZlQXR0cmlidXRlKGIpOihlPWUudHlwZSxjPTM9PT1lfHw0PT09ZSYmITA9PT1jP1wiXCI6XCJcIitjLGQ/YS5zZXRBdHRyaWJ1dGVOUyhkLGIsYyk6YS5zZXRBdHRyaWJ1dGUoYixjKSkpfVxudmFyIHVhPWFhLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVELHZhPVN5bWJvbC5mb3IoXCJyZWFjdC5lbGVtZW50XCIpLHdhPVN5bWJvbC5mb3IoXCJyZWFjdC5wb3J0YWxcIikseWE9U3ltYm9sLmZvcihcInJlYWN0LmZyYWdtZW50XCIpLHphPVN5bWJvbC5mb3IoXCJyZWFjdC5zdHJpY3RfbW9kZVwiKSxBYT1TeW1ib2wuZm9yKFwicmVhY3QucHJvZmlsZXJcIiksQmE9U3ltYm9sLmZvcihcInJlYWN0LnByb3ZpZGVyXCIpLENhPVN5bWJvbC5mb3IoXCJyZWFjdC5jb250ZXh0XCIpLERhPVN5bWJvbC5mb3IoXCJyZWFjdC5mb3J3YXJkX3JlZlwiKSxFYT1TeW1ib2wuZm9yKFwicmVhY3Quc3VzcGVuc2VcIiksRmE9U3ltYm9sLmZvcihcInJlYWN0LnN1c3BlbnNlX2xpc3RcIiksR2E9U3ltYm9sLmZvcihcInJlYWN0Lm1lbW9cIiksSGE9U3ltYm9sLmZvcihcInJlYWN0LmxhenlcIik7U3ltYm9sLmZvcihcInJlYWN0LnNjb3BlXCIpO1N5bWJvbC5mb3IoXCJyZWFjdC5kZWJ1Z190cmFjZV9tb2RlXCIpO1xudmFyIElhPVN5bWJvbC5mb3IoXCJyZWFjdC5vZmZzY3JlZW5cIik7U3ltYm9sLmZvcihcInJlYWN0LmxlZ2FjeV9oaWRkZW5cIik7U3ltYm9sLmZvcihcInJlYWN0LmNhY2hlXCIpO1N5bWJvbC5mb3IoXCJyZWFjdC50cmFjaW5nX21hcmtlclwiKTt2YXIgSmE9U3ltYm9sLml0ZXJhdG9yO2Z1bmN0aW9uIEthKGEpe2lmKG51bGw9PT1hfHxcIm9iamVjdFwiIT09dHlwZW9mIGEpcmV0dXJuIG51bGw7YT1KYSYmYVtKYV18fGFbXCJAQGl0ZXJhdG9yXCJdO3JldHVyblwiZnVuY3Rpb25cIj09PXR5cGVvZiBhP2E6bnVsbH12YXIgQT1PYmplY3QuYXNzaWduLExhO2Z1bmN0aW9uIE1hKGEpe2lmKHZvaWQgMD09PUxhKXRyeXt0aHJvdyBFcnJvcigpO31jYXRjaChjKXt2YXIgYj1jLnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO0xhPWImJmJbMV18fFwiXCJ9cmV0dXJuXCJcXG5cIitMYSthfXZhciBOYT0hMTtcbmZ1bmN0aW9uIE9hKGEsYil7aWYoIWF8fE5hKXJldHVyblwiXCI7TmE9ITA7dmFyIGM9RXJyb3IucHJlcGFyZVN0YWNrVHJhY2U7RXJyb3IucHJlcGFyZVN0YWNrVHJhY2U9dm9pZCAwO3RyeXtpZihiKWlmKGI9ZnVuY3Rpb24oKXt0aHJvdyBFcnJvcigpO30sT2JqZWN0LmRlZmluZVByb3BlcnR5KGIucHJvdG90eXBlLFwicHJvcHNcIix7c2V0OmZ1bmN0aW9uKCl7dGhyb3cgRXJyb3IoKTt9fSksXCJvYmplY3RcIj09PXR5cGVvZiBSZWZsZWN0JiZSZWZsZWN0LmNvbnN0cnVjdCl7dHJ5e1JlZmxlY3QuY29uc3RydWN0KGIsW10pfWNhdGNoKGwpe3ZhciBkPWx9UmVmbGVjdC5jb25zdHJ1Y3QoYSxbXSxiKX1lbHNle3RyeXtiLmNhbGwoKX1jYXRjaChsKXtkPWx9YS5jYWxsKGIucHJvdG90eXBlKX1lbHNle3RyeXt0aHJvdyBFcnJvcigpO31jYXRjaChsKXtkPWx9YSgpfX1jYXRjaChsKXtpZihsJiZkJiZcInN0cmluZ1wiPT09dHlwZW9mIGwuc3RhY2spe2Zvcih2YXIgZT1sLnN0YWNrLnNwbGl0KFwiXFxuXCIpLFxuZj1kLnN0YWNrLnNwbGl0KFwiXFxuXCIpLGc9ZS5sZW5ndGgtMSxoPWYubGVuZ3RoLTE7MTw9ZyYmMDw9aCYmZVtnXSE9PWZbaF07KWgtLTtmb3IoOzE8PWcmJjA8PWg7Zy0tLGgtLSlpZihlW2ddIT09ZltoXSl7aWYoMSE9PWd8fDEhPT1oKXtkbyBpZihnLS0saC0tLDA+aHx8ZVtnXSE9PWZbaF0pe3ZhciBrPVwiXFxuXCIrZVtnXS5yZXBsYWNlKFwiIGF0IG5ldyBcIixcIiBhdCBcIik7YS5kaXNwbGF5TmFtZSYmay5pbmNsdWRlcyhcIjxhbm9ueW1vdXM+XCIpJiYoaz1rLnJlcGxhY2UoXCI8YW5vbnltb3VzPlwiLGEuZGlzcGxheU5hbWUpKTtyZXR1cm4ga313aGlsZSgxPD1nJiYwPD1oKX1icmVha319fWZpbmFsbHl7TmE9ITEsRXJyb3IucHJlcGFyZVN0YWNrVHJhY2U9Y31yZXR1cm4oYT1hP2EuZGlzcGxheU5hbWV8fGEubmFtZTpcIlwiKT9NYShhKTpcIlwifVxuZnVuY3Rpb24gUGEoYSl7c3dpdGNoKGEudGFnKXtjYXNlIDU6cmV0dXJuIE1hKGEudHlwZSk7Y2FzZSAxNjpyZXR1cm4gTWEoXCJMYXp5XCIpO2Nhc2UgMTM6cmV0dXJuIE1hKFwiU3VzcGVuc2VcIik7Y2FzZSAxOTpyZXR1cm4gTWEoXCJTdXNwZW5zZUxpc3RcIik7Y2FzZSAwOmNhc2UgMjpjYXNlIDE1OnJldHVybiBhPU9hKGEudHlwZSwhMSksYTtjYXNlIDExOnJldHVybiBhPU9hKGEudHlwZS5yZW5kZXIsITEpLGE7Y2FzZSAxOnJldHVybiBhPU9hKGEudHlwZSwhMCksYTtkZWZhdWx0OnJldHVyblwiXCJ9fVxuZnVuY3Rpb24gUWEoYSl7aWYobnVsbD09YSlyZXR1cm4gbnVsbDtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYSlyZXR1cm4gYS5kaXNwbGF5TmFtZXx8YS5uYW1lfHxudWxsO2lmKFwic3RyaW5nXCI9PT10eXBlb2YgYSlyZXR1cm4gYTtzd2l0Y2goYSl7Y2FzZSB5YTpyZXR1cm5cIkZyYWdtZW50XCI7Y2FzZSB3YTpyZXR1cm5cIlBvcnRhbFwiO2Nhc2UgQWE6cmV0dXJuXCJQcm9maWxlclwiO2Nhc2UgemE6cmV0dXJuXCJTdHJpY3RNb2RlXCI7Y2FzZSBFYTpyZXR1cm5cIlN1c3BlbnNlXCI7Y2FzZSBGYTpyZXR1cm5cIlN1c3BlbnNlTGlzdFwifWlmKFwib2JqZWN0XCI9PT10eXBlb2YgYSlzd2l0Y2goYS4kJHR5cGVvZil7Y2FzZSBDYTpyZXR1cm4oYS5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLkNvbnN1bWVyXCI7Y2FzZSBCYTpyZXR1cm4oYS5fY29udGV4dC5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLlByb3ZpZGVyXCI7Y2FzZSBEYTp2YXIgYj1hLnJlbmRlcjthPWEuZGlzcGxheU5hbWU7YXx8KGE9Yi5kaXNwbGF5TmFtZXx8XG5iLm5hbWV8fFwiXCIsYT1cIlwiIT09YT9cIkZvcndhcmRSZWYoXCIrYStcIilcIjpcIkZvcndhcmRSZWZcIik7cmV0dXJuIGE7Y2FzZSBHYTpyZXR1cm4gYj1hLmRpc3BsYXlOYW1lfHxudWxsLG51bGwhPT1iP2I6UWEoYS50eXBlKXx8XCJNZW1vXCI7Y2FzZSBIYTpiPWEuX3BheWxvYWQ7YT1hLl9pbml0O3RyeXtyZXR1cm4gUWEoYShiKSl9Y2F0Y2goYyl7fX1yZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFJhKGEpe3ZhciBiPWEudHlwZTtzd2l0Y2goYS50YWcpe2Nhc2UgMjQ6cmV0dXJuXCJDYWNoZVwiO2Nhc2UgOTpyZXR1cm4oYi5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLkNvbnN1bWVyXCI7Y2FzZSAxMDpyZXR1cm4oYi5fY29udGV4dC5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLlByb3ZpZGVyXCI7Y2FzZSAxODpyZXR1cm5cIkRlaHlkcmF0ZWRGcmFnbWVudFwiO2Nhc2UgMTE6cmV0dXJuIGE9Yi5yZW5kZXIsYT1hLmRpc3BsYXlOYW1lfHxhLm5hbWV8fFwiXCIsYi5kaXNwbGF5TmFtZXx8KFwiXCIhPT1hP1wiRm9yd2FyZFJlZihcIithK1wiKVwiOlwiRm9yd2FyZFJlZlwiKTtjYXNlIDc6cmV0dXJuXCJGcmFnbWVudFwiO2Nhc2UgNTpyZXR1cm4gYjtjYXNlIDQ6cmV0dXJuXCJQb3J0YWxcIjtjYXNlIDM6cmV0dXJuXCJSb290XCI7Y2FzZSA2OnJldHVyblwiVGV4dFwiO2Nhc2UgMTY6cmV0dXJuIFFhKGIpO2Nhc2UgODpyZXR1cm4gYj09PXphP1wiU3RyaWN0TW9kZVwiOlwiTW9kZVwiO2Nhc2UgMjI6cmV0dXJuXCJPZmZzY3JlZW5cIjtcbmNhc2UgMTI6cmV0dXJuXCJQcm9maWxlclwiO2Nhc2UgMjE6cmV0dXJuXCJTY29wZVwiO2Nhc2UgMTM6cmV0dXJuXCJTdXNwZW5zZVwiO2Nhc2UgMTk6cmV0dXJuXCJTdXNwZW5zZUxpc3RcIjtjYXNlIDI1OnJldHVyblwiVHJhY2luZ01hcmtlclwiO2Nhc2UgMTpjYXNlIDA6Y2FzZSAxNzpjYXNlIDI6Y2FzZSAxNDpjYXNlIDE1OmlmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBiKXJldHVybiBiLmRpc3BsYXlOYW1lfHxiLm5hbWV8fG51bGw7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBiKXJldHVybiBifXJldHVybiBudWxsfWZ1bmN0aW9uIFNhKGEpe3N3aXRjaCh0eXBlb2YgYSl7Y2FzZSBcImJvb2xlYW5cIjpjYXNlIFwibnVtYmVyXCI6Y2FzZSBcInN0cmluZ1wiOmNhc2UgXCJ1bmRlZmluZWRcIjpyZXR1cm4gYTtjYXNlIFwib2JqZWN0XCI6cmV0dXJuIGE7ZGVmYXVsdDpyZXR1cm5cIlwifX1cbmZ1bmN0aW9uIFRhKGEpe3ZhciBiPWEudHlwZTtyZXR1cm4oYT1hLm5vZGVOYW1lKSYmXCJpbnB1dFwiPT09YS50b0xvd2VyQ2FzZSgpJiYoXCJjaGVja2JveFwiPT09Ynx8XCJyYWRpb1wiPT09Yil9XG5mdW5jdGlvbiBVYShhKXt2YXIgYj1UYShhKT9cImNoZWNrZWRcIjpcInZhbHVlXCIsYz1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGEuY29uc3RydWN0b3IucHJvdG90eXBlLGIpLGQ9XCJcIithW2JdO2lmKCFhLmhhc093blByb3BlcnR5KGIpJiZcInVuZGVmaW5lZFwiIT09dHlwZW9mIGMmJlwiZnVuY3Rpb25cIj09PXR5cGVvZiBjLmdldCYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGMuc2V0KXt2YXIgZT1jLmdldCxmPWMuc2V0O09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIse2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gZS5jYWxsKHRoaXMpfSxzZXQ6ZnVuY3Rpb24oYSl7ZD1cIlwiK2E7Zi5jYWxsKHRoaXMsYSl9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7ZW51bWVyYWJsZTpjLmVudW1lcmFibGV9KTtyZXR1cm57Z2V0VmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm4gZH0sc2V0VmFsdWU6ZnVuY3Rpb24oYSl7ZD1cIlwiK2F9LHN0b3BUcmFja2luZzpmdW5jdGlvbigpe2EuX3ZhbHVlVHJhY2tlcj1cbm51bGw7ZGVsZXRlIGFbYl19fX19ZnVuY3Rpb24gVmEoYSl7YS5fdmFsdWVUcmFja2VyfHwoYS5fdmFsdWVUcmFja2VyPVVhKGEpKX1mdW5jdGlvbiBXYShhKXtpZighYSlyZXR1cm4hMTt2YXIgYj1hLl92YWx1ZVRyYWNrZXI7aWYoIWIpcmV0dXJuITA7dmFyIGM9Yi5nZXRWYWx1ZSgpO3ZhciBkPVwiXCI7YSYmKGQ9VGEoYSk/YS5jaGVja2VkP1widHJ1ZVwiOlwiZmFsc2VcIjphLnZhbHVlKTthPWQ7cmV0dXJuIGEhPT1jPyhiLnNldFZhbHVlKGEpLCEwKTohMX1mdW5jdGlvbiBYYShhKXthPWF8fChcInVuZGVmaW5lZFwiIT09dHlwZW9mIGRvY3VtZW50P2RvY3VtZW50OnZvaWQgMCk7aWYoXCJ1bmRlZmluZWRcIj09PXR5cGVvZiBhKXJldHVybiBudWxsO3RyeXtyZXR1cm4gYS5hY3RpdmVFbGVtZW50fHxhLmJvZHl9Y2F0Y2goYil7cmV0dXJuIGEuYm9keX19XG5mdW5jdGlvbiBZYShhLGIpe3ZhciBjPWIuY2hlY2tlZDtyZXR1cm4gQSh7fSxiLHtkZWZhdWx0Q2hlY2tlZDp2b2lkIDAsZGVmYXVsdFZhbHVlOnZvaWQgMCx2YWx1ZTp2b2lkIDAsY2hlY2tlZDpudWxsIT1jP2M6YS5fd3JhcHBlclN0YXRlLmluaXRpYWxDaGVja2VkfSl9ZnVuY3Rpb24gWmEoYSxiKXt2YXIgYz1udWxsPT1iLmRlZmF1bHRWYWx1ZT9cIlwiOmIuZGVmYXVsdFZhbHVlLGQ9bnVsbCE9Yi5jaGVja2VkP2IuY2hlY2tlZDpiLmRlZmF1bHRDaGVja2VkO2M9U2EobnVsbCE9Yi52YWx1ZT9iLnZhbHVlOmMpO2EuX3dyYXBwZXJTdGF0ZT17aW5pdGlhbENoZWNrZWQ6ZCxpbml0aWFsVmFsdWU6Yyxjb250cm9sbGVkOlwiY2hlY2tib3hcIj09PWIudHlwZXx8XCJyYWRpb1wiPT09Yi50eXBlP251bGwhPWIuY2hlY2tlZDpudWxsIT1iLnZhbHVlfX1mdW5jdGlvbiBhYihhLGIpe2I9Yi5jaGVja2VkO251bGwhPWImJnRhKGEsXCJjaGVja2VkXCIsYiwhMSl9XG5mdW5jdGlvbiBiYihhLGIpe2FiKGEsYik7dmFyIGM9U2EoYi52YWx1ZSksZD1iLnR5cGU7aWYobnVsbCE9YylpZihcIm51bWJlclwiPT09ZCl7aWYoMD09PWMmJlwiXCI9PT1hLnZhbHVlfHxhLnZhbHVlIT1jKWEudmFsdWU9XCJcIitjfWVsc2UgYS52YWx1ZSE9PVwiXCIrYyYmKGEudmFsdWU9XCJcIitjKTtlbHNlIGlmKFwic3VibWl0XCI9PT1kfHxcInJlc2V0XCI9PT1kKXthLnJlbW92ZUF0dHJpYnV0ZShcInZhbHVlXCIpO3JldHVybn1iLmhhc093blByb3BlcnR5KFwidmFsdWVcIik/Y2IoYSxiLnR5cGUsYyk6Yi5oYXNPd25Qcm9wZXJ0eShcImRlZmF1bHRWYWx1ZVwiKSYmY2IoYSxiLnR5cGUsU2EoYi5kZWZhdWx0VmFsdWUpKTtudWxsPT1iLmNoZWNrZWQmJm51bGwhPWIuZGVmYXVsdENoZWNrZWQmJihhLmRlZmF1bHRDaGVja2VkPSEhYi5kZWZhdWx0Q2hlY2tlZCl9XG5mdW5jdGlvbiBkYihhLGIsYyl7aWYoYi5oYXNPd25Qcm9wZXJ0eShcInZhbHVlXCIpfHxiLmhhc093blByb3BlcnR5KFwiZGVmYXVsdFZhbHVlXCIpKXt2YXIgZD1iLnR5cGU7aWYoIShcInN1Ym1pdFwiIT09ZCYmXCJyZXNldFwiIT09ZHx8dm9pZCAwIT09Yi52YWx1ZSYmbnVsbCE9PWIudmFsdWUpKXJldHVybjtiPVwiXCIrYS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZTtjfHxiPT09YS52YWx1ZXx8KGEudmFsdWU9Yik7YS5kZWZhdWx0VmFsdWU9Yn1jPWEubmFtZTtcIlwiIT09YyYmKGEubmFtZT1cIlwiKTthLmRlZmF1bHRDaGVja2VkPSEhYS5fd3JhcHBlclN0YXRlLmluaXRpYWxDaGVja2VkO1wiXCIhPT1jJiYoYS5uYW1lPWMpfVxuZnVuY3Rpb24gY2IoYSxiLGMpe2lmKFwibnVtYmVyXCIhPT1ifHxYYShhLm93bmVyRG9jdW1lbnQpIT09YSludWxsPT1jP2EuZGVmYXVsdFZhbHVlPVwiXCIrYS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZTphLmRlZmF1bHRWYWx1ZSE9PVwiXCIrYyYmKGEuZGVmYXVsdFZhbHVlPVwiXCIrYyl9dmFyIGViPUFycmF5LmlzQXJyYXk7XG5mdW5jdGlvbiBmYihhLGIsYyxkKXthPWEub3B0aW9ucztpZihiKXtiPXt9O2Zvcih2YXIgZT0wO2U8Yy5sZW5ndGg7ZSsrKWJbXCIkXCIrY1tlXV09ITA7Zm9yKGM9MDtjPGEubGVuZ3RoO2MrKyllPWIuaGFzT3duUHJvcGVydHkoXCIkXCIrYVtjXS52YWx1ZSksYVtjXS5zZWxlY3RlZCE9PWUmJihhW2NdLnNlbGVjdGVkPWUpLGUmJmQmJihhW2NdLmRlZmF1bHRTZWxlY3RlZD0hMCl9ZWxzZXtjPVwiXCIrU2EoYyk7Yj1udWxsO2ZvcihlPTA7ZTxhLmxlbmd0aDtlKyspe2lmKGFbZV0udmFsdWU9PT1jKXthW2VdLnNlbGVjdGVkPSEwO2QmJihhW2VdLmRlZmF1bHRTZWxlY3RlZD0hMCk7cmV0dXJufW51bGwhPT1ifHxhW2VdLmRpc2FibGVkfHwoYj1hW2VdKX1udWxsIT09YiYmKGIuc2VsZWN0ZWQ9ITApfX1cbmZ1bmN0aW9uIGdiKGEsYil7aWYobnVsbCE9Yi5kYW5nZXJvdXNseVNldElubmVySFRNTCl0aHJvdyBFcnJvcihwKDkxKSk7cmV0dXJuIEEoe30sYix7dmFsdWU6dm9pZCAwLGRlZmF1bHRWYWx1ZTp2b2lkIDAsY2hpbGRyZW46XCJcIithLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlfSl9ZnVuY3Rpb24gaGIoYSxiKXt2YXIgYz1iLnZhbHVlO2lmKG51bGw9PWMpe2M9Yi5jaGlsZHJlbjtiPWIuZGVmYXVsdFZhbHVlO2lmKG51bGwhPWMpe2lmKG51bGwhPWIpdGhyb3cgRXJyb3IocCg5MikpO2lmKGViKGMpKXtpZigxPGMubGVuZ3RoKXRocm93IEVycm9yKHAoOTMpKTtjPWNbMF19Yj1jfW51bGw9PWImJihiPVwiXCIpO2M9Yn1hLl93cmFwcGVyU3RhdGU9e2luaXRpYWxWYWx1ZTpTYShjKX19XG5mdW5jdGlvbiBpYihhLGIpe3ZhciBjPVNhKGIudmFsdWUpLGQ9U2EoYi5kZWZhdWx0VmFsdWUpO251bGwhPWMmJihjPVwiXCIrYyxjIT09YS52YWx1ZSYmKGEudmFsdWU9YyksbnVsbD09Yi5kZWZhdWx0VmFsdWUmJmEuZGVmYXVsdFZhbHVlIT09YyYmKGEuZGVmYXVsdFZhbHVlPWMpKTtudWxsIT1kJiYoYS5kZWZhdWx0VmFsdWU9XCJcIitkKX1mdW5jdGlvbiBqYihhKXt2YXIgYj1hLnRleHRDb250ZW50O2I9PT1hLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlJiZcIlwiIT09YiYmbnVsbCE9PWImJihhLnZhbHVlPWIpfWZ1bmN0aW9uIGtiKGEpe3N3aXRjaChhKXtjYXNlIFwic3ZnXCI6cmV0dXJuXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiO2Nhc2UgXCJtYXRoXCI6cmV0dXJuXCJodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MXCI7ZGVmYXVsdDpyZXR1cm5cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIn19XG5mdW5jdGlvbiBsYihhLGIpe3JldHVybiBudWxsPT1hfHxcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj09PWE/a2IoYik6XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPT09YSYmXCJmb3JlaWduT2JqZWN0XCI9PT1iP1wiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiOmF9XG52YXIgbWIsbmI9ZnVuY3Rpb24oYSl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBNU0FwcCYmTVNBcHAuZXhlY1Vuc2FmZUxvY2FsRnVuY3Rpb24/ZnVuY3Rpb24oYixjLGQsZSl7TVNBcHAuZXhlY1Vuc2FmZUxvY2FsRnVuY3Rpb24oZnVuY3Rpb24oKXtyZXR1cm4gYShiLGMsZCxlKX0pfTphfShmdW5jdGlvbihhLGIpe2lmKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiE9PWEubmFtZXNwYWNlVVJJfHxcImlubmVySFRNTFwiaW4gYSlhLmlubmVySFRNTD1iO2Vsc2V7bWI9bWJ8fGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7bWIuaW5uZXJIVE1MPVwiPHN2Zz5cIitiLnZhbHVlT2YoKS50b1N0cmluZygpK1wiPC9zdmc+XCI7Zm9yKGI9bWIuZmlyc3RDaGlsZDthLmZpcnN0Q2hpbGQ7KWEucmVtb3ZlQ2hpbGQoYS5maXJzdENoaWxkKTtmb3IoO2IuZmlyc3RDaGlsZDspYS5hcHBlbmRDaGlsZChiLmZpcnN0Q2hpbGQpfX0pO1xuZnVuY3Rpb24gb2IoYSxiKXtpZihiKXt2YXIgYz1hLmZpcnN0Q2hpbGQ7aWYoYyYmYz09PWEubGFzdENoaWxkJiYzPT09Yy5ub2RlVHlwZSl7Yy5ub2RlVmFsdWU9YjtyZXR1cm59fWEudGV4dENvbnRlbnQ9Yn1cbnZhciBwYj17YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsYXNwZWN0UmF0aW86ITAsYm9yZGVySW1hZ2VPdXRzZXQ6ITAsYm9yZGVySW1hZ2VTbGljZTohMCxib3JkZXJJbWFnZVdpZHRoOiEwLGJveEZsZXg6ITAsYm94RmxleEdyb3VwOiEwLGJveE9yZGluYWxHcm91cDohMCxjb2x1bW5Db3VudDohMCxjb2x1bW5zOiEwLGZsZXg6ITAsZmxleEdyb3c6ITAsZmxleFBvc2l0aXZlOiEwLGZsZXhTaHJpbms6ITAsZmxleE5lZ2F0aXZlOiEwLGZsZXhPcmRlcjohMCxncmlkQXJlYTohMCxncmlkUm93OiEwLGdyaWRSb3dFbmQ6ITAsZ3JpZFJvd1NwYW46ITAsZ3JpZFJvd1N0YXJ0OiEwLGdyaWRDb2x1bW46ITAsZ3JpZENvbHVtbkVuZDohMCxncmlkQ29sdW1uU3BhbjohMCxncmlkQ29sdW1uU3RhcnQ6ITAsZm9udFdlaWdodDohMCxsaW5lQ2xhbXA6ITAsbGluZUhlaWdodDohMCxvcGFjaXR5OiEwLG9yZGVyOiEwLG9ycGhhbnM6ITAsdGFiU2l6ZTohMCx3aWRvd3M6ITAsekluZGV4OiEwLFxuem9vbTohMCxmaWxsT3BhY2l0eTohMCxmbG9vZE9wYWNpdHk6ITAsc3RvcE9wYWNpdHk6ITAsc3Ryb2tlRGFzaGFycmF5OiEwLHN0cm9rZURhc2hvZmZzZXQ6ITAsc3Ryb2tlTWl0ZXJsaW1pdDohMCxzdHJva2VPcGFjaXR5OiEwLHN0cm9rZVdpZHRoOiEwfSxxYj1bXCJXZWJraXRcIixcIm1zXCIsXCJNb3pcIixcIk9cIl07T2JqZWN0LmtleXMocGIpLmZvckVhY2goZnVuY3Rpb24oYSl7cWIuZm9yRWFjaChmdW5jdGlvbihiKXtiPWIrYS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSthLnN1YnN0cmluZygxKTtwYltiXT1wYlthXX0pfSk7ZnVuY3Rpb24gcmIoYSxiLGMpe3JldHVybiBudWxsPT1ifHxcImJvb2xlYW5cIj09PXR5cGVvZiBifHxcIlwiPT09Yj9cIlwiOmN8fFwibnVtYmVyXCIhPT10eXBlb2YgYnx8MD09PWJ8fHBiLmhhc093blByb3BlcnR5KGEpJiZwYlthXT8oXCJcIitiKS50cmltKCk6YitcInB4XCJ9XG5mdW5jdGlvbiBzYihhLGIpe2E9YS5zdHlsZTtmb3IodmFyIGMgaW4gYilpZihiLmhhc093blByb3BlcnR5KGMpKXt2YXIgZD0wPT09Yy5pbmRleE9mKFwiLS1cIiksZT1yYihjLGJbY10sZCk7XCJmbG9hdFwiPT09YyYmKGM9XCJjc3NGbG9hdFwiKTtkP2Euc2V0UHJvcGVydHkoYyxlKTphW2NdPWV9fXZhciB0Yj1BKHttZW51aXRlbTohMH0se2FyZWE6ITAsYmFzZTohMCxicjohMCxjb2w6ITAsZW1iZWQ6ITAsaHI6ITAsaW1nOiEwLGlucHV0OiEwLGtleWdlbjohMCxsaW5rOiEwLG1ldGE6ITAscGFyYW06ITAsc291cmNlOiEwLHRyYWNrOiEwLHdicjohMH0pO1xuZnVuY3Rpb24gdWIoYSxiKXtpZihiKXtpZih0YlthXSYmKG51bGwhPWIuY2hpbGRyZW58fG51bGwhPWIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwpKXRocm93IEVycm9yKHAoMTM3LGEpKTtpZihudWxsIT1iLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKXtpZihudWxsIT1iLmNoaWxkcmVuKXRocm93IEVycm9yKHAoNjApKTtpZihcIm9iamVjdFwiIT09dHlwZW9mIGIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUx8fCEoXCJfX2h0bWxcImluIGIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwpKXRocm93IEVycm9yKHAoNjEpKTt9aWYobnVsbCE9Yi5zdHlsZSYmXCJvYmplY3RcIiE9PXR5cGVvZiBiLnN0eWxlKXRocm93IEVycm9yKHAoNjIpKTt9fVxuZnVuY3Rpb24gdmIoYSxiKXtpZigtMT09PWEuaW5kZXhPZihcIi1cIikpcmV0dXJuXCJzdHJpbmdcIj09PXR5cGVvZiBiLmlzO3N3aXRjaChhKXtjYXNlIFwiYW5ub3RhdGlvbi14bWxcIjpjYXNlIFwiY29sb3ItcHJvZmlsZVwiOmNhc2UgXCJmb250LWZhY2VcIjpjYXNlIFwiZm9udC1mYWNlLXNyY1wiOmNhc2UgXCJmb250LWZhY2UtdXJpXCI6Y2FzZSBcImZvbnQtZmFjZS1mb3JtYXRcIjpjYXNlIFwiZm9udC1mYWNlLW5hbWVcIjpjYXNlIFwibWlzc2luZy1nbHlwaFwiOnJldHVybiExO2RlZmF1bHQ6cmV0dXJuITB9fXZhciB3Yj1udWxsO2Z1bmN0aW9uIHhiKGEpe2E9YS50YXJnZXR8fGEuc3JjRWxlbWVudHx8d2luZG93O2EuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQmJihhPWEuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQpO3JldHVybiAzPT09YS5ub2RlVHlwZT9hLnBhcmVudE5vZGU6YX12YXIgeWI9bnVsbCx6Yj1udWxsLEFiPW51bGw7XG5mdW5jdGlvbiBCYihhKXtpZihhPUNiKGEpKXtpZihcImZ1bmN0aW9uXCIhPT10eXBlb2YgeWIpdGhyb3cgRXJyb3IocCgyODApKTt2YXIgYj1hLnN0YXRlTm9kZTtiJiYoYj1EYihiKSx5YihhLnN0YXRlTm9kZSxhLnR5cGUsYikpfX1mdW5jdGlvbiBFYihhKXt6Yj9BYj9BYi5wdXNoKGEpOkFiPVthXTp6Yj1hfWZ1bmN0aW9uIEZiKCl7aWYoemIpe3ZhciBhPXpiLGI9QWI7QWI9emI9bnVsbDtCYihhKTtpZihiKWZvcihhPTA7YTxiLmxlbmd0aDthKyspQmIoYlthXSl9fWZ1bmN0aW9uIEdiKGEsYil7cmV0dXJuIGEoYil9ZnVuY3Rpb24gSGIoKXt9dmFyIEliPSExO2Z1bmN0aW9uIEpiKGEsYixjKXtpZihJYilyZXR1cm4gYShiLGMpO0liPSEwO3RyeXtyZXR1cm4gR2IoYSxiLGMpfWZpbmFsbHl7aWYoSWI9ITEsbnVsbCE9PXpifHxudWxsIT09QWIpSGIoKSxGYigpfX1cbmZ1bmN0aW9uIEtiKGEsYil7dmFyIGM9YS5zdGF0ZU5vZGU7aWYobnVsbD09PWMpcmV0dXJuIG51bGw7dmFyIGQ9RGIoYyk7aWYobnVsbD09PWQpcmV0dXJuIG51bGw7Yz1kW2JdO2E6c3dpdGNoKGIpe2Nhc2UgXCJvbkNsaWNrXCI6Y2FzZSBcIm9uQ2xpY2tDYXB0dXJlXCI6Y2FzZSBcIm9uRG91YmxlQ2xpY2tcIjpjYXNlIFwib25Eb3VibGVDbGlja0NhcHR1cmVcIjpjYXNlIFwib25Nb3VzZURvd25cIjpjYXNlIFwib25Nb3VzZURvd25DYXB0dXJlXCI6Y2FzZSBcIm9uTW91c2VNb3ZlXCI6Y2FzZSBcIm9uTW91c2VNb3ZlQ2FwdHVyZVwiOmNhc2UgXCJvbk1vdXNlVXBcIjpjYXNlIFwib25Nb3VzZVVwQ2FwdHVyZVwiOmNhc2UgXCJvbk1vdXNlRW50ZXJcIjooZD0hZC5kaXNhYmxlZCl8fChhPWEudHlwZSxkPSEoXCJidXR0b25cIj09PWF8fFwiaW5wdXRcIj09PWF8fFwic2VsZWN0XCI9PT1hfHxcInRleHRhcmVhXCI9PT1hKSk7YT0hZDticmVhayBhO2RlZmF1bHQ6YT0hMX1pZihhKXJldHVybiBudWxsO2lmKGMmJlwiZnVuY3Rpb25cIiE9PVxudHlwZW9mIGMpdGhyb3cgRXJyb3IocCgyMzEsYix0eXBlb2YgYykpO3JldHVybiBjfXZhciBMYj0hMTtpZihpYSl0cnl7dmFyIE1iPXt9O09iamVjdC5kZWZpbmVQcm9wZXJ0eShNYixcInBhc3NpdmVcIix7Z2V0OmZ1bmN0aW9uKCl7TGI9ITB9fSk7d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJ0ZXN0XCIsTWIsTWIpO3dpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwidGVzdFwiLE1iLE1iKX1jYXRjaChhKXtMYj0hMX1mdW5jdGlvbiBOYihhLGIsYyxkLGUsZixnLGgsayl7dmFyIGw9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDMpO3RyeXtiLmFwcGx5KGMsbCl9Y2F0Y2gobSl7dGhpcy5vbkVycm9yKG0pfX12YXIgT2I9ITEsUGI9bnVsbCxRYj0hMSxSYj1udWxsLFNiPXtvbkVycm9yOmZ1bmN0aW9uKGEpe09iPSEwO1BiPWF9fTtmdW5jdGlvbiBUYihhLGIsYyxkLGUsZixnLGgsayl7T2I9ITE7UGI9bnVsbDtOYi5hcHBseShTYixhcmd1bWVudHMpfVxuZnVuY3Rpb24gVWIoYSxiLGMsZCxlLGYsZyxoLGspe1RiLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtpZihPYil7aWYoT2Ipe3ZhciBsPVBiO09iPSExO1BiPW51bGx9ZWxzZSB0aHJvdyBFcnJvcihwKDE5OCkpO1FifHwoUWI9ITAsUmI9bCl9fWZ1bmN0aW9uIFZiKGEpe3ZhciBiPWEsYz1hO2lmKGEuYWx0ZXJuYXRlKWZvcig7Yi5yZXR1cm47KWI9Yi5yZXR1cm47ZWxzZXthPWI7ZG8gYj1hLDAhPT0oYi5mbGFncyY0MDk4KSYmKGM9Yi5yZXR1cm4pLGE9Yi5yZXR1cm47d2hpbGUoYSl9cmV0dXJuIDM9PT1iLnRhZz9jOm51bGx9ZnVuY3Rpb24gV2IoYSl7aWYoMTM9PT1hLnRhZyl7dmFyIGI9YS5tZW1vaXplZFN0YXRlO251bGw9PT1iJiYoYT1hLmFsdGVybmF0ZSxudWxsIT09YSYmKGI9YS5tZW1vaXplZFN0YXRlKSk7aWYobnVsbCE9PWIpcmV0dXJuIGIuZGVoeWRyYXRlZH1yZXR1cm4gbnVsbH1mdW5jdGlvbiBYYihhKXtpZihWYihhKSE9PWEpdGhyb3cgRXJyb3IocCgxODgpKTt9XG5mdW5jdGlvbiBZYihhKXt2YXIgYj1hLmFsdGVybmF0ZTtpZighYil7Yj1WYihhKTtpZihudWxsPT09Yil0aHJvdyBFcnJvcihwKDE4OCkpO3JldHVybiBiIT09YT9udWxsOmF9Zm9yKHZhciBjPWEsZD1iOzspe3ZhciBlPWMucmV0dXJuO2lmKG51bGw9PT1lKWJyZWFrO3ZhciBmPWUuYWx0ZXJuYXRlO2lmKG51bGw9PT1mKXtkPWUucmV0dXJuO2lmKG51bGwhPT1kKXtjPWQ7Y29udGludWV9YnJlYWt9aWYoZS5jaGlsZD09PWYuY2hpbGQpe2ZvcihmPWUuY2hpbGQ7Zjspe2lmKGY9PT1jKXJldHVybiBYYihlKSxhO2lmKGY9PT1kKXJldHVybiBYYihlKSxiO2Y9Zi5zaWJsaW5nfXRocm93IEVycm9yKHAoMTg4KSk7fWlmKGMucmV0dXJuIT09ZC5yZXR1cm4pYz1lLGQ9ZjtlbHNle2Zvcih2YXIgZz0hMSxoPWUuY2hpbGQ7aDspe2lmKGg9PT1jKXtnPSEwO2M9ZTtkPWY7YnJlYWt9aWYoaD09PWQpe2c9ITA7ZD1lO2M9ZjticmVha31oPWguc2libGluZ31pZighZyl7Zm9yKGg9Zi5jaGlsZDtoOyl7aWYoaD09PVxuYyl7Zz0hMDtjPWY7ZD1lO2JyZWFrfWlmKGg9PT1kKXtnPSEwO2Q9ZjtjPWU7YnJlYWt9aD1oLnNpYmxpbmd9aWYoIWcpdGhyb3cgRXJyb3IocCgxODkpKTt9fWlmKGMuYWx0ZXJuYXRlIT09ZCl0aHJvdyBFcnJvcihwKDE5MCkpO31pZigzIT09Yy50YWcpdGhyb3cgRXJyb3IocCgxODgpKTtyZXR1cm4gYy5zdGF0ZU5vZGUuY3VycmVudD09PWM/YTpifWZ1bmN0aW9uIFpiKGEpe2E9WWIoYSk7cmV0dXJuIG51bGwhPT1hPyRiKGEpOm51bGx9ZnVuY3Rpb24gJGIoYSl7aWYoNT09PWEudGFnfHw2PT09YS50YWcpcmV0dXJuIGE7Zm9yKGE9YS5jaGlsZDtudWxsIT09YTspe3ZhciBiPSRiKGEpO2lmKG51bGwhPT1iKXJldHVybiBiO2E9YS5zaWJsaW5nfXJldHVybiBudWxsfVxudmFyIGFjPWNhLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2ssYmM9Y2EudW5zdGFibGVfY2FuY2VsQ2FsbGJhY2ssY2M9Y2EudW5zdGFibGVfc2hvdWxkWWllbGQsZGM9Y2EudW5zdGFibGVfcmVxdWVzdFBhaW50LEI9Y2EudW5zdGFibGVfbm93LGVjPWNhLnVuc3RhYmxlX2dldEN1cnJlbnRQcmlvcml0eUxldmVsLGZjPWNhLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5LGdjPWNhLnVuc3RhYmxlX1VzZXJCbG9ja2luZ1ByaW9yaXR5LGhjPWNhLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5LGljPWNhLnVuc3RhYmxlX0xvd1ByaW9yaXR5LGpjPWNhLnVuc3RhYmxlX0lkbGVQcmlvcml0eSxrYz1udWxsLGxjPW51bGw7ZnVuY3Rpb24gbWMoYSl7aWYobGMmJlwiZnVuY3Rpb25cIj09PXR5cGVvZiBsYy5vbkNvbW1pdEZpYmVyUm9vdCl0cnl7bGMub25Db21taXRGaWJlclJvb3Qoa2MsYSx2b2lkIDAsMTI4PT09KGEuY3VycmVudC5mbGFncyYxMjgpKX1jYXRjaChiKXt9fVxudmFyIG9jPU1hdGguY2x6MzI/TWF0aC5jbHozMjpuYyxwYz1NYXRoLmxvZyxxYz1NYXRoLkxOMjtmdW5jdGlvbiBuYyhhKXthPj4+PTA7cmV0dXJuIDA9PT1hPzMyOjMxLShwYyhhKS9xY3wwKXwwfXZhciByYz02NCxzYz00MTk0MzA0O1xuZnVuY3Rpb24gdGMoYSl7c3dpdGNoKGEmLWEpe2Nhc2UgMTpyZXR1cm4gMTtjYXNlIDI6cmV0dXJuIDI7Y2FzZSA0OnJldHVybiA0O2Nhc2UgODpyZXR1cm4gODtjYXNlIDE2OnJldHVybiAxNjtjYXNlIDMyOnJldHVybiAzMjtjYXNlIDY0OmNhc2UgMTI4OmNhc2UgMjU2OmNhc2UgNTEyOmNhc2UgMTAyNDpjYXNlIDIwNDg6Y2FzZSA0MDk2OmNhc2UgODE5MjpjYXNlIDE2Mzg0OmNhc2UgMzI3Njg6Y2FzZSA2NTUzNjpjYXNlIDEzMTA3MjpjYXNlIDI2MjE0NDpjYXNlIDUyNDI4ODpjYXNlIDEwNDg1NzY6Y2FzZSAyMDk3MTUyOnJldHVybiBhJjQxOTQyNDA7Y2FzZSA0MTk0MzA0OmNhc2UgODM4ODYwODpjYXNlIDE2Nzc3MjE2OmNhc2UgMzM1NTQ0MzI6Y2FzZSA2NzEwODg2NDpyZXR1cm4gYSYxMzAwMjM0MjQ7Y2FzZSAxMzQyMTc3Mjg6cmV0dXJuIDEzNDIxNzcyODtjYXNlIDI2ODQzNTQ1NjpyZXR1cm4gMjY4NDM1NDU2O2Nhc2UgNTM2ODcwOTEyOnJldHVybiA1MzY4NzA5MTI7Y2FzZSAxMDczNzQxODI0OnJldHVybiAxMDczNzQxODI0O1xuZGVmYXVsdDpyZXR1cm4gYX19ZnVuY3Rpb24gdWMoYSxiKXt2YXIgYz1hLnBlbmRpbmdMYW5lcztpZigwPT09YylyZXR1cm4gMDt2YXIgZD0wLGU9YS5zdXNwZW5kZWRMYW5lcyxmPWEucGluZ2VkTGFuZXMsZz1jJjI2ODQzNTQ1NTtpZigwIT09Zyl7dmFyIGg9ZyZ+ZTswIT09aD9kPXRjKGgpOihmJj1nLDAhPT1mJiYoZD10YyhmKSkpfWVsc2UgZz1jJn5lLDAhPT1nP2Q9dGMoZyk6MCE9PWYmJihkPXRjKGYpKTtpZigwPT09ZClyZXR1cm4gMDtpZigwIT09YiYmYiE9PWQmJjA9PT0oYiZlKSYmKGU9ZCYtZCxmPWImLWIsZT49Znx8MTY9PT1lJiYwIT09KGYmNDE5NDI0MCkpKXJldHVybiBiOzAhPT0oZCY0KSYmKGR8PWMmMTYpO2I9YS5lbnRhbmdsZWRMYW5lcztpZigwIT09Yilmb3IoYT1hLmVudGFuZ2xlbWVudHMsYiY9ZDswPGI7KWM9MzEtb2MoYiksZT0xPDxjLGR8PWFbY10sYiY9fmU7cmV0dXJuIGR9XG5mdW5jdGlvbiB2YyhhLGIpe3N3aXRjaChhKXtjYXNlIDE6Y2FzZSAyOmNhc2UgNDpyZXR1cm4gYisyNTA7Y2FzZSA4OmNhc2UgMTY6Y2FzZSAzMjpjYXNlIDY0OmNhc2UgMTI4OmNhc2UgMjU2OmNhc2UgNTEyOmNhc2UgMTAyNDpjYXNlIDIwNDg6Y2FzZSA0MDk2OmNhc2UgODE5MjpjYXNlIDE2Mzg0OmNhc2UgMzI3Njg6Y2FzZSA2NTUzNjpjYXNlIDEzMTA3MjpjYXNlIDI2MjE0NDpjYXNlIDUyNDI4ODpjYXNlIDEwNDg1NzY6Y2FzZSAyMDk3MTUyOnJldHVybiBiKzVFMztjYXNlIDQxOTQzMDQ6Y2FzZSA4Mzg4NjA4OmNhc2UgMTY3NzcyMTY6Y2FzZSAzMzU1NDQzMjpjYXNlIDY3MTA4ODY0OnJldHVybi0xO2Nhc2UgMTM0MjE3NzI4OmNhc2UgMjY4NDM1NDU2OmNhc2UgNTM2ODcwOTEyOmNhc2UgMTA3Mzc0MTgyNDpyZXR1cm4tMTtkZWZhdWx0OnJldHVybi0xfX1cbmZ1bmN0aW9uIHdjKGEsYil7Zm9yKHZhciBjPWEuc3VzcGVuZGVkTGFuZXMsZD1hLnBpbmdlZExhbmVzLGU9YS5leHBpcmF0aW9uVGltZXMsZj1hLnBlbmRpbmdMYW5lczswPGY7KXt2YXIgZz0zMS1vYyhmKSxoPTE8PGcsaz1lW2ddO2lmKC0xPT09ayl7aWYoMD09PShoJmMpfHwwIT09KGgmZCkpZVtnXT12YyhoLGIpfWVsc2Ugazw9YiYmKGEuZXhwaXJlZExhbmVzfD1oKTtmJj1+aH19ZnVuY3Rpb24geGMoYSl7YT1hLnBlbmRpbmdMYW5lcyYtMTA3Mzc0MTgyNTtyZXR1cm4gMCE9PWE/YTphJjEwNzM3NDE4MjQ/MTA3Mzc0MTgyNDowfWZ1bmN0aW9uIHljKCl7dmFyIGE9cmM7cmM8PD0xOzA9PT0ocmMmNDE5NDI0MCkmJihyYz02NCk7cmV0dXJuIGF9ZnVuY3Rpb24gemMoYSl7Zm9yKHZhciBiPVtdLGM9MDszMT5jO2MrKyliLnB1c2goYSk7cmV0dXJuIGJ9XG5mdW5jdGlvbiBBYyhhLGIsYyl7YS5wZW5kaW5nTGFuZXN8PWI7NTM2ODcwOTEyIT09YiYmKGEuc3VzcGVuZGVkTGFuZXM9MCxhLnBpbmdlZExhbmVzPTApO2E9YS5ldmVudFRpbWVzO2I9MzEtb2MoYik7YVtiXT1jfWZ1bmN0aW9uIEJjKGEsYil7dmFyIGM9YS5wZW5kaW5nTGFuZXMmfmI7YS5wZW5kaW5nTGFuZXM9YjthLnN1c3BlbmRlZExhbmVzPTA7YS5waW5nZWRMYW5lcz0wO2EuZXhwaXJlZExhbmVzJj1iO2EubXV0YWJsZVJlYWRMYW5lcyY9YjthLmVudGFuZ2xlZExhbmVzJj1iO2I9YS5lbnRhbmdsZW1lbnRzO3ZhciBkPWEuZXZlbnRUaW1lcztmb3IoYT1hLmV4cGlyYXRpb25UaW1lczswPGM7KXt2YXIgZT0zMS1vYyhjKSxmPTE8PGU7YltlXT0wO2RbZV09LTE7YVtlXT0tMTtjJj1+Zn19XG5mdW5jdGlvbiBDYyhhLGIpe3ZhciBjPWEuZW50YW5nbGVkTGFuZXN8PWI7Zm9yKGE9YS5lbnRhbmdsZW1lbnRzO2M7KXt2YXIgZD0zMS1vYyhjKSxlPTE8PGQ7ZSZifGFbZF0mYiYmKGFbZF18PWIpO2MmPX5lfX12YXIgQz0wO2Z1bmN0aW9uIERjKGEpe2EmPS1hO3JldHVybiAxPGE/NDxhPzAhPT0oYSYyNjg0MzU0NTUpPzE2OjUzNjg3MDkxMjo0OjF9dmFyIEVjLEZjLEdjLEhjLEljLEpjPSExLEtjPVtdLExjPW51bGwsTWM9bnVsbCxOYz1udWxsLE9jPW5ldyBNYXAsUGM9bmV3IE1hcCxRYz1bXSxSYz1cIm1vdXNlZG93biBtb3VzZXVwIHRvdWNoY2FuY2VsIHRvdWNoZW5kIHRvdWNoc3RhcnQgYXV4Y2xpY2sgZGJsY2xpY2sgcG9pbnRlcmNhbmNlbCBwb2ludGVyZG93biBwb2ludGVydXAgZHJhZ2VuZCBkcmFnc3RhcnQgZHJvcCBjb21wb3NpdGlvbmVuZCBjb21wb3NpdGlvbnN0YXJ0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgaW5wdXQgdGV4dElucHV0IGNvcHkgY3V0IHBhc3RlIGNsaWNrIGNoYW5nZSBjb250ZXh0bWVudSByZXNldCBzdWJtaXRcIi5zcGxpdChcIiBcIik7XG5mdW5jdGlvbiBTYyhhLGIpe3N3aXRjaChhKXtjYXNlIFwiZm9jdXNpblwiOmNhc2UgXCJmb2N1c291dFwiOkxjPW51bGw7YnJlYWs7Y2FzZSBcImRyYWdlbnRlclwiOmNhc2UgXCJkcmFnbGVhdmVcIjpNYz1udWxsO2JyZWFrO2Nhc2UgXCJtb3VzZW92ZXJcIjpjYXNlIFwibW91c2VvdXRcIjpOYz1udWxsO2JyZWFrO2Nhc2UgXCJwb2ludGVyb3ZlclwiOmNhc2UgXCJwb2ludGVyb3V0XCI6T2MuZGVsZXRlKGIucG9pbnRlcklkKTticmVhaztjYXNlIFwiZ290cG9pbnRlcmNhcHR1cmVcIjpjYXNlIFwibG9zdHBvaW50ZXJjYXB0dXJlXCI6UGMuZGVsZXRlKGIucG9pbnRlcklkKX19XG5mdW5jdGlvbiBUYyhhLGIsYyxkLGUsZil7aWYobnVsbD09PWF8fGEubmF0aXZlRXZlbnQhPT1mKXJldHVybiBhPXtibG9ja2VkT246Yixkb21FdmVudE5hbWU6YyxldmVudFN5c3RlbUZsYWdzOmQsbmF0aXZlRXZlbnQ6Zix0YXJnZXRDb250YWluZXJzOltlXX0sbnVsbCE9PWImJihiPUNiKGIpLG51bGwhPT1iJiZGYyhiKSksYTthLmV2ZW50U3lzdGVtRmxhZ3N8PWQ7Yj1hLnRhcmdldENvbnRhaW5lcnM7bnVsbCE9PWUmJi0xPT09Yi5pbmRleE9mKGUpJiZiLnB1c2goZSk7cmV0dXJuIGF9XG5mdW5jdGlvbiBVYyhhLGIsYyxkLGUpe3N3aXRjaChiKXtjYXNlIFwiZm9jdXNpblwiOnJldHVybiBMYz1UYyhMYyxhLGIsYyxkLGUpLCEwO2Nhc2UgXCJkcmFnZW50ZXJcIjpyZXR1cm4gTWM9VGMoTWMsYSxiLGMsZCxlKSwhMDtjYXNlIFwibW91c2VvdmVyXCI6cmV0dXJuIE5jPVRjKE5jLGEsYixjLGQsZSksITA7Y2FzZSBcInBvaW50ZXJvdmVyXCI6dmFyIGY9ZS5wb2ludGVySWQ7T2Muc2V0KGYsVGMoT2MuZ2V0KGYpfHxudWxsLGEsYixjLGQsZSkpO3JldHVybiEwO2Nhc2UgXCJnb3Rwb2ludGVyY2FwdHVyZVwiOnJldHVybiBmPWUucG9pbnRlcklkLFBjLnNldChmLFRjKFBjLmdldChmKXx8bnVsbCxhLGIsYyxkLGUpKSwhMH1yZXR1cm4hMX1cbmZ1bmN0aW9uIFZjKGEpe3ZhciBiPVdjKGEudGFyZ2V0KTtpZihudWxsIT09Yil7dmFyIGM9VmIoYik7aWYobnVsbCE9PWMpaWYoYj1jLnRhZywxMz09PWIpe2lmKGI9V2IoYyksbnVsbCE9PWIpe2EuYmxvY2tlZE9uPWI7SWMoYS5wcmlvcml0eSxmdW5jdGlvbigpe0djKGMpfSk7cmV0dXJufX1lbHNlIGlmKDM9PT1iJiZjLnN0YXRlTm9kZS5jdXJyZW50Lm1lbW9pemVkU3RhdGUuaXNEZWh5ZHJhdGVkKXthLmJsb2NrZWRPbj0zPT09Yy50YWc/Yy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbzpudWxsO3JldHVybn19YS5ibG9ja2VkT249bnVsbH1cbmZ1bmN0aW9uIFhjKGEpe2lmKG51bGwhPT1hLmJsb2NrZWRPbilyZXR1cm4hMTtmb3IodmFyIGI9YS50YXJnZXRDb250YWluZXJzOzA8Yi5sZW5ndGg7KXt2YXIgYz1ZYyhhLmRvbUV2ZW50TmFtZSxhLmV2ZW50U3lzdGVtRmxhZ3MsYlswXSxhLm5hdGl2ZUV2ZW50KTtpZihudWxsPT09Yyl7Yz1hLm5hdGl2ZUV2ZW50O3ZhciBkPW5ldyBjLmNvbnN0cnVjdG9yKGMudHlwZSxjKTt3Yj1kO2MudGFyZ2V0LmRpc3BhdGNoRXZlbnQoZCk7d2I9bnVsbH1lbHNlIHJldHVybiBiPUNiKGMpLG51bGwhPT1iJiZGYyhiKSxhLmJsb2NrZWRPbj1jLCExO2Iuc2hpZnQoKX1yZXR1cm4hMH1mdW5jdGlvbiBaYyhhLGIsYyl7WGMoYSkmJmMuZGVsZXRlKGIpfWZ1bmN0aW9uICRjKCl7SmM9ITE7bnVsbCE9PUxjJiZYYyhMYykmJihMYz1udWxsKTtudWxsIT09TWMmJlhjKE1jKSYmKE1jPW51bGwpO251bGwhPT1OYyYmWGMoTmMpJiYoTmM9bnVsbCk7T2MuZm9yRWFjaChaYyk7UGMuZm9yRWFjaChaYyl9XG5mdW5jdGlvbiBhZChhLGIpe2EuYmxvY2tlZE9uPT09YiYmKGEuYmxvY2tlZE9uPW51bGwsSmN8fChKYz0hMCxjYS51bnN0YWJsZV9zY2hlZHVsZUNhbGxiYWNrKGNhLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5LCRjKSkpfVxuZnVuY3Rpb24gYmQoYSl7ZnVuY3Rpb24gYihiKXtyZXR1cm4gYWQoYixhKX1pZigwPEtjLmxlbmd0aCl7YWQoS2NbMF0sYSk7Zm9yKHZhciBjPTE7YzxLYy5sZW5ndGg7YysrKXt2YXIgZD1LY1tjXTtkLmJsb2NrZWRPbj09PWEmJihkLmJsb2NrZWRPbj1udWxsKX19bnVsbCE9PUxjJiZhZChMYyxhKTtudWxsIT09TWMmJmFkKE1jLGEpO251bGwhPT1OYyYmYWQoTmMsYSk7T2MuZm9yRWFjaChiKTtQYy5mb3JFYWNoKGIpO2ZvcihjPTA7YzxRYy5sZW5ndGg7YysrKWQ9UWNbY10sZC5ibG9ja2VkT249PT1hJiYoZC5ibG9ja2VkT249bnVsbCk7Zm9yKDswPFFjLmxlbmd0aCYmKGM9UWNbMF0sbnVsbD09PWMuYmxvY2tlZE9uKTspVmMoYyksbnVsbD09PWMuYmxvY2tlZE9uJiZRYy5zaGlmdCgpfXZhciBjZD11YS5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZyxkZD0hMDtcbmZ1bmN0aW9uIGVkKGEsYixjLGQpe3ZhciBlPUMsZj1jZC50cmFuc2l0aW9uO2NkLnRyYW5zaXRpb249bnVsbDt0cnl7Qz0xLGZkKGEsYixjLGQpfWZpbmFsbHl7Qz1lLGNkLnRyYW5zaXRpb249Zn19ZnVuY3Rpb24gZ2QoYSxiLGMsZCl7dmFyIGU9QyxmPWNkLnRyYW5zaXRpb247Y2QudHJhbnNpdGlvbj1udWxsO3RyeXtDPTQsZmQoYSxiLGMsZCl9ZmluYWxseXtDPWUsY2QudHJhbnNpdGlvbj1mfX1cbmZ1bmN0aW9uIGZkKGEsYixjLGQpe2lmKGRkKXt2YXIgZT1ZYyhhLGIsYyxkKTtpZihudWxsPT09ZSloZChhLGIsZCxpZCxjKSxTYyhhLGQpO2Vsc2UgaWYoVWMoZSxhLGIsYyxkKSlkLnN0b3BQcm9wYWdhdGlvbigpO2Vsc2UgaWYoU2MoYSxkKSxiJjQmJi0xPFJjLmluZGV4T2YoYSkpe2Zvcig7bnVsbCE9PWU7KXt2YXIgZj1DYihlKTtudWxsIT09ZiYmRWMoZik7Zj1ZYyhhLGIsYyxkKTtudWxsPT09ZiYmaGQoYSxiLGQsaWQsYyk7aWYoZj09PWUpYnJlYWs7ZT1mfW51bGwhPT1lJiZkLnN0b3BQcm9wYWdhdGlvbigpfWVsc2UgaGQoYSxiLGQsbnVsbCxjKX19dmFyIGlkPW51bGw7XG5mdW5jdGlvbiBZYyhhLGIsYyxkKXtpZD1udWxsO2E9eGIoZCk7YT1XYyhhKTtpZihudWxsIT09YSlpZihiPVZiKGEpLG51bGw9PT1iKWE9bnVsbDtlbHNlIGlmKGM9Yi50YWcsMTM9PT1jKXthPVdiKGIpO2lmKG51bGwhPT1hKXJldHVybiBhO2E9bnVsbH1lbHNlIGlmKDM9PT1jKXtpZihiLnN0YXRlTm9kZS5jdXJyZW50Lm1lbW9pemVkU3RhdGUuaXNEZWh5ZHJhdGVkKXJldHVybiAzPT09Yi50YWc/Yi5zdGF0ZU5vZGUuY29udGFpbmVySW5mbzpudWxsO2E9bnVsbH1lbHNlIGIhPT1hJiYoYT1udWxsKTtpZD1hO3JldHVybiBudWxsfVxuZnVuY3Rpb24gamQoYSl7c3dpdGNoKGEpe2Nhc2UgXCJjYW5jZWxcIjpjYXNlIFwiY2xpY2tcIjpjYXNlIFwiY2xvc2VcIjpjYXNlIFwiY29udGV4dG1lbnVcIjpjYXNlIFwiY29weVwiOmNhc2UgXCJjdXRcIjpjYXNlIFwiYXV4Y2xpY2tcIjpjYXNlIFwiZGJsY2xpY2tcIjpjYXNlIFwiZHJhZ2VuZFwiOmNhc2UgXCJkcmFnc3RhcnRcIjpjYXNlIFwiZHJvcFwiOmNhc2UgXCJmb2N1c2luXCI6Y2FzZSBcImZvY3Vzb3V0XCI6Y2FzZSBcImlucHV0XCI6Y2FzZSBcImludmFsaWRcIjpjYXNlIFwia2V5ZG93blwiOmNhc2UgXCJrZXlwcmVzc1wiOmNhc2UgXCJrZXl1cFwiOmNhc2UgXCJtb3VzZWRvd25cIjpjYXNlIFwibW91c2V1cFwiOmNhc2UgXCJwYXN0ZVwiOmNhc2UgXCJwYXVzZVwiOmNhc2UgXCJwbGF5XCI6Y2FzZSBcInBvaW50ZXJjYW5jZWxcIjpjYXNlIFwicG9pbnRlcmRvd25cIjpjYXNlIFwicG9pbnRlcnVwXCI6Y2FzZSBcInJhdGVjaGFuZ2VcIjpjYXNlIFwicmVzZXRcIjpjYXNlIFwicmVzaXplXCI6Y2FzZSBcInNlZWtlZFwiOmNhc2UgXCJzdWJtaXRcIjpjYXNlIFwidG91Y2hjYW5jZWxcIjpjYXNlIFwidG91Y2hlbmRcIjpjYXNlIFwidG91Y2hzdGFydFwiOmNhc2UgXCJ2b2x1bWVjaGFuZ2VcIjpjYXNlIFwiY2hhbmdlXCI6Y2FzZSBcInNlbGVjdGlvbmNoYW5nZVwiOmNhc2UgXCJ0ZXh0SW5wdXRcIjpjYXNlIFwiY29tcG9zaXRpb25zdGFydFwiOmNhc2UgXCJjb21wb3NpdGlvbmVuZFwiOmNhc2UgXCJjb21wb3NpdGlvbnVwZGF0ZVwiOmNhc2UgXCJiZWZvcmVibHVyXCI6Y2FzZSBcImFmdGVyYmx1clwiOmNhc2UgXCJiZWZvcmVpbnB1dFwiOmNhc2UgXCJibHVyXCI6Y2FzZSBcImZ1bGxzY3JlZW5jaGFuZ2VcIjpjYXNlIFwiZm9jdXNcIjpjYXNlIFwiaGFzaGNoYW5nZVwiOmNhc2UgXCJwb3BzdGF0ZVwiOmNhc2UgXCJzZWxlY3RcIjpjYXNlIFwic2VsZWN0c3RhcnRcIjpyZXR1cm4gMTtjYXNlIFwiZHJhZ1wiOmNhc2UgXCJkcmFnZW50ZXJcIjpjYXNlIFwiZHJhZ2V4aXRcIjpjYXNlIFwiZHJhZ2xlYXZlXCI6Y2FzZSBcImRyYWdvdmVyXCI6Y2FzZSBcIm1vdXNlbW92ZVwiOmNhc2UgXCJtb3VzZW91dFwiOmNhc2UgXCJtb3VzZW92ZXJcIjpjYXNlIFwicG9pbnRlcm1vdmVcIjpjYXNlIFwicG9pbnRlcm91dFwiOmNhc2UgXCJwb2ludGVyb3ZlclwiOmNhc2UgXCJzY3JvbGxcIjpjYXNlIFwidG9nZ2xlXCI6Y2FzZSBcInRvdWNobW92ZVwiOmNhc2UgXCJ3aGVlbFwiOmNhc2UgXCJtb3VzZWVudGVyXCI6Y2FzZSBcIm1vdXNlbGVhdmVcIjpjYXNlIFwicG9pbnRlcmVudGVyXCI6Y2FzZSBcInBvaW50ZXJsZWF2ZVwiOnJldHVybiA0O1xuY2FzZSBcIm1lc3NhZ2VcIjpzd2l0Y2goZWMoKSl7Y2FzZSBmYzpyZXR1cm4gMTtjYXNlIGdjOnJldHVybiA0O2Nhc2UgaGM6Y2FzZSBpYzpyZXR1cm4gMTY7Y2FzZSBqYzpyZXR1cm4gNTM2ODcwOTEyO2RlZmF1bHQ6cmV0dXJuIDE2fWRlZmF1bHQ6cmV0dXJuIDE2fX12YXIga2Q9bnVsbCxsZD1udWxsLG1kPW51bGw7ZnVuY3Rpb24gbmQoKXtpZihtZClyZXR1cm4gbWQ7dmFyIGEsYj1sZCxjPWIubGVuZ3RoLGQsZT1cInZhbHVlXCJpbiBrZD9rZC52YWx1ZTprZC50ZXh0Q29udGVudCxmPWUubGVuZ3RoO2ZvcihhPTA7YTxjJiZiW2FdPT09ZVthXTthKyspO3ZhciBnPWMtYTtmb3IoZD0xO2Q8PWcmJmJbYy1kXT09PWVbZi1kXTtkKyspO3JldHVybiBtZD1lLnNsaWNlKGEsMTxkPzEtZDp2b2lkIDApfVxuZnVuY3Rpb24gb2QoYSl7dmFyIGI9YS5rZXlDb2RlO1wiY2hhckNvZGVcImluIGE/KGE9YS5jaGFyQ29kZSwwPT09YSYmMTM9PT1iJiYoYT0xMykpOmE9YjsxMD09PWEmJihhPTEzKTtyZXR1cm4gMzI8PWF8fDEzPT09YT9hOjB9ZnVuY3Rpb24gcGQoKXtyZXR1cm4hMH1mdW5jdGlvbiBxZCgpe3JldHVybiExfVxuZnVuY3Rpb24gcmQoYSl7ZnVuY3Rpb24gYihiLGQsZSxmLGcpe3RoaXMuX3JlYWN0TmFtZT1iO3RoaXMuX3RhcmdldEluc3Q9ZTt0aGlzLnR5cGU9ZDt0aGlzLm5hdGl2ZUV2ZW50PWY7dGhpcy50YXJnZXQ9Zzt0aGlzLmN1cnJlbnRUYXJnZXQ9bnVsbDtmb3IodmFyIGMgaW4gYSlhLmhhc093blByb3BlcnR5KGMpJiYoYj1hW2NdLHRoaXNbY109Yj9iKGYpOmZbY10pO3RoaXMuaXNEZWZhdWx0UHJldmVudGVkPShudWxsIT1mLmRlZmF1bHRQcmV2ZW50ZWQ/Zi5kZWZhdWx0UHJldmVudGVkOiExPT09Zi5yZXR1cm5WYWx1ZSk/cGQ6cWQ7dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1xZDtyZXR1cm4gdGhpc31BKGIucHJvdG90eXBlLHtwcmV2ZW50RGVmYXVsdDpmdW5jdGlvbigpe3RoaXMuZGVmYXVsdFByZXZlbnRlZD0hMDt2YXIgYT10aGlzLm5hdGl2ZUV2ZW50O2EmJihhLnByZXZlbnREZWZhdWx0P2EucHJldmVudERlZmF1bHQoKTpcInVua25vd25cIiE9PXR5cGVvZiBhLnJldHVyblZhbHVlJiZcbihhLnJldHVyblZhbHVlPSExKSx0aGlzLmlzRGVmYXVsdFByZXZlbnRlZD1wZCl9LHN0b3BQcm9wYWdhdGlvbjpmdW5jdGlvbigpe3ZhciBhPXRoaXMubmF0aXZlRXZlbnQ7YSYmKGEuc3RvcFByb3BhZ2F0aW9uP2Euc3RvcFByb3BhZ2F0aW9uKCk6XCJ1bmtub3duXCIhPT10eXBlb2YgYS5jYW5jZWxCdWJibGUmJihhLmNhbmNlbEJ1YmJsZT0hMCksdGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1wZCl9LHBlcnNpc3Q6ZnVuY3Rpb24oKXt9LGlzUGVyc2lzdGVudDpwZH0pO3JldHVybiBifVxudmFyIHNkPXtldmVudFBoYXNlOjAsYnViYmxlczowLGNhbmNlbGFibGU6MCx0aW1lU3RhbXA6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudGltZVN0YW1wfHxEYXRlLm5vdygpfSxkZWZhdWx0UHJldmVudGVkOjAsaXNUcnVzdGVkOjB9LHRkPXJkKHNkKSx1ZD1BKHt9LHNkLHt2aWV3OjAsZGV0YWlsOjB9KSx2ZD1yZCh1ZCksd2QseGQseWQsQWQ9QSh7fSx1ZCx7c2NyZWVuWDowLHNjcmVlblk6MCxjbGllbnRYOjAsY2xpZW50WTowLHBhZ2VYOjAscGFnZVk6MCxjdHJsS2V5OjAsc2hpZnRLZXk6MCxhbHRLZXk6MCxtZXRhS2V5OjAsZ2V0TW9kaWZpZXJTdGF0ZTp6ZCxidXR0b246MCxidXR0b25zOjAscmVsYXRlZFRhcmdldDpmdW5jdGlvbihhKXtyZXR1cm4gdm9pZCAwPT09YS5yZWxhdGVkVGFyZ2V0P2EuZnJvbUVsZW1lbnQ9PT1hLnNyY0VsZW1lbnQ/YS50b0VsZW1lbnQ6YS5mcm9tRWxlbWVudDphLnJlbGF0ZWRUYXJnZXR9LG1vdmVtZW50WDpmdW5jdGlvbihhKXtpZihcIm1vdmVtZW50WFwiaW5cbmEpcmV0dXJuIGEubW92ZW1lbnRYO2EhPT15ZCYmKHlkJiZcIm1vdXNlbW92ZVwiPT09YS50eXBlPyh3ZD1hLnNjcmVlblgteWQuc2NyZWVuWCx4ZD1hLnNjcmVlblkteWQuc2NyZWVuWSk6eGQ9d2Q9MCx5ZD1hKTtyZXR1cm4gd2R9LG1vdmVtZW50WTpmdW5jdGlvbihhKXtyZXR1cm5cIm1vdmVtZW50WVwiaW4gYT9hLm1vdmVtZW50WTp4ZH19KSxCZD1yZChBZCksQ2Q9QSh7fSxBZCx7ZGF0YVRyYW5zZmVyOjB9KSxEZD1yZChDZCksRWQ9QSh7fSx1ZCx7cmVsYXRlZFRhcmdldDowfSksRmQ9cmQoRWQpLEdkPUEoe30sc2Qse2FuaW1hdGlvbk5hbWU6MCxlbGFwc2VkVGltZTowLHBzZXVkb0VsZW1lbnQ6MH0pLEhkPXJkKEdkKSxJZD1BKHt9LHNkLHtjbGlwYm9hcmREYXRhOmZ1bmN0aW9uKGEpe3JldHVyblwiY2xpcGJvYXJkRGF0YVwiaW4gYT9hLmNsaXBib2FyZERhdGE6d2luZG93LmNsaXBib2FyZERhdGF9fSksSmQ9cmQoSWQpLEtkPUEoe30sc2Qse2RhdGE6MH0pLExkPXJkKEtkKSxNZD17RXNjOlwiRXNjYXBlXCIsXG5TcGFjZWJhcjpcIiBcIixMZWZ0OlwiQXJyb3dMZWZ0XCIsVXA6XCJBcnJvd1VwXCIsUmlnaHQ6XCJBcnJvd1JpZ2h0XCIsRG93bjpcIkFycm93RG93blwiLERlbDpcIkRlbGV0ZVwiLFdpbjpcIk9TXCIsTWVudTpcIkNvbnRleHRNZW51XCIsQXBwczpcIkNvbnRleHRNZW51XCIsU2Nyb2xsOlwiU2Nyb2xsTG9ja1wiLE1velByaW50YWJsZUtleTpcIlVuaWRlbnRpZmllZFwifSxOZD17ODpcIkJhY2tzcGFjZVwiLDk6XCJUYWJcIiwxMjpcIkNsZWFyXCIsMTM6XCJFbnRlclwiLDE2OlwiU2hpZnRcIiwxNzpcIkNvbnRyb2xcIiwxODpcIkFsdFwiLDE5OlwiUGF1c2VcIiwyMDpcIkNhcHNMb2NrXCIsMjc6XCJFc2NhcGVcIiwzMjpcIiBcIiwzMzpcIlBhZ2VVcFwiLDM0OlwiUGFnZURvd25cIiwzNTpcIkVuZFwiLDM2OlwiSG9tZVwiLDM3OlwiQXJyb3dMZWZ0XCIsMzg6XCJBcnJvd1VwXCIsMzk6XCJBcnJvd1JpZ2h0XCIsNDA6XCJBcnJvd0Rvd25cIiw0NTpcIkluc2VydFwiLDQ2OlwiRGVsZXRlXCIsMTEyOlwiRjFcIiwxMTM6XCJGMlwiLDExNDpcIkYzXCIsMTE1OlwiRjRcIiwxMTY6XCJGNVwiLDExNzpcIkY2XCIsMTE4OlwiRjdcIixcbjExOTpcIkY4XCIsMTIwOlwiRjlcIiwxMjE6XCJGMTBcIiwxMjI6XCJGMTFcIiwxMjM6XCJGMTJcIiwxNDQ6XCJOdW1Mb2NrXCIsMTQ1OlwiU2Nyb2xsTG9ja1wiLDIyNDpcIk1ldGFcIn0sT2Q9e0FsdDpcImFsdEtleVwiLENvbnRyb2w6XCJjdHJsS2V5XCIsTWV0YTpcIm1ldGFLZXlcIixTaGlmdDpcInNoaWZ0S2V5XCJ9O2Z1bmN0aW9uIFBkKGEpe3ZhciBiPXRoaXMubmF0aXZlRXZlbnQ7cmV0dXJuIGIuZ2V0TW9kaWZpZXJTdGF0ZT9iLmdldE1vZGlmaWVyU3RhdGUoYSk6KGE9T2RbYV0pPyEhYlthXTohMX1mdW5jdGlvbiB6ZCgpe3JldHVybiBQZH1cbnZhciBRZD1BKHt9LHVkLHtrZXk6ZnVuY3Rpb24oYSl7aWYoYS5rZXkpe3ZhciBiPU1kW2Eua2V5XXx8YS5rZXk7aWYoXCJVbmlkZW50aWZpZWRcIiE9PWIpcmV0dXJuIGJ9cmV0dXJuXCJrZXlwcmVzc1wiPT09YS50eXBlPyhhPW9kKGEpLDEzPT09YT9cIkVudGVyXCI6U3RyaW5nLmZyb21DaGFyQ29kZShhKSk6XCJrZXlkb3duXCI9PT1hLnR5cGV8fFwia2V5dXBcIj09PWEudHlwZT9OZFthLmtleUNvZGVdfHxcIlVuaWRlbnRpZmllZFwiOlwiXCJ9LGNvZGU6MCxsb2NhdGlvbjowLGN0cmxLZXk6MCxzaGlmdEtleTowLGFsdEtleTowLG1ldGFLZXk6MCxyZXBlYXQ6MCxsb2NhbGU6MCxnZXRNb2RpZmllclN0YXRlOnpkLGNoYXJDb2RlOmZ1bmN0aW9uKGEpe3JldHVyblwia2V5cHJlc3NcIj09PWEudHlwZT9vZChhKTowfSxrZXlDb2RlOmZ1bmN0aW9uKGEpe3JldHVyblwia2V5ZG93blwiPT09YS50eXBlfHxcImtleXVwXCI9PT1hLnR5cGU/YS5rZXlDb2RlOjB9LHdoaWNoOmZ1bmN0aW9uKGEpe3JldHVyblwia2V5cHJlc3NcIj09PVxuYS50eXBlP29kKGEpOlwia2V5ZG93blwiPT09YS50eXBlfHxcImtleXVwXCI9PT1hLnR5cGU/YS5rZXlDb2RlOjB9fSksUmQ9cmQoUWQpLFNkPUEoe30sQWQse3BvaW50ZXJJZDowLHdpZHRoOjAsaGVpZ2h0OjAscHJlc3N1cmU6MCx0YW5nZW50aWFsUHJlc3N1cmU6MCx0aWx0WDowLHRpbHRZOjAsdHdpc3Q6MCxwb2ludGVyVHlwZTowLGlzUHJpbWFyeTowfSksVGQ9cmQoU2QpLFVkPUEoe30sdWQse3RvdWNoZXM6MCx0YXJnZXRUb3VjaGVzOjAsY2hhbmdlZFRvdWNoZXM6MCxhbHRLZXk6MCxtZXRhS2V5OjAsY3RybEtleTowLHNoaWZ0S2V5OjAsZ2V0TW9kaWZpZXJTdGF0ZTp6ZH0pLFZkPXJkKFVkKSxXZD1BKHt9LHNkLHtwcm9wZXJ0eU5hbWU6MCxlbGFwc2VkVGltZTowLHBzZXVkb0VsZW1lbnQ6MH0pLFhkPXJkKFdkKSxZZD1BKHt9LEFkLHtkZWx0YVg6ZnVuY3Rpb24oYSl7cmV0dXJuXCJkZWx0YVhcImluIGE/YS5kZWx0YVg6XCJ3aGVlbERlbHRhWFwiaW4gYT8tYS53aGVlbERlbHRhWDowfSxcbmRlbHRhWTpmdW5jdGlvbihhKXtyZXR1cm5cImRlbHRhWVwiaW4gYT9hLmRlbHRhWTpcIndoZWVsRGVsdGFZXCJpbiBhPy1hLndoZWVsRGVsdGFZOlwid2hlZWxEZWx0YVwiaW4gYT8tYS53aGVlbERlbHRhOjB9LGRlbHRhWjowLGRlbHRhTW9kZTowfSksWmQ9cmQoWWQpLCRkPVs5LDEzLDI3LDMyXSxhZT1pYSYmXCJDb21wb3NpdGlvbkV2ZW50XCJpbiB3aW5kb3csYmU9bnVsbDtpYSYmXCJkb2N1bWVudE1vZGVcImluIGRvY3VtZW50JiYoYmU9ZG9jdW1lbnQuZG9jdW1lbnRNb2RlKTt2YXIgY2U9aWEmJlwiVGV4dEV2ZW50XCJpbiB3aW5kb3cmJiFiZSxkZT1pYSYmKCFhZXx8YmUmJjg8YmUmJjExPj1iZSksZWU9U3RyaW5nLmZyb21DaGFyQ29kZSgzMiksZmU9ITE7XG5mdW5jdGlvbiBnZShhLGIpe3N3aXRjaChhKXtjYXNlIFwia2V5dXBcIjpyZXR1cm4tMSE9PSRkLmluZGV4T2YoYi5rZXlDb2RlKTtjYXNlIFwia2V5ZG93blwiOnJldHVybiAyMjkhPT1iLmtleUNvZGU7Y2FzZSBcImtleXByZXNzXCI6Y2FzZSBcIm1vdXNlZG93blwiOmNhc2UgXCJmb2N1c291dFwiOnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuITF9fWZ1bmN0aW9uIGhlKGEpe2E9YS5kZXRhaWw7cmV0dXJuXCJvYmplY3RcIj09PXR5cGVvZiBhJiZcImRhdGFcImluIGE/YS5kYXRhOm51bGx9dmFyIGllPSExO2Z1bmN0aW9uIGplKGEsYil7c3dpdGNoKGEpe2Nhc2UgXCJjb21wb3NpdGlvbmVuZFwiOnJldHVybiBoZShiKTtjYXNlIFwia2V5cHJlc3NcIjppZigzMiE9PWIud2hpY2gpcmV0dXJuIG51bGw7ZmU9ITA7cmV0dXJuIGVlO2Nhc2UgXCJ0ZXh0SW5wdXRcIjpyZXR1cm4gYT1iLmRhdGEsYT09PWVlJiZmZT9udWxsOmE7ZGVmYXVsdDpyZXR1cm4gbnVsbH19XG5mdW5jdGlvbiBrZShhLGIpe2lmKGllKXJldHVyblwiY29tcG9zaXRpb25lbmRcIj09PWF8fCFhZSYmZ2UoYSxiKT8oYT1uZCgpLG1kPWxkPWtkPW51bGwsaWU9ITEsYSk6bnVsbDtzd2l0Y2goYSl7Y2FzZSBcInBhc3RlXCI6cmV0dXJuIG51bGw7Y2FzZSBcImtleXByZXNzXCI6aWYoIShiLmN0cmxLZXl8fGIuYWx0S2V5fHxiLm1ldGFLZXkpfHxiLmN0cmxLZXkmJmIuYWx0S2V5KXtpZihiLmNoYXImJjE8Yi5jaGFyLmxlbmd0aClyZXR1cm4gYi5jaGFyO2lmKGIud2hpY2gpcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoYi53aGljaCl9cmV0dXJuIG51bGw7Y2FzZSBcImNvbXBvc2l0aW9uZW5kXCI6cmV0dXJuIGRlJiZcImtvXCIhPT1iLmxvY2FsZT9udWxsOmIuZGF0YTtkZWZhdWx0OnJldHVybiBudWxsfX1cbnZhciBsZT17Y29sb3I6ITAsZGF0ZTohMCxkYXRldGltZTohMCxcImRhdGV0aW1lLWxvY2FsXCI6ITAsZW1haWw6ITAsbW9udGg6ITAsbnVtYmVyOiEwLHBhc3N3b3JkOiEwLHJhbmdlOiEwLHNlYXJjaDohMCx0ZWw6ITAsdGV4dDohMCx0aW1lOiEwLHVybDohMCx3ZWVrOiEwfTtmdW5jdGlvbiBtZShhKXt2YXIgYj1hJiZhLm5vZGVOYW1lJiZhLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuXCJpbnB1dFwiPT09Yj8hIWxlW2EudHlwZV06XCJ0ZXh0YXJlYVwiPT09Yj8hMDohMX1mdW5jdGlvbiBuZShhLGIsYyxkKXtFYihkKTtiPW9lKGIsXCJvbkNoYW5nZVwiKTswPGIubGVuZ3RoJiYoYz1uZXcgdGQoXCJvbkNoYW5nZVwiLFwiY2hhbmdlXCIsbnVsbCxjLGQpLGEucHVzaCh7ZXZlbnQ6YyxsaXN0ZW5lcnM6Yn0pKX12YXIgcGU9bnVsbCxxZT1udWxsO2Z1bmN0aW9uIHJlKGEpe3NlKGEsMCl9ZnVuY3Rpb24gdGUoYSl7dmFyIGI9dWUoYSk7aWYoV2EoYikpcmV0dXJuIGF9XG5mdW5jdGlvbiB2ZShhLGIpe2lmKFwiY2hhbmdlXCI9PT1hKXJldHVybiBifXZhciB3ZT0hMTtpZihpYSl7dmFyIHhlO2lmKGlhKXt2YXIgeWU9XCJvbmlucHV0XCJpbiBkb2N1bWVudDtpZigheWUpe3ZhciB6ZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO3plLnNldEF0dHJpYnV0ZShcIm9uaW5wdXRcIixcInJldHVybjtcIik7eWU9XCJmdW5jdGlvblwiPT09dHlwZW9mIHplLm9uaW5wdXR9eGU9eWV9ZWxzZSB4ZT0hMTt3ZT14ZSYmKCFkb2N1bWVudC5kb2N1bWVudE1vZGV8fDk8ZG9jdW1lbnQuZG9jdW1lbnRNb2RlKX1mdW5jdGlvbiBBZSgpe3BlJiYocGUuZGV0YWNoRXZlbnQoXCJvbnByb3BlcnR5Y2hhbmdlXCIsQmUpLHFlPXBlPW51bGwpfWZ1bmN0aW9uIEJlKGEpe2lmKFwidmFsdWVcIj09PWEucHJvcGVydHlOYW1lJiZ0ZShxZSkpe3ZhciBiPVtdO25lKGIscWUsYSx4YihhKSk7SmIocmUsYil9fVxuZnVuY3Rpb24gQ2UoYSxiLGMpe1wiZm9jdXNpblwiPT09YT8oQWUoKSxwZT1iLHFlPWMscGUuYXR0YWNoRXZlbnQoXCJvbnByb3BlcnR5Y2hhbmdlXCIsQmUpKTpcImZvY3Vzb3V0XCI9PT1hJiZBZSgpfWZ1bmN0aW9uIERlKGEpe2lmKFwic2VsZWN0aW9uY2hhbmdlXCI9PT1hfHxcImtleXVwXCI9PT1hfHxcImtleWRvd25cIj09PWEpcmV0dXJuIHRlKHFlKX1mdW5jdGlvbiBFZShhLGIpe2lmKFwiY2xpY2tcIj09PWEpcmV0dXJuIHRlKGIpfWZ1bmN0aW9uIEZlKGEsYil7aWYoXCJpbnB1dFwiPT09YXx8XCJjaGFuZ2VcIj09PWEpcmV0dXJuIHRlKGIpfWZ1bmN0aW9uIEdlKGEsYil7cmV0dXJuIGE9PT1iJiYoMCE9PWF8fDEvYT09PTEvYil8fGEhPT1hJiZiIT09Yn12YXIgSGU9XCJmdW5jdGlvblwiPT09dHlwZW9mIE9iamVjdC5pcz9PYmplY3QuaXM6R2U7XG5mdW5jdGlvbiBJZShhLGIpe2lmKEhlKGEsYikpcmV0dXJuITA7aWYoXCJvYmplY3RcIiE9PXR5cGVvZiBhfHxudWxsPT09YXx8XCJvYmplY3RcIiE9PXR5cGVvZiBifHxudWxsPT09YilyZXR1cm4hMTt2YXIgYz1PYmplY3Qua2V5cyhhKSxkPU9iamVjdC5rZXlzKGIpO2lmKGMubGVuZ3RoIT09ZC5sZW5ndGgpcmV0dXJuITE7Zm9yKGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGU9Y1tkXTtpZighamEuY2FsbChiLGUpfHwhSGUoYVtlXSxiW2VdKSlyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBKZShhKXtmb3IoO2EmJmEuZmlyc3RDaGlsZDspYT1hLmZpcnN0Q2hpbGQ7cmV0dXJuIGF9XG5mdW5jdGlvbiBLZShhLGIpe3ZhciBjPUplKGEpO2E9MDtmb3IodmFyIGQ7Yzspe2lmKDM9PT1jLm5vZGVUeXBlKXtkPWErYy50ZXh0Q29udGVudC5sZW5ndGg7aWYoYTw9YiYmZD49YilyZXR1cm57bm9kZTpjLG9mZnNldDpiLWF9O2E9ZH1hOntmb3IoO2M7KXtpZihjLm5leHRTaWJsaW5nKXtjPWMubmV4dFNpYmxpbmc7YnJlYWsgYX1jPWMucGFyZW50Tm9kZX1jPXZvaWQgMH1jPUplKGMpfX1mdW5jdGlvbiBMZShhLGIpe3JldHVybiBhJiZiP2E9PT1iPyEwOmEmJjM9PT1hLm5vZGVUeXBlPyExOmImJjM9PT1iLm5vZGVUeXBlP0xlKGEsYi5wYXJlbnROb2RlKTpcImNvbnRhaW5zXCJpbiBhP2EuY29udGFpbnMoYik6YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbj8hIShhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIpJjE2KTohMTohMX1cbmZ1bmN0aW9uIE1lKCl7Zm9yKHZhciBhPXdpbmRvdyxiPVhhKCk7YiBpbnN0YW5jZW9mIGEuSFRNTElGcmFtZUVsZW1lbnQ7KXt0cnl7dmFyIGM9XCJzdHJpbmdcIj09PXR5cGVvZiBiLmNvbnRlbnRXaW5kb3cubG9jYXRpb24uaHJlZn1jYXRjaChkKXtjPSExfWlmKGMpYT1iLmNvbnRlbnRXaW5kb3c7ZWxzZSBicmVhaztiPVhhKGEuZG9jdW1lbnQpfXJldHVybiBifWZ1bmN0aW9uIE5lKGEpe3ZhciBiPWEmJmEubm9kZU5hbWUmJmEubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4gYiYmKFwiaW5wdXRcIj09PWImJihcInRleHRcIj09PWEudHlwZXx8XCJzZWFyY2hcIj09PWEudHlwZXx8XCJ0ZWxcIj09PWEudHlwZXx8XCJ1cmxcIj09PWEudHlwZXx8XCJwYXNzd29yZFwiPT09YS50eXBlKXx8XCJ0ZXh0YXJlYVwiPT09Ynx8XCJ0cnVlXCI9PT1hLmNvbnRlbnRFZGl0YWJsZSl9XG5mdW5jdGlvbiBPZShhKXt2YXIgYj1NZSgpLGM9YS5mb2N1c2VkRWxlbSxkPWEuc2VsZWN0aW9uUmFuZ2U7aWYoYiE9PWMmJmMmJmMub3duZXJEb2N1bWVudCYmTGUoYy5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxjKSl7aWYobnVsbCE9PWQmJk5lKGMpKWlmKGI9ZC5zdGFydCxhPWQuZW5kLHZvaWQgMD09PWEmJihhPWIpLFwic2VsZWN0aW9uU3RhcnRcImluIGMpYy5zZWxlY3Rpb25TdGFydD1iLGMuc2VsZWN0aW9uRW5kPU1hdGgubWluKGEsYy52YWx1ZS5sZW5ndGgpO2Vsc2UgaWYoYT0oYj1jLm93bmVyRG9jdW1lbnR8fGRvY3VtZW50KSYmYi5kZWZhdWx0Vmlld3x8d2luZG93LGEuZ2V0U2VsZWN0aW9uKXthPWEuZ2V0U2VsZWN0aW9uKCk7dmFyIGU9Yy50ZXh0Q29udGVudC5sZW5ndGgsZj1NYXRoLm1pbihkLnN0YXJ0LGUpO2Q9dm9pZCAwPT09ZC5lbmQ/ZjpNYXRoLm1pbihkLmVuZCxlKTshYS5leHRlbmQmJmY+ZCYmKGU9ZCxkPWYsZj1lKTtlPUtlKGMsZik7dmFyIGc9S2UoYyxcbmQpO2UmJmcmJigxIT09YS5yYW5nZUNvdW50fHxhLmFuY2hvck5vZGUhPT1lLm5vZGV8fGEuYW5jaG9yT2Zmc2V0IT09ZS5vZmZzZXR8fGEuZm9jdXNOb2RlIT09Zy5ub2RlfHxhLmZvY3VzT2Zmc2V0IT09Zy5vZmZzZXQpJiYoYj1iLmNyZWF0ZVJhbmdlKCksYi5zZXRTdGFydChlLm5vZGUsZS5vZmZzZXQpLGEucmVtb3ZlQWxsUmFuZ2VzKCksZj5kPyhhLmFkZFJhbmdlKGIpLGEuZXh0ZW5kKGcubm9kZSxnLm9mZnNldCkpOihiLnNldEVuZChnLm5vZGUsZy5vZmZzZXQpLGEuYWRkUmFuZ2UoYikpKX1iPVtdO2ZvcihhPWM7YT1hLnBhcmVudE5vZGU7KTE9PT1hLm5vZGVUeXBlJiZiLnB1c2goe2VsZW1lbnQ6YSxsZWZ0OmEuc2Nyb2xsTGVmdCx0b3A6YS5zY3JvbGxUb3B9KTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYy5mb2N1cyYmYy5mb2N1cygpO2ZvcihjPTA7YzxiLmxlbmd0aDtjKyspYT1iW2NdLGEuZWxlbWVudC5zY3JvbGxMZWZ0PWEubGVmdCxhLmVsZW1lbnQuc2Nyb2xsVG9wPWEudG9wfX1cbnZhciBQZT1pYSYmXCJkb2N1bWVudE1vZGVcImluIGRvY3VtZW50JiYxMT49ZG9jdW1lbnQuZG9jdW1lbnRNb2RlLFFlPW51bGwsUmU9bnVsbCxTZT1udWxsLFRlPSExO1xuZnVuY3Rpb24gVWUoYSxiLGMpe3ZhciBkPWMud2luZG93PT09Yz9jLmRvY3VtZW50Ojk9PT1jLm5vZGVUeXBlP2M6Yy5vd25lckRvY3VtZW50O1RlfHxudWxsPT1RZXx8UWUhPT1YYShkKXx8KGQ9UWUsXCJzZWxlY3Rpb25TdGFydFwiaW4gZCYmTmUoZCk/ZD17c3RhcnQ6ZC5zZWxlY3Rpb25TdGFydCxlbmQ6ZC5zZWxlY3Rpb25FbmR9OihkPShkLm93bmVyRG9jdW1lbnQmJmQub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlld3x8d2luZG93KS5nZXRTZWxlY3Rpb24oKSxkPXthbmNob3JOb2RlOmQuYW5jaG9yTm9kZSxhbmNob3JPZmZzZXQ6ZC5hbmNob3JPZmZzZXQsZm9jdXNOb2RlOmQuZm9jdXNOb2RlLGZvY3VzT2Zmc2V0OmQuZm9jdXNPZmZzZXR9KSxTZSYmSWUoU2UsZCl8fChTZT1kLGQ9b2UoUmUsXCJvblNlbGVjdFwiKSwwPGQubGVuZ3RoJiYoYj1uZXcgdGQoXCJvblNlbGVjdFwiLFwic2VsZWN0XCIsbnVsbCxiLGMpLGEucHVzaCh7ZXZlbnQ6YixsaXN0ZW5lcnM6ZH0pLGIudGFyZ2V0PVFlKSkpfVxuZnVuY3Rpb24gVmUoYSxiKXt2YXIgYz17fTtjW2EudG9Mb3dlckNhc2UoKV09Yi50b0xvd2VyQ2FzZSgpO2NbXCJXZWJraXRcIithXT1cIndlYmtpdFwiK2I7Y1tcIk1velwiK2FdPVwibW96XCIrYjtyZXR1cm4gY312YXIgV2U9e2FuaW1hdGlvbmVuZDpWZShcIkFuaW1hdGlvblwiLFwiQW5pbWF0aW9uRW5kXCIpLGFuaW1hdGlvbml0ZXJhdGlvbjpWZShcIkFuaW1hdGlvblwiLFwiQW5pbWF0aW9uSXRlcmF0aW9uXCIpLGFuaW1hdGlvbnN0YXJ0OlZlKFwiQW5pbWF0aW9uXCIsXCJBbmltYXRpb25TdGFydFwiKSx0cmFuc2l0aW9uZW5kOlZlKFwiVHJhbnNpdGlvblwiLFwiVHJhbnNpdGlvbkVuZFwiKX0sWGU9e30sWWU9e307XG5pYSYmKFllPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikuc3R5bGUsXCJBbmltYXRpb25FdmVudFwiaW4gd2luZG93fHwoZGVsZXRlIFdlLmFuaW1hdGlvbmVuZC5hbmltYXRpb24sZGVsZXRlIFdlLmFuaW1hdGlvbml0ZXJhdGlvbi5hbmltYXRpb24sZGVsZXRlIFdlLmFuaW1hdGlvbnN0YXJ0LmFuaW1hdGlvbiksXCJUcmFuc2l0aW9uRXZlbnRcImluIHdpbmRvd3x8ZGVsZXRlIFdlLnRyYW5zaXRpb25lbmQudHJhbnNpdGlvbik7ZnVuY3Rpb24gWmUoYSl7aWYoWGVbYV0pcmV0dXJuIFhlW2FdO2lmKCFXZVthXSlyZXR1cm4gYTt2YXIgYj1XZVthXSxjO2ZvcihjIGluIGIpaWYoYi5oYXNPd25Qcm9wZXJ0eShjKSYmYyBpbiBZZSlyZXR1cm4gWGVbYV09YltjXTtyZXR1cm4gYX12YXIgJGU9WmUoXCJhbmltYXRpb25lbmRcIiksYWY9WmUoXCJhbmltYXRpb25pdGVyYXRpb25cIiksYmY9WmUoXCJhbmltYXRpb25zdGFydFwiKSxjZj1aZShcInRyYW5zaXRpb25lbmRcIiksZGY9bmV3IE1hcCxlZj1cImFib3J0IGF1eENsaWNrIGNhbmNlbCBjYW5QbGF5IGNhblBsYXlUaHJvdWdoIGNsaWNrIGNsb3NlIGNvbnRleHRNZW51IGNvcHkgY3V0IGRyYWcgZHJhZ0VuZCBkcmFnRW50ZXIgZHJhZ0V4aXQgZHJhZ0xlYXZlIGRyYWdPdmVyIGRyYWdTdGFydCBkcm9wIGR1cmF0aW9uQ2hhbmdlIGVtcHRpZWQgZW5jcnlwdGVkIGVuZGVkIGVycm9yIGdvdFBvaW50ZXJDYXB0dXJlIGlucHV0IGludmFsaWQga2V5RG93biBrZXlQcmVzcyBrZXlVcCBsb2FkIGxvYWRlZERhdGEgbG9hZGVkTWV0YWRhdGEgbG9hZFN0YXJ0IGxvc3RQb2ludGVyQ2FwdHVyZSBtb3VzZURvd24gbW91c2VNb3ZlIG1vdXNlT3V0IG1vdXNlT3ZlciBtb3VzZVVwIHBhc3RlIHBhdXNlIHBsYXkgcGxheWluZyBwb2ludGVyQ2FuY2VsIHBvaW50ZXJEb3duIHBvaW50ZXJNb3ZlIHBvaW50ZXJPdXQgcG9pbnRlck92ZXIgcG9pbnRlclVwIHByb2dyZXNzIHJhdGVDaGFuZ2UgcmVzZXQgcmVzaXplIHNlZWtlZCBzZWVraW5nIHN0YWxsZWQgc3VibWl0IHN1c3BlbmQgdGltZVVwZGF0ZSB0b3VjaENhbmNlbCB0b3VjaEVuZCB0b3VjaFN0YXJ0IHZvbHVtZUNoYW5nZSBzY3JvbGwgdG9nZ2xlIHRvdWNoTW92ZSB3YWl0aW5nIHdoZWVsXCIuc3BsaXQoXCIgXCIpO1xuZnVuY3Rpb24gZmYoYSxiKXtkZi5zZXQoYSxiKTtmYShiLFthXSl9Zm9yKHZhciBnZj0wO2dmPGVmLmxlbmd0aDtnZisrKXt2YXIgaGY9ZWZbZ2ZdLGpmPWhmLnRvTG93ZXJDYXNlKCksa2Y9aGZbMF0udG9VcHBlckNhc2UoKStoZi5zbGljZSgxKTtmZihqZixcIm9uXCIra2YpfWZmKCRlLFwib25BbmltYXRpb25FbmRcIik7ZmYoYWYsXCJvbkFuaW1hdGlvbkl0ZXJhdGlvblwiKTtmZihiZixcIm9uQW5pbWF0aW9uU3RhcnRcIik7ZmYoXCJkYmxjbGlja1wiLFwib25Eb3VibGVDbGlja1wiKTtmZihcImZvY3VzaW5cIixcIm9uRm9jdXNcIik7ZmYoXCJmb2N1c291dFwiLFwib25CbHVyXCIpO2ZmKGNmLFwib25UcmFuc2l0aW9uRW5kXCIpO2hhKFwib25Nb3VzZUVudGVyXCIsW1wibW91c2VvdXRcIixcIm1vdXNlb3ZlclwiXSk7aGEoXCJvbk1vdXNlTGVhdmVcIixbXCJtb3VzZW91dFwiLFwibW91c2VvdmVyXCJdKTtoYShcIm9uUG9pbnRlckVudGVyXCIsW1wicG9pbnRlcm91dFwiLFwicG9pbnRlcm92ZXJcIl0pO1xuaGEoXCJvblBvaW50ZXJMZWF2ZVwiLFtcInBvaW50ZXJvdXRcIixcInBvaW50ZXJvdmVyXCJdKTtmYShcIm9uQ2hhbmdlXCIsXCJjaGFuZ2UgY2xpY2sgZm9jdXNpbiBmb2N1c291dCBpbnB1dCBrZXlkb3duIGtleXVwIHNlbGVjdGlvbmNoYW5nZVwiLnNwbGl0KFwiIFwiKSk7ZmEoXCJvblNlbGVjdFwiLFwiZm9jdXNvdXQgY29udGV4dG1lbnUgZHJhZ2VuZCBmb2N1c2luIGtleWRvd24ga2V5dXAgbW91c2Vkb3duIG1vdXNldXAgc2VsZWN0aW9uY2hhbmdlXCIuc3BsaXQoXCIgXCIpKTtmYShcIm9uQmVmb3JlSW5wdXRcIixbXCJjb21wb3NpdGlvbmVuZFwiLFwia2V5cHJlc3NcIixcInRleHRJbnB1dFwiLFwicGFzdGVcIl0pO2ZhKFwib25Db21wb3NpdGlvbkVuZFwiLFwiY29tcG9zaXRpb25lbmQgZm9jdXNvdXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBtb3VzZWRvd25cIi5zcGxpdChcIiBcIikpO2ZhKFwib25Db21wb3NpdGlvblN0YXJ0XCIsXCJjb21wb3NpdGlvbnN0YXJ0IGZvY3Vzb3V0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgbW91c2Vkb3duXCIuc3BsaXQoXCIgXCIpKTtcbmZhKFwib25Db21wb3NpdGlvblVwZGF0ZVwiLFwiY29tcG9zaXRpb251cGRhdGUgZm9jdXNvdXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBtb3VzZWRvd25cIi5zcGxpdChcIiBcIikpO3ZhciBsZj1cImFib3J0IGNhbnBsYXkgY2FucGxheXRocm91Z2ggZHVyYXRpb25jaGFuZ2UgZW1wdGllZCBlbmNyeXB0ZWQgZW5kZWQgZXJyb3IgbG9hZGVkZGF0YSBsb2FkZWRtZXRhZGF0YSBsb2Fkc3RhcnQgcGF1c2UgcGxheSBwbGF5aW5nIHByb2dyZXNzIHJhdGVjaGFuZ2UgcmVzaXplIHNlZWtlZCBzZWVraW5nIHN0YWxsZWQgc3VzcGVuZCB0aW1ldXBkYXRlIHZvbHVtZWNoYW5nZSB3YWl0aW5nXCIuc3BsaXQoXCIgXCIpLG1mPW5ldyBTZXQoXCJjYW5jZWwgY2xvc2UgaW52YWxpZCBsb2FkIHNjcm9sbCB0b2dnbGVcIi5zcGxpdChcIiBcIikuY29uY2F0KGxmKSk7XG5mdW5jdGlvbiBuZihhLGIsYyl7dmFyIGQ9YS50eXBlfHxcInVua25vd24tZXZlbnRcIjthLmN1cnJlbnRUYXJnZXQ9YztVYihkLGIsdm9pZCAwLGEpO2EuY3VycmVudFRhcmdldD1udWxsfVxuZnVuY3Rpb24gc2UoYSxiKXtiPTAhPT0oYiY0KTtmb3IodmFyIGM9MDtjPGEubGVuZ3RoO2MrKyl7dmFyIGQ9YVtjXSxlPWQuZXZlbnQ7ZD1kLmxpc3RlbmVyczthOnt2YXIgZj12b2lkIDA7aWYoYilmb3IodmFyIGc9ZC5sZW5ndGgtMTswPD1nO2ctLSl7dmFyIGg9ZFtnXSxrPWguaW5zdGFuY2UsbD1oLmN1cnJlbnRUYXJnZXQ7aD1oLmxpc3RlbmVyO2lmKGshPT1mJiZlLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpYnJlYWsgYTtuZihlLGgsbCk7Zj1rfWVsc2UgZm9yKGc9MDtnPGQubGVuZ3RoO2crKyl7aD1kW2ddO2s9aC5pbnN0YW5jZTtsPWguY3VycmVudFRhcmdldDtoPWgubGlzdGVuZXI7aWYoayE9PWYmJmUuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSlicmVhayBhO25mKGUsaCxsKTtmPWt9fX1pZihRYil0aHJvdyBhPVJiLFFiPSExLFJiPW51bGwsYTt9XG5mdW5jdGlvbiBEKGEsYil7dmFyIGM9YltvZl07dm9pZCAwPT09YyYmKGM9YltvZl09bmV3IFNldCk7dmFyIGQ9YStcIl9fYnViYmxlXCI7Yy5oYXMoZCl8fChwZihiLGEsMiwhMSksYy5hZGQoZCkpfWZ1bmN0aW9uIHFmKGEsYixjKXt2YXIgZD0wO2ImJihkfD00KTtwZihjLGEsZCxiKX12YXIgcmY9XCJfcmVhY3RMaXN0ZW5pbmdcIitNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtmdW5jdGlvbiBzZihhKXtpZighYVtyZl0pe2FbcmZdPSEwO2RhLmZvckVhY2goZnVuY3Rpb24oYil7XCJzZWxlY3Rpb25jaGFuZ2VcIiE9PWImJihtZi5oYXMoYil8fHFmKGIsITEsYSkscWYoYiwhMCxhKSl9KTt2YXIgYj05PT09YS5ub2RlVHlwZT9hOmEub3duZXJEb2N1bWVudDtudWxsPT09Ynx8YltyZl18fChiW3JmXT0hMCxxZihcInNlbGVjdGlvbmNoYW5nZVwiLCExLGIpKX19XG5mdW5jdGlvbiBwZihhLGIsYyxkKXtzd2l0Y2goamQoYikpe2Nhc2UgMTp2YXIgZT1lZDticmVhaztjYXNlIDQ6ZT1nZDticmVhaztkZWZhdWx0OmU9ZmR9Yz1lLmJpbmQobnVsbCxiLGMsYSk7ZT12b2lkIDA7IUxifHxcInRvdWNoc3RhcnRcIiE9PWImJlwidG91Y2htb3ZlXCIhPT1iJiZcIndoZWVsXCIhPT1ifHwoZT0hMCk7ZD92b2lkIDAhPT1lP2EuYWRkRXZlbnRMaXN0ZW5lcihiLGMse2NhcHR1cmU6ITAscGFzc2l2ZTplfSk6YS5hZGRFdmVudExpc3RlbmVyKGIsYywhMCk6dm9pZCAwIT09ZT9hLmFkZEV2ZW50TGlzdGVuZXIoYixjLHtwYXNzaXZlOmV9KTphLmFkZEV2ZW50TGlzdGVuZXIoYixjLCExKX1cbmZ1bmN0aW9uIGhkKGEsYixjLGQsZSl7dmFyIGY9ZDtpZigwPT09KGImMSkmJjA9PT0oYiYyKSYmbnVsbCE9PWQpYTpmb3IoOzspe2lmKG51bGw9PT1kKXJldHVybjt2YXIgZz1kLnRhZztpZigzPT09Z3x8ND09PWcpe3ZhciBoPWQuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87aWYoaD09PWV8fDg9PT1oLm5vZGVUeXBlJiZoLnBhcmVudE5vZGU9PT1lKWJyZWFrO2lmKDQ9PT1nKWZvcihnPWQucmV0dXJuO251bGwhPT1nOyl7dmFyIGs9Zy50YWc7aWYoMz09PWt8fDQ9PT1rKWlmKGs9Zy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyxrPT09ZXx8OD09PWsubm9kZVR5cGUmJmsucGFyZW50Tm9kZT09PWUpcmV0dXJuO2c9Zy5yZXR1cm59Zm9yKDtudWxsIT09aDspe2c9V2MoaCk7aWYobnVsbD09PWcpcmV0dXJuO2s9Zy50YWc7aWYoNT09PWt8fDY9PT1rKXtkPWY9Zztjb250aW51ZSBhfWg9aC5wYXJlbnROb2RlfX1kPWQucmV0dXJufUpiKGZ1bmN0aW9uKCl7dmFyIGQ9ZixlPXhiKGMpLGc9W107XG5hOnt2YXIgaD1kZi5nZXQoYSk7aWYodm9pZCAwIT09aCl7dmFyIGs9dGQsbj1hO3N3aXRjaChhKXtjYXNlIFwia2V5cHJlc3NcIjppZigwPT09b2QoYykpYnJlYWsgYTtjYXNlIFwia2V5ZG93blwiOmNhc2UgXCJrZXl1cFwiOms9UmQ7YnJlYWs7Y2FzZSBcImZvY3VzaW5cIjpuPVwiZm9jdXNcIjtrPUZkO2JyZWFrO2Nhc2UgXCJmb2N1c291dFwiOm49XCJibHVyXCI7az1GZDticmVhaztjYXNlIFwiYmVmb3JlYmx1clwiOmNhc2UgXCJhZnRlcmJsdXJcIjprPUZkO2JyZWFrO2Nhc2UgXCJjbGlja1wiOmlmKDI9PT1jLmJ1dHRvbilicmVhayBhO2Nhc2UgXCJhdXhjbGlja1wiOmNhc2UgXCJkYmxjbGlja1wiOmNhc2UgXCJtb3VzZWRvd25cIjpjYXNlIFwibW91c2Vtb3ZlXCI6Y2FzZSBcIm1vdXNldXBcIjpjYXNlIFwibW91c2VvdXRcIjpjYXNlIFwibW91c2VvdmVyXCI6Y2FzZSBcImNvbnRleHRtZW51XCI6az1CZDticmVhaztjYXNlIFwiZHJhZ1wiOmNhc2UgXCJkcmFnZW5kXCI6Y2FzZSBcImRyYWdlbnRlclwiOmNhc2UgXCJkcmFnZXhpdFwiOmNhc2UgXCJkcmFnbGVhdmVcIjpjYXNlIFwiZHJhZ292ZXJcIjpjYXNlIFwiZHJhZ3N0YXJ0XCI6Y2FzZSBcImRyb3BcIjprPVxuRGQ7YnJlYWs7Y2FzZSBcInRvdWNoY2FuY2VsXCI6Y2FzZSBcInRvdWNoZW5kXCI6Y2FzZSBcInRvdWNobW92ZVwiOmNhc2UgXCJ0b3VjaHN0YXJ0XCI6az1WZDticmVhaztjYXNlICRlOmNhc2UgYWY6Y2FzZSBiZjprPUhkO2JyZWFrO2Nhc2UgY2Y6az1YZDticmVhaztjYXNlIFwic2Nyb2xsXCI6az12ZDticmVhaztjYXNlIFwid2hlZWxcIjprPVpkO2JyZWFrO2Nhc2UgXCJjb3B5XCI6Y2FzZSBcImN1dFwiOmNhc2UgXCJwYXN0ZVwiOms9SmQ7YnJlYWs7Y2FzZSBcImdvdHBvaW50ZXJjYXB0dXJlXCI6Y2FzZSBcImxvc3Rwb2ludGVyY2FwdHVyZVwiOmNhc2UgXCJwb2ludGVyY2FuY2VsXCI6Y2FzZSBcInBvaW50ZXJkb3duXCI6Y2FzZSBcInBvaW50ZXJtb3ZlXCI6Y2FzZSBcInBvaW50ZXJvdXRcIjpjYXNlIFwicG9pbnRlcm92ZXJcIjpjYXNlIFwicG9pbnRlcnVwXCI6az1UZH12YXIgdD0wIT09KGImNCksSj0hdCYmXCJzY3JvbGxcIj09PWEseD10P251bGwhPT1oP2grXCJDYXB0dXJlXCI6bnVsbDpoO3Q9W107Zm9yKHZhciB3PWQsdTtudWxsIT09XG53Oyl7dT13O3ZhciBGPXUuc3RhdGVOb2RlOzU9PT11LnRhZyYmbnVsbCE9PUYmJih1PUYsbnVsbCE9PXgmJihGPUtiKHcseCksbnVsbCE9RiYmdC5wdXNoKHRmKHcsRix1KSkpKTtpZihKKWJyZWFrO3c9dy5yZXR1cm59MDx0Lmxlbmd0aCYmKGg9bmV3IGsoaCxuLG51bGwsYyxlKSxnLnB1c2goe2V2ZW50OmgsbGlzdGVuZXJzOnR9KSl9fWlmKDA9PT0oYiY3KSl7YTp7aD1cIm1vdXNlb3ZlclwiPT09YXx8XCJwb2ludGVyb3ZlclwiPT09YTtrPVwibW91c2VvdXRcIj09PWF8fFwicG9pbnRlcm91dFwiPT09YTtpZihoJiZjIT09d2ImJihuPWMucmVsYXRlZFRhcmdldHx8Yy5mcm9tRWxlbWVudCkmJihXYyhuKXx8blt1Zl0pKWJyZWFrIGE7aWYoa3x8aCl7aD1lLndpbmRvdz09PWU/ZTooaD1lLm93bmVyRG9jdW1lbnQpP2guZGVmYXVsdFZpZXd8fGgucGFyZW50V2luZG93OndpbmRvdztpZihrKXtpZihuPWMucmVsYXRlZFRhcmdldHx8Yy50b0VsZW1lbnQsaz1kLG49bj9XYyhuKTpudWxsLG51bGwhPT1cbm4mJihKPVZiKG4pLG4hPT1KfHw1IT09bi50YWcmJjYhPT1uLnRhZykpbj1udWxsfWVsc2Ugaz1udWxsLG49ZDtpZihrIT09bil7dD1CZDtGPVwib25Nb3VzZUxlYXZlXCI7eD1cIm9uTW91c2VFbnRlclwiO3c9XCJtb3VzZVwiO2lmKFwicG9pbnRlcm91dFwiPT09YXx8XCJwb2ludGVyb3ZlclwiPT09YSl0PVRkLEY9XCJvblBvaW50ZXJMZWF2ZVwiLHg9XCJvblBvaW50ZXJFbnRlclwiLHc9XCJwb2ludGVyXCI7Sj1udWxsPT1rP2g6dWUoayk7dT1udWxsPT1uP2g6dWUobik7aD1uZXcgdChGLHcrXCJsZWF2ZVwiLGssYyxlKTtoLnRhcmdldD1KO2gucmVsYXRlZFRhcmdldD11O0Y9bnVsbDtXYyhlKT09PWQmJih0PW5ldyB0KHgsdytcImVudGVyXCIsbixjLGUpLHQudGFyZ2V0PXUsdC5yZWxhdGVkVGFyZ2V0PUosRj10KTtKPUY7aWYoayYmbiliOnt0PWs7eD1uO3c9MDtmb3IodT10O3U7dT12Zih1KSl3Kys7dT0wO2ZvcihGPXg7RjtGPXZmKEYpKXUrKztmb3IoOzA8dy11Oyl0PXZmKHQpLHctLTtmb3IoOzA8dS13Oyl4PVxudmYoeCksdS0tO2Zvcig7dy0tOyl7aWYodD09PXh8fG51bGwhPT14JiZ0PT09eC5hbHRlcm5hdGUpYnJlYWsgYjt0PXZmKHQpO3g9dmYoeCl9dD1udWxsfWVsc2UgdD1udWxsO251bGwhPT1rJiZ3ZihnLGgsayx0LCExKTtudWxsIT09biYmbnVsbCE9PUomJndmKGcsSixuLHQsITApfX19YTp7aD1kP3VlKGQpOndpbmRvdztrPWgubm9kZU5hbWUmJmgubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtpZihcInNlbGVjdFwiPT09a3x8XCJpbnB1dFwiPT09ayYmXCJmaWxlXCI9PT1oLnR5cGUpdmFyIG5hPXZlO2Vsc2UgaWYobWUoaCkpaWYod2UpbmE9RmU7ZWxzZXtuYT1EZTt2YXIgeGE9Q2V9ZWxzZShrPWgubm9kZU5hbWUpJiZcImlucHV0XCI9PT1rLnRvTG93ZXJDYXNlKCkmJihcImNoZWNrYm94XCI9PT1oLnR5cGV8fFwicmFkaW9cIj09PWgudHlwZSkmJihuYT1FZSk7aWYobmEmJihuYT1uYShhLGQpKSl7bmUoZyxuYSxjLGUpO2JyZWFrIGF9eGEmJnhhKGEsaCxkKTtcImZvY3Vzb3V0XCI9PT1hJiYoeGE9aC5fd3JhcHBlclN0YXRlKSYmXG54YS5jb250cm9sbGVkJiZcIm51bWJlclwiPT09aC50eXBlJiZjYihoLFwibnVtYmVyXCIsaC52YWx1ZSl9eGE9ZD91ZShkKTp3aW5kb3c7c3dpdGNoKGEpe2Nhc2UgXCJmb2N1c2luXCI6aWYobWUoeGEpfHxcInRydWVcIj09PXhhLmNvbnRlbnRFZGl0YWJsZSlRZT14YSxSZT1kLFNlPW51bGw7YnJlYWs7Y2FzZSBcImZvY3Vzb3V0XCI6U2U9UmU9UWU9bnVsbDticmVhaztjYXNlIFwibW91c2Vkb3duXCI6VGU9ITA7YnJlYWs7Y2FzZSBcImNvbnRleHRtZW51XCI6Y2FzZSBcIm1vdXNldXBcIjpjYXNlIFwiZHJhZ2VuZFwiOlRlPSExO1VlKGcsYyxlKTticmVhaztjYXNlIFwic2VsZWN0aW9uY2hhbmdlXCI6aWYoUGUpYnJlYWs7Y2FzZSBcImtleWRvd25cIjpjYXNlIFwia2V5dXBcIjpVZShnLGMsZSl9dmFyICRhO2lmKGFlKWI6e3N3aXRjaChhKXtjYXNlIFwiY29tcG9zaXRpb25zdGFydFwiOnZhciBiYT1cIm9uQ29tcG9zaXRpb25TdGFydFwiO2JyZWFrIGI7Y2FzZSBcImNvbXBvc2l0aW9uZW5kXCI6YmE9XCJvbkNvbXBvc2l0aW9uRW5kXCI7XG5icmVhayBiO2Nhc2UgXCJjb21wb3NpdGlvbnVwZGF0ZVwiOmJhPVwib25Db21wb3NpdGlvblVwZGF0ZVwiO2JyZWFrIGJ9YmE9dm9pZCAwfWVsc2UgaWU/Z2UoYSxjKSYmKGJhPVwib25Db21wb3NpdGlvbkVuZFwiKTpcImtleWRvd25cIj09PWEmJjIyOT09PWMua2V5Q29kZSYmKGJhPVwib25Db21wb3NpdGlvblN0YXJ0XCIpO2JhJiYoZGUmJlwia29cIiE9PWMubG9jYWxlJiYoaWV8fFwib25Db21wb3NpdGlvblN0YXJ0XCIhPT1iYT9cIm9uQ29tcG9zaXRpb25FbmRcIj09PWJhJiZpZSYmKCRhPW5kKCkpOihrZD1lLGxkPVwidmFsdWVcImluIGtkP2tkLnZhbHVlOmtkLnRleHRDb250ZW50LGllPSEwKSkseGE9b2UoZCxiYSksMDx4YS5sZW5ndGgmJihiYT1uZXcgTGQoYmEsYSxudWxsLGMsZSksZy5wdXNoKHtldmVudDpiYSxsaXN0ZW5lcnM6eGF9KSwkYT9iYS5kYXRhPSRhOigkYT1oZShjKSxudWxsIT09JGEmJihiYS5kYXRhPSRhKSkpKTtpZigkYT1jZT9qZShhLGMpOmtlKGEsYykpZD1vZShkLFwib25CZWZvcmVJbnB1dFwiKSxcbjA8ZC5sZW5ndGgmJihlPW5ldyBMZChcIm9uQmVmb3JlSW5wdXRcIixcImJlZm9yZWlucHV0XCIsbnVsbCxjLGUpLGcucHVzaCh7ZXZlbnQ6ZSxsaXN0ZW5lcnM6ZH0pLGUuZGF0YT0kYSl9c2UoZyxiKX0pfWZ1bmN0aW9uIHRmKGEsYixjKXtyZXR1cm57aW5zdGFuY2U6YSxsaXN0ZW5lcjpiLGN1cnJlbnRUYXJnZXQ6Y319ZnVuY3Rpb24gb2UoYSxiKXtmb3IodmFyIGM9YitcIkNhcHR1cmVcIixkPVtdO251bGwhPT1hOyl7dmFyIGU9YSxmPWUuc3RhdGVOb2RlOzU9PT1lLnRhZyYmbnVsbCE9PWYmJihlPWYsZj1LYihhLGMpLG51bGwhPWYmJmQudW5zaGlmdCh0ZihhLGYsZSkpLGY9S2IoYSxiKSxudWxsIT1mJiZkLnB1c2godGYoYSxmLGUpKSk7YT1hLnJldHVybn1yZXR1cm4gZH1mdW5jdGlvbiB2ZihhKXtpZihudWxsPT09YSlyZXR1cm4gbnVsbDtkbyBhPWEucmV0dXJuO3doaWxlKGEmJjUhPT1hLnRhZyk7cmV0dXJuIGE/YTpudWxsfVxuZnVuY3Rpb24gd2YoYSxiLGMsZCxlKXtmb3IodmFyIGY9Yi5fcmVhY3ROYW1lLGc9W107bnVsbCE9PWMmJmMhPT1kOyl7dmFyIGg9YyxrPWguYWx0ZXJuYXRlLGw9aC5zdGF0ZU5vZGU7aWYobnVsbCE9PWsmJms9PT1kKWJyZWFrOzU9PT1oLnRhZyYmbnVsbCE9PWwmJihoPWwsZT8oaz1LYihjLGYpLG51bGwhPWsmJmcudW5zaGlmdCh0ZihjLGssaCkpKTplfHwoaz1LYihjLGYpLG51bGwhPWsmJmcucHVzaCh0ZihjLGssaCkpKSk7Yz1jLnJldHVybn0wIT09Zy5sZW5ndGgmJmEucHVzaCh7ZXZlbnQ6YixsaXN0ZW5lcnM6Z30pfXZhciB4Zj0vXFxyXFxuPy9nLHlmPS9cXHUwMDAwfFxcdUZGRkQvZztmdW5jdGlvbiB6ZihhKXtyZXR1cm4oXCJzdHJpbmdcIj09PXR5cGVvZiBhP2E6XCJcIithKS5yZXBsYWNlKHhmLFwiXFxuXCIpLnJlcGxhY2UoeWYsXCJcIil9ZnVuY3Rpb24gQWYoYSxiLGMpe2I9emYoYik7aWYoemYoYSkhPT1iJiZjKXRocm93IEVycm9yKHAoNDI1KSk7fWZ1bmN0aW9uIEJmKCl7fVxudmFyIENmPW51bGwsRGY9bnVsbDtmdW5jdGlvbiBFZihhLGIpe3JldHVyblwidGV4dGFyZWFcIj09PWF8fFwibm9zY3JpcHRcIj09PWF8fFwic3RyaW5nXCI9PT10eXBlb2YgYi5jaGlsZHJlbnx8XCJudW1iZXJcIj09PXR5cGVvZiBiLmNoaWxkcmVufHxcIm9iamVjdFwiPT09dHlwZW9mIGIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwmJm51bGwhPT1iLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MJiZudWxsIT1iLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLl9faHRtbH1cbnZhciBGZj1cImZ1bmN0aW9uXCI9PT10eXBlb2Ygc2V0VGltZW91dD9zZXRUaW1lb3V0OnZvaWQgMCxHZj1cImZ1bmN0aW9uXCI9PT10eXBlb2YgY2xlYXJUaW1lb3V0P2NsZWFyVGltZW91dDp2b2lkIDAsSGY9XCJmdW5jdGlvblwiPT09dHlwZW9mIFByb21pc2U/UHJvbWlzZTp2b2lkIDAsSmY9XCJmdW5jdGlvblwiPT09dHlwZW9mIHF1ZXVlTWljcm90YXNrP3F1ZXVlTWljcm90YXNrOlwidW5kZWZpbmVkXCIhPT10eXBlb2YgSGY/ZnVuY3Rpb24oYSl7cmV0dXJuIEhmLnJlc29sdmUobnVsbCkudGhlbihhKS5jYXRjaChJZil9OkZmO2Z1bmN0aW9uIElmKGEpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXt0aHJvdyBhO30pfVxuZnVuY3Rpb24gS2YoYSxiKXt2YXIgYz1iLGQ9MDtkb3t2YXIgZT1jLm5leHRTaWJsaW5nO2EucmVtb3ZlQ2hpbGQoYyk7aWYoZSYmOD09PWUubm9kZVR5cGUpaWYoYz1lLmRhdGEsXCIvJFwiPT09Yyl7aWYoMD09PWQpe2EucmVtb3ZlQ2hpbGQoZSk7YmQoYik7cmV0dXJufWQtLX1lbHNlXCIkXCIhPT1jJiZcIiQ/XCIhPT1jJiZcIiQhXCIhPT1jfHxkKys7Yz1lfXdoaWxlKGMpO2JkKGIpfWZ1bmN0aW9uIExmKGEpe2Zvcig7bnVsbCE9YTthPWEubmV4dFNpYmxpbmcpe3ZhciBiPWEubm9kZVR5cGU7aWYoMT09PWJ8fDM9PT1iKWJyZWFrO2lmKDg9PT1iKXtiPWEuZGF0YTtpZihcIiRcIj09PWJ8fFwiJCFcIj09PWJ8fFwiJD9cIj09PWIpYnJlYWs7aWYoXCIvJFwiPT09YilyZXR1cm4gbnVsbH19cmV0dXJuIGF9XG5mdW5jdGlvbiBNZihhKXthPWEucHJldmlvdXNTaWJsaW5nO2Zvcih2YXIgYj0wO2E7KXtpZig4PT09YS5ub2RlVHlwZSl7dmFyIGM9YS5kYXRhO2lmKFwiJFwiPT09Y3x8XCIkIVwiPT09Y3x8XCIkP1wiPT09Yyl7aWYoMD09PWIpcmV0dXJuIGE7Yi0tfWVsc2VcIi8kXCI9PT1jJiZiKyt9YT1hLnByZXZpb3VzU2libGluZ31yZXR1cm4gbnVsbH12YXIgTmY9TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiksT2Y9XCJfX3JlYWN0RmliZXIkXCIrTmYsUGY9XCJfX3JlYWN0UHJvcHMkXCIrTmYsdWY9XCJfX3JlYWN0Q29udGFpbmVyJFwiK05mLG9mPVwiX19yZWFjdEV2ZW50cyRcIitOZixRZj1cIl9fcmVhY3RMaXN0ZW5lcnMkXCIrTmYsUmY9XCJfX3JlYWN0SGFuZGxlcyRcIitOZjtcbmZ1bmN0aW9uIFdjKGEpe3ZhciBiPWFbT2ZdO2lmKGIpcmV0dXJuIGI7Zm9yKHZhciBjPWEucGFyZW50Tm9kZTtjOyl7aWYoYj1jW3VmXXx8Y1tPZl0pe2M9Yi5hbHRlcm5hdGU7aWYobnVsbCE9PWIuY2hpbGR8fG51bGwhPT1jJiZudWxsIT09Yy5jaGlsZClmb3IoYT1NZihhKTtudWxsIT09YTspe2lmKGM9YVtPZl0pcmV0dXJuIGM7YT1NZihhKX1yZXR1cm4gYn1hPWM7Yz1hLnBhcmVudE5vZGV9cmV0dXJuIG51bGx9ZnVuY3Rpb24gQ2IoYSl7YT1hW09mXXx8YVt1Zl07cmV0dXJuIWF8fDUhPT1hLnRhZyYmNiE9PWEudGFnJiYxMyE9PWEudGFnJiYzIT09YS50YWc/bnVsbDphfWZ1bmN0aW9uIHVlKGEpe2lmKDU9PT1hLnRhZ3x8Nj09PWEudGFnKXJldHVybiBhLnN0YXRlTm9kZTt0aHJvdyBFcnJvcihwKDMzKSk7fWZ1bmN0aW9uIERiKGEpe3JldHVybiBhW1BmXXx8bnVsbH12YXIgU2Y9W10sVGY9LTE7ZnVuY3Rpb24gVWYoYSl7cmV0dXJue2N1cnJlbnQ6YX19XG5mdW5jdGlvbiBFKGEpezA+VGZ8fChhLmN1cnJlbnQ9U2ZbVGZdLFNmW1RmXT1udWxsLFRmLS0pfWZ1bmN0aW9uIEcoYSxiKXtUZisrO1NmW1RmXT1hLmN1cnJlbnQ7YS5jdXJyZW50PWJ9dmFyIFZmPXt9LEg9VWYoVmYpLFdmPVVmKCExKSxYZj1WZjtmdW5jdGlvbiBZZihhLGIpe3ZhciBjPWEudHlwZS5jb250ZXh0VHlwZXM7aWYoIWMpcmV0dXJuIFZmO3ZhciBkPWEuc3RhdGVOb2RlO2lmKGQmJmQuX19yZWFjdEludGVybmFsTWVtb2l6ZWRVbm1hc2tlZENoaWxkQ29udGV4dD09PWIpcmV0dXJuIGQuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNYXNrZWRDaGlsZENvbnRleHQ7dmFyIGU9e30sZjtmb3IoZiBpbiBjKWVbZl09YltmXTtkJiYoYT1hLnN0YXRlTm9kZSxhLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkVW5tYXNrZWRDaGlsZENvbnRleHQ9YixhLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWFza2VkQ2hpbGRDb250ZXh0PWUpO3JldHVybiBlfVxuZnVuY3Rpb24gWmYoYSl7YT1hLmNoaWxkQ29udGV4dFR5cGVzO3JldHVybiBudWxsIT09YSYmdm9pZCAwIT09YX1mdW5jdGlvbiAkZigpe0UoV2YpO0UoSCl9ZnVuY3Rpb24gYWcoYSxiLGMpe2lmKEguY3VycmVudCE9PVZmKXRocm93IEVycm9yKHAoMTY4KSk7RyhILGIpO0coV2YsYyl9ZnVuY3Rpb24gYmcoYSxiLGMpe3ZhciBkPWEuc3RhdGVOb2RlO2I9Yi5jaGlsZENvbnRleHRUeXBlcztpZihcImZ1bmN0aW9uXCIhPT10eXBlb2YgZC5nZXRDaGlsZENvbnRleHQpcmV0dXJuIGM7ZD1kLmdldENoaWxkQ29udGV4dCgpO2Zvcih2YXIgZSBpbiBkKWlmKCEoZSBpbiBiKSl0aHJvdyBFcnJvcihwKDEwOCxSYShhKXx8XCJVbmtub3duXCIsZSkpO3JldHVybiBBKHt9LGMsZCl9XG5mdW5jdGlvbiBjZyhhKXthPShhPWEuc3RhdGVOb2RlKSYmYS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dHx8VmY7WGY9SC5jdXJyZW50O0coSCxhKTtHKFdmLFdmLmN1cnJlbnQpO3JldHVybiEwfWZ1bmN0aW9uIGRnKGEsYixjKXt2YXIgZD1hLnN0YXRlTm9kZTtpZighZCl0aHJvdyBFcnJvcihwKDE2OSkpO2M/KGE9YmcoYSxiLFhmKSxkLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0PWEsRShXZiksRShIKSxHKEgsYSkpOkUoV2YpO0coV2YsYyl9dmFyIGVnPW51bGwsZmc9ITEsZ2c9ITE7ZnVuY3Rpb24gaGcoYSl7bnVsbD09PWVnP2VnPVthXTplZy5wdXNoKGEpfWZ1bmN0aW9uIGlnKGEpe2ZnPSEwO2hnKGEpfVxuZnVuY3Rpb24gamcoKXtpZighZ2cmJm51bGwhPT1lZyl7Z2c9ITA7dmFyIGE9MCxiPUM7dHJ5e3ZhciBjPWVnO2ZvcihDPTE7YTxjLmxlbmd0aDthKyspe3ZhciBkPWNbYV07ZG8gZD1kKCEwKTt3aGlsZShudWxsIT09ZCl9ZWc9bnVsbDtmZz0hMX1jYXRjaChlKXt0aHJvdyBudWxsIT09ZWcmJihlZz1lZy5zbGljZShhKzEpKSxhYyhmYyxqZyksZTt9ZmluYWxseXtDPWIsZ2c9ITF9fXJldHVybiBudWxsfXZhciBrZz1bXSxsZz0wLG1nPW51bGwsbmc9MCxvZz1bXSxwZz0wLHFnPW51bGwscmc9MSxzZz1cIlwiO2Z1bmN0aW9uIHRnKGEsYil7a2dbbGcrK109bmc7a2dbbGcrK109bWc7bWc9YTtuZz1ifVxuZnVuY3Rpb24gdWcoYSxiLGMpe29nW3BnKytdPXJnO29nW3BnKytdPXNnO29nW3BnKytdPXFnO3FnPWE7dmFyIGQ9cmc7YT1zZzt2YXIgZT0zMi1vYyhkKS0xO2QmPX4oMTw8ZSk7Yys9MTt2YXIgZj0zMi1vYyhiKStlO2lmKDMwPGYpe3ZhciBnPWUtZSU1O2Y9KGQmKDE8PGcpLTEpLnRvU3RyaW5nKDMyKTtkPj49ZztlLT1nO3JnPTE8PDMyLW9jKGIpK2V8Yzw8ZXxkO3NnPWYrYX1lbHNlIHJnPTE8PGZ8Yzw8ZXxkLHNnPWF9ZnVuY3Rpb24gdmcoYSl7bnVsbCE9PWEucmV0dXJuJiYodGcoYSwxKSx1ZyhhLDEsMCkpfWZ1bmN0aW9uIHdnKGEpe2Zvcig7YT09PW1nOyltZz1rZ1stLWxnXSxrZ1tsZ109bnVsbCxuZz1rZ1stLWxnXSxrZ1tsZ109bnVsbDtmb3IoO2E9PT1xZzspcWc9b2dbLS1wZ10sb2dbcGddPW51bGwsc2c9b2dbLS1wZ10sb2dbcGddPW51bGwscmc9b2dbLS1wZ10sb2dbcGddPW51bGx9dmFyIHhnPW51bGwseWc9bnVsbCxJPSExLHpnPW51bGw7XG5mdW5jdGlvbiBBZyhhLGIpe3ZhciBjPUJnKDUsbnVsbCxudWxsLDApO2MuZWxlbWVudFR5cGU9XCJERUxFVEVEXCI7Yy5zdGF0ZU5vZGU9YjtjLnJldHVybj1hO2I9YS5kZWxldGlvbnM7bnVsbD09PWI/KGEuZGVsZXRpb25zPVtjXSxhLmZsYWdzfD0xNik6Yi5wdXNoKGMpfVxuZnVuY3Rpb24gQ2coYSxiKXtzd2l0Y2goYS50YWcpe2Nhc2UgNTp2YXIgYz1hLnR5cGU7Yj0xIT09Yi5ub2RlVHlwZXx8Yy50b0xvd2VyQ2FzZSgpIT09Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpP251bGw6YjtyZXR1cm4gbnVsbCE9PWI/KGEuc3RhdGVOb2RlPWIseGc9YSx5Zz1MZihiLmZpcnN0Q2hpbGQpLCEwKTohMTtjYXNlIDY6cmV0dXJuIGI9XCJcIj09PWEucGVuZGluZ1Byb3BzfHwzIT09Yi5ub2RlVHlwZT9udWxsOmIsbnVsbCE9PWI/KGEuc3RhdGVOb2RlPWIseGc9YSx5Zz1udWxsLCEwKTohMTtjYXNlIDEzOnJldHVybiBiPTghPT1iLm5vZGVUeXBlP251bGw6YixudWxsIT09Yj8oYz1udWxsIT09cWc/e2lkOnJnLG92ZXJmbG93OnNnfTpudWxsLGEubWVtb2l6ZWRTdGF0ZT17ZGVoeWRyYXRlZDpiLHRyZWVDb250ZXh0OmMscmV0cnlMYW5lOjEwNzM3NDE4MjR9LGM9QmcoMTgsbnVsbCxudWxsLDApLGMuc3RhdGVOb2RlPWIsYy5yZXR1cm49YSxhLmNoaWxkPWMseGc9YSx5Zz1cbm51bGwsITApOiExO2RlZmF1bHQ6cmV0dXJuITF9fWZ1bmN0aW9uIERnKGEpe3JldHVybiAwIT09KGEubW9kZSYxKSYmMD09PShhLmZsYWdzJjEyOCl9ZnVuY3Rpb24gRWcoYSl7aWYoSSl7dmFyIGI9eWc7aWYoYil7dmFyIGM9YjtpZighQ2coYSxiKSl7aWYoRGcoYSkpdGhyb3cgRXJyb3IocCg0MTgpKTtiPUxmKGMubmV4dFNpYmxpbmcpO3ZhciBkPXhnO2ImJkNnKGEsYik/QWcoZCxjKTooYS5mbGFncz1hLmZsYWdzJi00MDk3fDIsST0hMSx4Zz1hKX19ZWxzZXtpZihEZyhhKSl0aHJvdyBFcnJvcihwKDQxOCkpO2EuZmxhZ3M9YS5mbGFncyYtNDA5N3wyO0k9ITE7eGc9YX19fWZ1bmN0aW9uIEZnKGEpe2ZvcihhPWEucmV0dXJuO251bGwhPT1hJiY1IT09YS50YWcmJjMhPT1hLnRhZyYmMTMhPT1hLnRhZzspYT1hLnJldHVybjt4Zz1hfVxuZnVuY3Rpb24gR2coYSl7aWYoYSE9PXhnKXJldHVybiExO2lmKCFJKXJldHVybiBGZyhhKSxJPSEwLCExO3ZhciBiOyhiPTMhPT1hLnRhZykmJiEoYj01IT09YS50YWcpJiYoYj1hLnR5cGUsYj1cImhlYWRcIiE9PWImJlwiYm9keVwiIT09YiYmIUVmKGEudHlwZSxhLm1lbW9pemVkUHJvcHMpKTtpZihiJiYoYj15Zykpe2lmKERnKGEpKXRocm93IEhnKCksRXJyb3IocCg0MTgpKTtmb3IoO2I7KUFnKGEsYiksYj1MZihiLm5leHRTaWJsaW5nKX1GZyhhKTtpZigxMz09PWEudGFnKXthPWEubWVtb2l6ZWRTdGF0ZTthPW51bGwhPT1hP2EuZGVoeWRyYXRlZDpudWxsO2lmKCFhKXRocm93IEVycm9yKHAoMzE3KSk7YTp7YT1hLm5leHRTaWJsaW5nO2ZvcihiPTA7YTspe2lmKDg9PT1hLm5vZGVUeXBlKXt2YXIgYz1hLmRhdGE7aWYoXCIvJFwiPT09Yyl7aWYoMD09PWIpe3lnPUxmKGEubmV4dFNpYmxpbmcpO2JyZWFrIGF9Yi0tfWVsc2VcIiRcIiE9PWMmJlwiJCFcIiE9PWMmJlwiJD9cIiE9PWN8fGIrK31hPWEubmV4dFNpYmxpbmd9eWc9XG5udWxsfX1lbHNlIHlnPXhnP0xmKGEuc3RhdGVOb2RlLm5leHRTaWJsaW5nKTpudWxsO3JldHVybiEwfWZ1bmN0aW9uIEhnKCl7Zm9yKHZhciBhPXlnO2E7KWE9TGYoYS5uZXh0U2libGluZyl9ZnVuY3Rpb24gSWcoKXt5Zz14Zz1udWxsO0k9ITF9ZnVuY3Rpb24gSmcoYSl7bnVsbD09PXpnP3pnPVthXTp6Zy5wdXNoKGEpfXZhciBLZz11YS5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZztmdW5jdGlvbiBMZyhhLGIpe2lmKGEmJmEuZGVmYXVsdFByb3BzKXtiPUEoe30sYik7YT1hLmRlZmF1bHRQcm9wcztmb3IodmFyIGMgaW4gYSl2b2lkIDA9PT1iW2NdJiYoYltjXT1hW2NdKTtyZXR1cm4gYn1yZXR1cm4gYn12YXIgTWc9VWYobnVsbCksTmc9bnVsbCxPZz1udWxsLFBnPW51bGw7ZnVuY3Rpb24gUWcoKXtQZz1PZz1OZz1udWxsfWZ1bmN0aW9uIFJnKGEpe3ZhciBiPU1nLmN1cnJlbnQ7RShNZyk7YS5fY3VycmVudFZhbHVlPWJ9XG5mdW5jdGlvbiBTZyhhLGIsYyl7Zm9yKDtudWxsIT09YTspe3ZhciBkPWEuYWx0ZXJuYXRlOyhhLmNoaWxkTGFuZXMmYikhPT1iPyhhLmNoaWxkTGFuZXN8PWIsbnVsbCE9PWQmJihkLmNoaWxkTGFuZXN8PWIpKTpudWxsIT09ZCYmKGQuY2hpbGRMYW5lcyZiKSE9PWImJihkLmNoaWxkTGFuZXN8PWIpO2lmKGE9PT1jKWJyZWFrO2E9YS5yZXR1cm59fWZ1bmN0aW9uIFRnKGEsYil7Tmc9YTtQZz1PZz1udWxsO2E9YS5kZXBlbmRlbmNpZXM7bnVsbCE9PWEmJm51bGwhPT1hLmZpcnN0Q29udGV4dCYmKDAhPT0oYS5sYW5lcyZiKSYmKFVnPSEwKSxhLmZpcnN0Q29udGV4dD1udWxsKX1cbmZ1bmN0aW9uIFZnKGEpe3ZhciBiPWEuX2N1cnJlbnRWYWx1ZTtpZihQZyE9PWEpaWYoYT17Y29udGV4dDphLG1lbW9pemVkVmFsdWU6YixuZXh0Om51bGx9LG51bGw9PT1PZyl7aWYobnVsbD09PU5nKXRocm93IEVycm9yKHAoMzA4KSk7T2c9YTtOZy5kZXBlbmRlbmNpZXM9e2xhbmVzOjAsZmlyc3RDb250ZXh0OmF9fWVsc2UgT2c9T2cubmV4dD1hO3JldHVybiBifXZhciBXZz1udWxsO2Z1bmN0aW9uIFhnKGEpe251bGw9PT1XZz9XZz1bYV06V2cucHVzaChhKX1mdW5jdGlvbiBZZyhhLGIsYyxkKXt2YXIgZT1iLmludGVybGVhdmVkO251bGw9PT1lPyhjLm5leHQ9YyxYZyhiKSk6KGMubmV4dD1lLm5leHQsZS5uZXh0PWMpO2IuaW50ZXJsZWF2ZWQ9YztyZXR1cm4gWmcoYSxkKX1cbmZ1bmN0aW9uIFpnKGEsYil7YS5sYW5lc3w9Yjt2YXIgYz1hLmFsdGVybmF0ZTtudWxsIT09YyYmKGMubGFuZXN8PWIpO2M9YTtmb3IoYT1hLnJldHVybjtudWxsIT09YTspYS5jaGlsZExhbmVzfD1iLGM9YS5hbHRlcm5hdGUsbnVsbCE9PWMmJihjLmNoaWxkTGFuZXN8PWIpLGM9YSxhPWEucmV0dXJuO3JldHVybiAzPT09Yy50YWc/Yy5zdGF0ZU5vZGU6bnVsbH12YXIgJGc9ITE7ZnVuY3Rpb24gYWgoYSl7YS51cGRhdGVRdWV1ZT17YmFzZVN0YXRlOmEubWVtb2l6ZWRTdGF0ZSxmaXJzdEJhc2VVcGRhdGU6bnVsbCxsYXN0QmFzZVVwZGF0ZTpudWxsLHNoYXJlZDp7cGVuZGluZzpudWxsLGludGVybGVhdmVkOm51bGwsbGFuZXM6MH0sZWZmZWN0czpudWxsfX1cbmZ1bmN0aW9uIGJoKGEsYil7YT1hLnVwZGF0ZVF1ZXVlO2IudXBkYXRlUXVldWU9PT1hJiYoYi51cGRhdGVRdWV1ZT17YmFzZVN0YXRlOmEuYmFzZVN0YXRlLGZpcnN0QmFzZVVwZGF0ZTphLmZpcnN0QmFzZVVwZGF0ZSxsYXN0QmFzZVVwZGF0ZTphLmxhc3RCYXNlVXBkYXRlLHNoYXJlZDphLnNoYXJlZCxlZmZlY3RzOmEuZWZmZWN0c30pfWZ1bmN0aW9uIGNoKGEsYil7cmV0dXJue2V2ZW50VGltZTphLGxhbmU6Yix0YWc6MCxwYXlsb2FkOm51bGwsY2FsbGJhY2s6bnVsbCxuZXh0Om51bGx9fVxuZnVuY3Rpb24gZGgoYSxiLGMpe3ZhciBkPWEudXBkYXRlUXVldWU7aWYobnVsbD09PWQpcmV0dXJuIG51bGw7ZD1kLnNoYXJlZDtpZigwIT09KEsmMikpe3ZhciBlPWQucGVuZGluZztudWxsPT09ZT9iLm5leHQ9YjooYi5uZXh0PWUubmV4dCxlLm5leHQ9Yik7ZC5wZW5kaW5nPWI7cmV0dXJuIFpnKGEsYyl9ZT1kLmludGVybGVhdmVkO251bGw9PT1lPyhiLm5leHQ9YixYZyhkKSk6KGIubmV4dD1lLm5leHQsZS5uZXh0PWIpO2QuaW50ZXJsZWF2ZWQ9YjtyZXR1cm4gWmcoYSxjKX1mdW5jdGlvbiBlaChhLGIsYyl7Yj1iLnVwZGF0ZVF1ZXVlO2lmKG51bGwhPT1iJiYoYj1iLnNoYXJlZCwwIT09KGMmNDE5NDI0MCkpKXt2YXIgZD1iLmxhbmVzO2QmPWEucGVuZGluZ0xhbmVzO2N8PWQ7Yi5sYW5lcz1jO0NjKGEsYyl9fVxuZnVuY3Rpb24gZmgoYSxiKXt2YXIgYz1hLnVwZGF0ZVF1ZXVlLGQ9YS5hbHRlcm5hdGU7aWYobnVsbCE9PWQmJihkPWQudXBkYXRlUXVldWUsYz09PWQpKXt2YXIgZT1udWxsLGY9bnVsbDtjPWMuZmlyc3RCYXNlVXBkYXRlO2lmKG51bGwhPT1jKXtkb3t2YXIgZz17ZXZlbnRUaW1lOmMuZXZlbnRUaW1lLGxhbmU6Yy5sYW5lLHRhZzpjLnRhZyxwYXlsb2FkOmMucGF5bG9hZCxjYWxsYmFjazpjLmNhbGxiYWNrLG5leHQ6bnVsbH07bnVsbD09PWY/ZT1mPWc6Zj1mLm5leHQ9ZztjPWMubmV4dH13aGlsZShudWxsIT09Yyk7bnVsbD09PWY/ZT1mPWI6Zj1mLm5leHQ9Yn1lbHNlIGU9Zj1iO2M9e2Jhc2VTdGF0ZTpkLmJhc2VTdGF0ZSxmaXJzdEJhc2VVcGRhdGU6ZSxsYXN0QmFzZVVwZGF0ZTpmLHNoYXJlZDpkLnNoYXJlZCxlZmZlY3RzOmQuZWZmZWN0c307YS51cGRhdGVRdWV1ZT1jO3JldHVybn1hPWMubGFzdEJhc2VVcGRhdGU7bnVsbD09PWE/Yy5maXJzdEJhc2VVcGRhdGU9YjphLm5leHQ9XG5iO2MubGFzdEJhc2VVcGRhdGU9Yn1cbmZ1bmN0aW9uIGdoKGEsYixjLGQpe3ZhciBlPWEudXBkYXRlUXVldWU7JGc9ITE7dmFyIGY9ZS5maXJzdEJhc2VVcGRhdGUsZz1lLmxhc3RCYXNlVXBkYXRlLGg9ZS5zaGFyZWQucGVuZGluZztpZihudWxsIT09aCl7ZS5zaGFyZWQucGVuZGluZz1udWxsO3ZhciBrPWgsbD1rLm5leHQ7ay5uZXh0PW51bGw7bnVsbD09PWc/Zj1sOmcubmV4dD1sO2c9azt2YXIgbT1hLmFsdGVybmF0ZTtudWxsIT09bSYmKG09bS51cGRhdGVRdWV1ZSxoPW0ubGFzdEJhc2VVcGRhdGUsaCE9PWcmJihudWxsPT09aD9tLmZpcnN0QmFzZVVwZGF0ZT1sOmgubmV4dD1sLG0ubGFzdEJhc2VVcGRhdGU9aykpfWlmKG51bGwhPT1mKXt2YXIgcT1lLmJhc2VTdGF0ZTtnPTA7bT1sPWs9bnVsbDtoPWY7ZG97dmFyIHI9aC5sYW5lLHk9aC5ldmVudFRpbWU7aWYoKGQmcik9PT1yKXtudWxsIT09bSYmKG09bS5uZXh0PXtldmVudFRpbWU6eSxsYW5lOjAsdGFnOmgudGFnLHBheWxvYWQ6aC5wYXlsb2FkLGNhbGxiYWNrOmguY2FsbGJhY2ssXG5uZXh0Om51bGx9KTthOnt2YXIgbj1hLHQ9aDtyPWI7eT1jO3N3aXRjaCh0LnRhZyl7Y2FzZSAxOm49dC5wYXlsb2FkO2lmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBuKXtxPW4uY2FsbCh5LHEscik7YnJlYWsgYX1xPW47YnJlYWsgYTtjYXNlIDM6bi5mbGFncz1uLmZsYWdzJi02NTUzN3wxMjg7Y2FzZSAwOm49dC5wYXlsb2FkO3I9XCJmdW5jdGlvblwiPT09dHlwZW9mIG4/bi5jYWxsKHkscSxyKTpuO2lmKG51bGw9PT1yfHx2b2lkIDA9PT1yKWJyZWFrIGE7cT1BKHt9LHEscik7YnJlYWsgYTtjYXNlIDI6JGc9ITB9fW51bGwhPT1oLmNhbGxiYWNrJiYwIT09aC5sYW5lJiYoYS5mbGFnc3w9NjQscj1lLmVmZmVjdHMsbnVsbD09PXI/ZS5lZmZlY3RzPVtoXTpyLnB1c2goaCkpfWVsc2UgeT17ZXZlbnRUaW1lOnksbGFuZTpyLHRhZzpoLnRhZyxwYXlsb2FkOmgucGF5bG9hZCxjYWxsYmFjazpoLmNhbGxiYWNrLG5leHQ6bnVsbH0sbnVsbD09PW0/KGw9bT15LGs9cSk6bT1tLm5leHQ9eSxnfD1yO1xuaD1oLm5leHQ7aWYobnVsbD09PWgpaWYoaD1lLnNoYXJlZC5wZW5kaW5nLG51bGw9PT1oKWJyZWFrO2Vsc2Ugcj1oLGg9ci5uZXh0LHIubmV4dD1udWxsLGUubGFzdEJhc2VVcGRhdGU9cixlLnNoYXJlZC5wZW5kaW5nPW51bGx9d2hpbGUoMSk7bnVsbD09PW0mJihrPXEpO2UuYmFzZVN0YXRlPWs7ZS5maXJzdEJhc2VVcGRhdGU9bDtlLmxhc3RCYXNlVXBkYXRlPW07Yj1lLnNoYXJlZC5pbnRlcmxlYXZlZDtpZihudWxsIT09Yil7ZT1iO2RvIGd8PWUubGFuZSxlPWUubmV4dDt3aGlsZShlIT09Yil9ZWxzZSBudWxsPT09ZiYmKGUuc2hhcmVkLmxhbmVzPTApO2hofD1nO2EubGFuZXM9ZzthLm1lbW9pemVkU3RhdGU9cX19XG5mdW5jdGlvbiBpaChhLGIsYyl7YT1iLmVmZmVjdHM7Yi5lZmZlY3RzPW51bGw7aWYobnVsbCE9PWEpZm9yKGI9MDtiPGEubGVuZ3RoO2IrKyl7dmFyIGQ9YVtiXSxlPWQuY2FsbGJhY2s7aWYobnVsbCE9PWUpe2QuY2FsbGJhY2s9bnVsbDtkPWM7aWYoXCJmdW5jdGlvblwiIT09dHlwZW9mIGUpdGhyb3cgRXJyb3IocCgxOTEsZSkpO2UuY2FsbChkKX19fXZhciBqaD0obmV3IGFhLkNvbXBvbmVudCkucmVmcztmdW5jdGlvbiBraChhLGIsYyxkKXtiPWEubWVtb2l6ZWRTdGF0ZTtjPWMoZCxiKTtjPW51bGw9PT1jfHx2b2lkIDA9PT1jP2I6QSh7fSxiLGMpO2EubWVtb2l6ZWRTdGF0ZT1jOzA9PT1hLmxhbmVzJiYoYS51cGRhdGVRdWV1ZS5iYXNlU3RhdGU9Yyl9XG52YXIgbmg9e2lzTW91bnRlZDpmdW5jdGlvbihhKXtyZXR1cm4oYT1hLl9yZWFjdEludGVybmFscyk/VmIoYSk9PT1hOiExfSxlbnF1ZXVlU2V0U3RhdGU6ZnVuY3Rpb24oYSxiLGMpe2E9YS5fcmVhY3RJbnRlcm5hbHM7dmFyIGQ9TCgpLGU9bGgoYSksZj1jaChkLGUpO2YucGF5bG9hZD1iO3ZvaWQgMCE9PWMmJm51bGwhPT1jJiYoZi5jYWxsYmFjaz1jKTtiPWRoKGEsZixlKTtudWxsIT09YiYmKG1oKGIsYSxlLGQpLGVoKGIsYSxlKSl9LGVucXVldWVSZXBsYWNlU3RhdGU6ZnVuY3Rpb24oYSxiLGMpe2E9YS5fcmVhY3RJbnRlcm5hbHM7dmFyIGQ9TCgpLGU9bGgoYSksZj1jaChkLGUpO2YudGFnPTE7Zi5wYXlsb2FkPWI7dm9pZCAwIT09YyYmbnVsbCE9PWMmJihmLmNhbGxiYWNrPWMpO2I9ZGgoYSxmLGUpO251bGwhPT1iJiYobWgoYixhLGUsZCksZWgoYixhLGUpKX0sZW5xdWV1ZUZvcmNlVXBkYXRlOmZ1bmN0aW9uKGEsYil7YT1hLl9yZWFjdEludGVybmFsczt2YXIgYz1MKCksZD1cbmxoKGEpLGU9Y2goYyxkKTtlLnRhZz0yO3ZvaWQgMCE9PWImJm51bGwhPT1iJiYoZS5jYWxsYmFjaz1iKTtiPWRoKGEsZSxkKTtudWxsIT09YiYmKG1oKGIsYSxkLGMpLGVoKGIsYSxkKSl9fTtmdW5jdGlvbiBvaChhLGIsYyxkLGUsZixnKXthPWEuc3RhdGVOb2RlO3JldHVyblwiZnVuY3Rpb25cIj09PXR5cGVvZiBhLnNob3VsZENvbXBvbmVudFVwZGF0ZT9hLnNob3VsZENvbXBvbmVudFVwZGF0ZShkLGYsZyk6Yi5wcm90b3R5cGUmJmIucHJvdG90eXBlLmlzUHVyZVJlYWN0Q29tcG9uZW50PyFJZShjLGQpfHwhSWUoZSxmKTohMH1cbmZ1bmN0aW9uIHBoKGEsYixjKXt2YXIgZD0hMSxlPVZmO3ZhciBmPWIuY29udGV4dFR5cGU7XCJvYmplY3RcIj09PXR5cGVvZiBmJiZudWxsIT09Zj9mPVZnKGYpOihlPVpmKGIpP1hmOkguY3VycmVudCxkPWIuY29udGV4dFR5cGVzLGY9KGQ9bnVsbCE9PWQmJnZvaWQgMCE9PWQpP1lmKGEsZSk6VmYpO2I9bmV3IGIoYyxmKTthLm1lbW9pemVkU3RhdGU9bnVsbCE9PWIuc3RhdGUmJnZvaWQgMCE9PWIuc3RhdGU/Yi5zdGF0ZTpudWxsO2IudXBkYXRlcj1uaDthLnN0YXRlTm9kZT1iO2IuX3JlYWN0SW50ZXJuYWxzPWE7ZCYmKGE9YS5zdGF0ZU5vZGUsYS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZFVubWFza2VkQ2hpbGRDb250ZXh0PWUsYS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1hc2tlZENoaWxkQ29udGV4dD1mKTtyZXR1cm4gYn1cbmZ1bmN0aW9uIHFoKGEsYixjLGQpe2E9Yi5zdGF0ZTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJiZiLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoYyxkKTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyYmYi5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhjLGQpO2Iuc3RhdGUhPT1hJiZuaC5lbnF1ZXVlUmVwbGFjZVN0YXRlKGIsYi5zdGF0ZSxudWxsKX1cbmZ1bmN0aW9uIHJoKGEsYixjLGQpe3ZhciBlPWEuc3RhdGVOb2RlO2UucHJvcHM9YztlLnN0YXRlPWEubWVtb2l6ZWRTdGF0ZTtlLnJlZnM9amg7YWgoYSk7dmFyIGY9Yi5jb250ZXh0VHlwZTtcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mP2UuY29udGV4dD1WZyhmKTooZj1aZihiKT9YZjpILmN1cnJlbnQsZS5jb250ZXh0PVlmKGEsZikpO2Uuc3RhdGU9YS5tZW1vaXplZFN0YXRlO2Y9Yi5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHM7XCJmdW5jdGlvblwiPT09dHlwZW9mIGYmJihraChhLGIsZixjKSxlLnN0YXRlPWEubWVtb2l6ZWRTdGF0ZSk7XCJmdW5jdGlvblwiPT09dHlwZW9mIGIuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzfHxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZXx8XCJmdW5jdGlvblwiIT09dHlwZW9mIGUuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCYmXCJmdW5jdGlvblwiIT09dHlwZW9mIGUuY29tcG9uZW50V2lsbE1vdW50fHwoYj1lLnN0YXRlLFxuXCJmdW5jdGlvblwiPT09dHlwZW9mIGUuY29tcG9uZW50V2lsbE1vdW50JiZlLmNvbXBvbmVudFdpbGxNb3VudCgpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQmJmUuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpLGIhPT1lLnN0YXRlJiZuaC5lbnF1ZXVlUmVwbGFjZVN0YXRlKGUsZS5zdGF0ZSxudWxsKSxnaChhLGMsZSxkKSxlLnN0YXRlPWEubWVtb2l6ZWRTdGF0ZSk7XCJmdW5jdGlvblwiPT09dHlwZW9mIGUuY29tcG9uZW50RGlkTW91bnQmJihhLmZsYWdzfD00MTk0MzA4KX1cbmZ1bmN0aW9uIHNoKGEsYixjKXthPWMucmVmO2lmKG51bGwhPT1hJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgYSYmXCJvYmplY3RcIiE9PXR5cGVvZiBhKXtpZihjLl9vd25lcil7Yz1jLl9vd25lcjtpZihjKXtpZigxIT09Yy50YWcpdGhyb3cgRXJyb3IocCgzMDkpKTt2YXIgZD1jLnN0YXRlTm9kZX1pZighZCl0aHJvdyBFcnJvcihwKDE0NyxhKSk7dmFyIGU9ZCxmPVwiXCIrYTtpZihudWxsIT09YiYmbnVsbCE9PWIucmVmJiZcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi5yZWYmJmIucmVmLl9zdHJpbmdSZWY9PT1mKXJldHVybiBiLnJlZjtiPWZ1bmN0aW9uKGEpe3ZhciBiPWUucmVmcztiPT09amgmJihiPWUucmVmcz17fSk7bnVsbD09PWE/ZGVsZXRlIGJbZl06YltmXT1hfTtiLl9zdHJpbmdSZWY9ZjtyZXR1cm4gYn1pZihcInN0cmluZ1wiIT09dHlwZW9mIGEpdGhyb3cgRXJyb3IocCgyODQpKTtpZighYy5fb3duZXIpdGhyb3cgRXJyb3IocCgyOTAsYSkpO31yZXR1cm4gYX1cbmZ1bmN0aW9uIHRoKGEsYil7YT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYik7dGhyb3cgRXJyb3IocCgzMSxcIltvYmplY3QgT2JqZWN0XVwiPT09YT9cIm9iamVjdCB3aXRoIGtleXMge1wiK09iamVjdC5rZXlzKGIpLmpvaW4oXCIsIFwiKStcIn1cIjphKSk7fWZ1bmN0aW9uIHVoKGEpe3ZhciBiPWEuX2luaXQ7cmV0dXJuIGIoYS5fcGF5bG9hZCl9XG5mdW5jdGlvbiB2aChhKXtmdW5jdGlvbiBiKGIsYyl7aWYoYSl7dmFyIGQ9Yi5kZWxldGlvbnM7bnVsbD09PWQ/KGIuZGVsZXRpb25zPVtjXSxiLmZsYWdzfD0xNik6ZC5wdXNoKGMpfX1mdW5jdGlvbiBjKGMsZCl7aWYoIWEpcmV0dXJuIG51bGw7Zm9yKDtudWxsIT09ZDspYihjLGQpLGQ9ZC5zaWJsaW5nO3JldHVybiBudWxsfWZ1bmN0aW9uIGQoYSxiKXtmb3IoYT1uZXcgTWFwO251bGwhPT1iOyludWxsIT09Yi5rZXk/YS5zZXQoYi5rZXksYik6YS5zZXQoYi5pbmRleCxiKSxiPWIuc2libGluZztyZXR1cm4gYX1mdW5jdGlvbiBlKGEsYil7YT13aChhLGIpO2EuaW5kZXg9MDthLnNpYmxpbmc9bnVsbDtyZXR1cm4gYX1mdW5jdGlvbiBmKGIsYyxkKXtiLmluZGV4PWQ7aWYoIWEpcmV0dXJuIGIuZmxhZ3N8PTEwNDg1NzYsYztkPWIuYWx0ZXJuYXRlO2lmKG51bGwhPT1kKXJldHVybiBkPWQuaW5kZXgsZDxjPyhiLmZsYWdzfD0yLGMpOmQ7Yi5mbGFnc3w9MjtyZXR1cm4gY31mdW5jdGlvbiBnKGIpe2EmJlxubnVsbD09PWIuYWx0ZXJuYXRlJiYoYi5mbGFnc3w9Mik7cmV0dXJuIGJ9ZnVuY3Rpb24gaChhLGIsYyxkKXtpZihudWxsPT09Ynx8NiE9PWIudGFnKXJldHVybiBiPXhoKGMsYS5tb2RlLGQpLGIucmV0dXJuPWEsYjtiPWUoYixjKTtiLnJldHVybj1hO3JldHVybiBifWZ1bmN0aW9uIGsoYSxiLGMsZCl7dmFyIGY9Yy50eXBlO2lmKGY9PT15YSlyZXR1cm4gbShhLGIsYy5wcm9wcy5jaGlsZHJlbixkLGMua2V5KTtpZihudWxsIT09YiYmKGIuZWxlbWVudFR5cGU9PT1mfHxcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mJiZmLiQkdHlwZW9mPT09SGEmJnVoKGYpPT09Yi50eXBlKSlyZXR1cm4gZD1lKGIsYy5wcm9wcyksZC5yZWY9c2goYSxiLGMpLGQucmV0dXJuPWEsZDtkPXloKGMudHlwZSxjLmtleSxjLnByb3BzLG51bGwsYS5tb2RlLGQpO2QucmVmPXNoKGEsYixjKTtkLnJldHVybj1hO3JldHVybiBkfWZ1bmN0aW9uIGwoYSxiLGMsZCl7aWYobnVsbD09PWJ8fDQhPT1iLnRhZ3x8XG5iLnN0YXRlTm9kZS5jb250YWluZXJJbmZvIT09Yy5jb250YWluZXJJbmZvfHxiLnN0YXRlTm9kZS5pbXBsZW1lbnRhdGlvbiE9PWMuaW1wbGVtZW50YXRpb24pcmV0dXJuIGI9emgoYyxhLm1vZGUsZCksYi5yZXR1cm49YSxiO2I9ZShiLGMuY2hpbGRyZW58fFtdKTtiLnJldHVybj1hO3JldHVybiBifWZ1bmN0aW9uIG0oYSxiLGMsZCxmKXtpZihudWxsPT09Ynx8NyE9PWIudGFnKXJldHVybiBiPUFoKGMsYS5tb2RlLGQsZiksYi5yZXR1cm49YSxiO2I9ZShiLGMpO2IucmV0dXJuPWE7cmV0dXJuIGJ9ZnVuY3Rpb24gcShhLGIsYyl7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBiJiZcIlwiIT09Ynx8XCJudW1iZXJcIj09PXR5cGVvZiBiKXJldHVybiBiPXhoKFwiXCIrYixhLm1vZGUsYyksYi5yZXR1cm49YSxiO2lmKFwib2JqZWN0XCI9PT10eXBlb2YgYiYmbnVsbCE9PWIpe3N3aXRjaChiLiQkdHlwZW9mKXtjYXNlIHZhOnJldHVybiBjPXloKGIudHlwZSxiLmtleSxiLnByb3BzLG51bGwsYS5tb2RlLGMpLFxuYy5yZWY9c2goYSxudWxsLGIpLGMucmV0dXJuPWEsYztjYXNlIHdhOnJldHVybiBiPXpoKGIsYS5tb2RlLGMpLGIucmV0dXJuPWEsYjtjYXNlIEhhOnZhciBkPWIuX2luaXQ7cmV0dXJuIHEoYSxkKGIuX3BheWxvYWQpLGMpfWlmKGViKGIpfHxLYShiKSlyZXR1cm4gYj1BaChiLGEubW9kZSxjLG51bGwpLGIucmV0dXJuPWEsYjt0aChhLGIpfXJldHVybiBudWxsfWZ1bmN0aW9uIHIoYSxiLGMsZCl7dmFyIGU9bnVsbCE9PWI/Yi5rZXk6bnVsbDtpZihcInN0cmluZ1wiPT09dHlwZW9mIGMmJlwiXCIhPT1jfHxcIm51bWJlclwiPT09dHlwZW9mIGMpcmV0dXJuIG51bGwhPT1lP251bGw6aChhLGIsXCJcIitjLGQpO2lmKFwib2JqZWN0XCI9PT10eXBlb2YgYyYmbnVsbCE9PWMpe3N3aXRjaChjLiQkdHlwZW9mKXtjYXNlIHZhOnJldHVybiBjLmtleT09PWU/ayhhLGIsYyxkKTpudWxsO2Nhc2Ugd2E6cmV0dXJuIGMua2V5PT09ZT9sKGEsYixjLGQpOm51bGw7Y2FzZSBIYTpyZXR1cm4gZT1jLl9pbml0LHIoYSxcbmIsZShjLl9wYXlsb2FkKSxkKX1pZihlYihjKXx8S2EoYykpcmV0dXJuIG51bGwhPT1lP251bGw6bShhLGIsYyxkLG51bGwpO3RoKGEsYyl9cmV0dXJuIG51bGx9ZnVuY3Rpb24geShhLGIsYyxkLGUpe2lmKFwic3RyaW5nXCI9PT10eXBlb2YgZCYmXCJcIiE9PWR8fFwibnVtYmVyXCI9PT10eXBlb2YgZClyZXR1cm4gYT1hLmdldChjKXx8bnVsbCxoKGIsYSxcIlwiK2QsZSk7aWYoXCJvYmplY3RcIj09PXR5cGVvZiBkJiZudWxsIT09ZCl7c3dpdGNoKGQuJCR0eXBlb2Ype2Nhc2UgdmE6cmV0dXJuIGE9YS5nZXQobnVsbD09PWQua2V5P2M6ZC5rZXkpfHxudWxsLGsoYixhLGQsZSk7Y2FzZSB3YTpyZXR1cm4gYT1hLmdldChudWxsPT09ZC5rZXk/YzpkLmtleSl8fG51bGwsbChiLGEsZCxlKTtjYXNlIEhhOnZhciBmPWQuX2luaXQ7cmV0dXJuIHkoYSxiLGMsZihkLl9wYXlsb2FkKSxlKX1pZihlYihkKXx8S2EoZCkpcmV0dXJuIGE9YS5nZXQoYyl8fG51bGwsbShiLGEsZCxlLG51bGwpO3RoKGIsZCl9cmV0dXJuIG51bGx9XG5mdW5jdGlvbiBuKGUsZyxoLGspe2Zvcih2YXIgbD1udWxsLG09bnVsbCx1PWcsdz1nPTAseD1udWxsO251bGwhPT11JiZ3PGgubGVuZ3RoO3crKyl7dS5pbmRleD53Pyh4PXUsdT1udWxsKTp4PXUuc2libGluZzt2YXIgbj1yKGUsdSxoW3ddLGspO2lmKG51bGw9PT1uKXtudWxsPT09dSYmKHU9eCk7YnJlYWt9YSYmdSYmbnVsbD09PW4uYWx0ZXJuYXRlJiZiKGUsdSk7Zz1mKG4sZyx3KTtudWxsPT09bT9sPW46bS5zaWJsaW5nPW47bT1uO3U9eH1pZih3PT09aC5sZW5ndGgpcmV0dXJuIGMoZSx1KSxJJiZ0ZyhlLHcpLGw7aWYobnVsbD09PXUpe2Zvcig7dzxoLmxlbmd0aDt3KyspdT1xKGUsaFt3XSxrKSxudWxsIT09dSYmKGc9Zih1LGcsdyksbnVsbD09PW0/bD11Om0uc2libGluZz11LG09dSk7SSYmdGcoZSx3KTtyZXR1cm4gbH1mb3IodT1kKGUsdSk7dzxoLmxlbmd0aDt3KyspeD15KHUsZSx3LGhbd10sayksbnVsbCE9PXgmJihhJiZudWxsIT09eC5hbHRlcm5hdGUmJnUuZGVsZXRlKG51bGw9PT1cbngua2V5P3c6eC5rZXkpLGc9Zih4LGcsdyksbnVsbD09PW0/bD14Om0uc2libGluZz14LG09eCk7YSYmdS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3JldHVybiBiKGUsYSl9KTtJJiZ0ZyhlLHcpO3JldHVybiBsfWZ1bmN0aW9uIHQoZSxnLGgsayl7dmFyIGw9S2EoaCk7aWYoXCJmdW5jdGlvblwiIT09dHlwZW9mIGwpdGhyb3cgRXJyb3IocCgxNTApKTtoPWwuY2FsbChoKTtpZihudWxsPT1oKXRocm93IEVycm9yKHAoMTUxKSk7Zm9yKHZhciB1PWw9bnVsbCxtPWcsdz1nPTAseD1udWxsLG49aC5uZXh0KCk7bnVsbCE9PW0mJiFuLmRvbmU7dysrLG49aC5uZXh0KCkpe20uaW5kZXg+dz8oeD1tLG09bnVsbCk6eD1tLnNpYmxpbmc7dmFyIHQ9cihlLG0sbi52YWx1ZSxrKTtpZihudWxsPT09dCl7bnVsbD09PW0mJihtPXgpO2JyZWFrfWEmJm0mJm51bGw9PT10LmFsdGVybmF0ZSYmYihlLG0pO2c9Zih0LGcsdyk7bnVsbD09PXU/bD10OnUuc2libGluZz10O3U9dDttPXh9aWYobi5kb25lKXJldHVybiBjKGUsXG5tKSxJJiZ0ZyhlLHcpLGw7aWYobnVsbD09PW0pe2Zvcig7IW4uZG9uZTt3Kyssbj1oLm5leHQoKSluPXEoZSxuLnZhbHVlLGspLG51bGwhPT1uJiYoZz1mKG4sZyx3KSxudWxsPT09dT9sPW46dS5zaWJsaW5nPW4sdT1uKTtJJiZ0ZyhlLHcpO3JldHVybiBsfWZvcihtPWQoZSxtKTshbi5kb25lO3crKyxuPWgubmV4dCgpKW49eShtLGUsdyxuLnZhbHVlLGspLG51bGwhPT1uJiYoYSYmbnVsbCE9PW4uYWx0ZXJuYXRlJiZtLmRlbGV0ZShudWxsPT09bi5rZXk/dzpuLmtleSksZz1mKG4sZyx3KSxudWxsPT09dT9sPW46dS5zaWJsaW5nPW4sdT1uKTthJiZtLmZvckVhY2goZnVuY3Rpb24oYSl7cmV0dXJuIGIoZSxhKX0pO0kmJnRnKGUsdyk7cmV0dXJuIGx9ZnVuY3Rpb24gSihhLGQsZixoKXtcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mJiZmLnR5cGU9PT15YSYmbnVsbD09PWYua2V5JiYoZj1mLnByb3BzLmNoaWxkcmVuKTtpZihcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mKXtzd2l0Y2goZi4kJHR5cGVvZil7Y2FzZSB2YTphOntmb3IodmFyIGs9XG5mLmtleSxsPWQ7bnVsbCE9PWw7KXtpZihsLmtleT09PWspe2s9Zi50eXBlO2lmKGs9PT15YSl7aWYoNz09PWwudGFnKXtjKGEsbC5zaWJsaW5nKTtkPWUobCxmLnByb3BzLmNoaWxkcmVuKTtkLnJldHVybj1hO2E9ZDticmVhayBhfX1lbHNlIGlmKGwuZWxlbWVudFR5cGU9PT1rfHxcIm9iamVjdFwiPT09dHlwZW9mIGsmJm51bGwhPT1rJiZrLiQkdHlwZW9mPT09SGEmJnVoKGspPT09bC50eXBlKXtjKGEsbC5zaWJsaW5nKTtkPWUobCxmLnByb3BzKTtkLnJlZj1zaChhLGwsZik7ZC5yZXR1cm49YTthPWQ7YnJlYWsgYX1jKGEsbCk7YnJlYWt9ZWxzZSBiKGEsbCk7bD1sLnNpYmxpbmd9Zi50eXBlPT09eWE/KGQ9QWgoZi5wcm9wcy5jaGlsZHJlbixhLm1vZGUsaCxmLmtleSksZC5yZXR1cm49YSxhPWQpOihoPXloKGYudHlwZSxmLmtleSxmLnByb3BzLG51bGwsYS5tb2RlLGgpLGgucmVmPXNoKGEsZCxmKSxoLnJldHVybj1hLGE9aCl9cmV0dXJuIGcoYSk7Y2FzZSB3YTphOntmb3IobD1mLmtleTtudWxsIT09XG5kOyl7aWYoZC5rZXk9PT1sKWlmKDQ9PT1kLnRhZyYmZC5zdGF0ZU5vZGUuY29udGFpbmVySW5mbz09PWYuY29udGFpbmVySW5mbyYmZC5zdGF0ZU5vZGUuaW1wbGVtZW50YXRpb249PT1mLmltcGxlbWVudGF0aW9uKXtjKGEsZC5zaWJsaW5nKTtkPWUoZCxmLmNoaWxkcmVufHxbXSk7ZC5yZXR1cm49YTthPWQ7YnJlYWsgYX1lbHNle2MoYSxkKTticmVha31lbHNlIGIoYSxkKTtkPWQuc2libGluZ31kPXpoKGYsYS5tb2RlLGgpO2QucmV0dXJuPWE7YT1kfXJldHVybiBnKGEpO2Nhc2UgSGE6cmV0dXJuIGw9Zi5faW5pdCxKKGEsZCxsKGYuX3BheWxvYWQpLGgpfWlmKGViKGYpKXJldHVybiBuKGEsZCxmLGgpO2lmKEthKGYpKXJldHVybiB0KGEsZCxmLGgpO3RoKGEsZil9cmV0dXJuXCJzdHJpbmdcIj09PXR5cGVvZiBmJiZcIlwiIT09Znx8XCJudW1iZXJcIj09PXR5cGVvZiBmPyhmPVwiXCIrZixudWxsIT09ZCYmNj09PWQudGFnPyhjKGEsZC5zaWJsaW5nKSxkPWUoZCxmKSxkLnJldHVybj1hLGE9ZCk6XG4oYyhhLGQpLGQ9eGgoZixhLm1vZGUsaCksZC5yZXR1cm49YSxhPWQpLGcoYSkpOmMoYSxkKX1yZXR1cm4gSn12YXIgQmg9dmgoITApLENoPXZoKCExKSxEaD17fSxFaD1VZihEaCksRmg9VWYoRGgpLEdoPVVmKERoKTtmdW5jdGlvbiBIaChhKXtpZihhPT09RGgpdGhyb3cgRXJyb3IocCgxNzQpKTtyZXR1cm4gYX1mdW5jdGlvbiBJaChhLGIpe0coR2gsYik7RyhGaCxhKTtHKEVoLERoKTthPWIubm9kZVR5cGU7c3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDExOmI9KGI9Yi5kb2N1bWVudEVsZW1lbnQpP2IubmFtZXNwYWNlVVJJOmxiKG51bGwsXCJcIik7YnJlYWs7ZGVmYXVsdDphPTg9PT1hP2IucGFyZW50Tm9kZTpiLGI9YS5uYW1lc3BhY2VVUkl8fG51bGwsYT1hLnRhZ05hbWUsYj1sYihiLGEpfUUoRWgpO0coRWgsYil9ZnVuY3Rpb24gSmgoKXtFKEVoKTtFKEZoKTtFKEdoKX1cbmZ1bmN0aW9uIEtoKGEpe0hoKEdoLmN1cnJlbnQpO3ZhciBiPUhoKEVoLmN1cnJlbnQpO3ZhciBjPWxiKGIsYS50eXBlKTtiIT09YyYmKEcoRmgsYSksRyhFaCxjKSl9ZnVuY3Rpb24gTGgoYSl7RmguY3VycmVudD09PWEmJihFKEVoKSxFKEZoKSl9dmFyIE09VWYoMCk7XG5mdW5jdGlvbiBNaChhKXtmb3IodmFyIGI9YTtudWxsIT09Yjspe2lmKDEzPT09Yi50YWcpe3ZhciBjPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09YyYmKGM9Yy5kZWh5ZHJhdGVkLG51bGw9PT1jfHxcIiQ/XCI9PT1jLmRhdGF8fFwiJCFcIj09PWMuZGF0YSkpcmV0dXJuIGJ9ZWxzZSBpZigxOT09PWIudGFnJiZ2b2lkIDAhPT1iLm1lbW9pemVkUHJvcHMucmV2ZWFsT3JkZXIpe2lmKDAhPT0oYi5mbGFncyYxMjgpKXJldHVybiBifWVsc2UgaWYobnVsbCE9PWIuY2hpbGQpe2IuY2hpbGQucmV0dXJuPWI7Yj1iLmNoaWxkO2NvbnRpbnVlfWlmKGI9PT1hKWJyZWFrO2Zvcig7bnVsbD09PWIuc2libGluZzspe2lmKG51bGw9PT1iLnJldHVybnx8Yi5yZXR1cm49PT1hKXJldHVybiBudWxsO2I9Yi5yZXR1cm59Yi5zaWJsaW5nLnJldHVybj1iLnJldHVybjtiPWIuc2libGluZ31yZXR1cm4gbnVsbH12YXIgTmg9W107XG5mdW5jdGlvbiBPaCgpe2Zvcih2YXIgYT0wO2E8TmgubGVuZ3RoO2ErKylOaFthXS5fd29ya0luUHJvZ3Jlc3NWZXJzaW9uUHJpbWFyeT1udWxsO05oLmxlbmd0aD0wfXZhciBQaD11YS5SZWFjdEN1cnJlbnREaXNwYXRjaGVyLFFoPXVhLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFJoPTAsTj1udWxsLE89bnVsbCxQPW51bGwsU2g9ITEsVGg9ITEsVWg9MCxWaD0wO2Z1bmN0aW9uIFEoKXt0aHJvdyBFcnJvcihwKDMyMSkpO31mdW5jdGlvbiBXaChhLGIpe2lmKG51bGw9PT1iKXJldHVybiExO2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGgmJmM8YS5sZW5ndGg7YysrKWlmKCFIZShhW2NdLGJbY10pKXJldHVybiExO3JldHVybiEwfVxuZnVuY3Rpb24gWGgoYSxiLGMsZCxlLGYpe1JoPWY7Tj1iO2IubWVtb2l6ZWRTdGF0ZT1udWxsO2IudXBkYXRlUXVldWU9bnVsbDtiLmxhbmVzPTA7UGguY3VycmVudD1udWxsPT09YXx8bnVsbD09PWEubWVtb2l6ZWRTdGF0ZT9ZaDpaaDthPWMoZCxlKTtpZihUaCl7Zj0wO2Rve1RoPSExO1VoPTA7aWYoMjU8PWYpdGhyb3cgRXJyb3IocCgzMDEpKTtmKz0xO1A9Tz1udWxsO2IudXBkYXRlUXVldWU9bnVsbDtQaC5jdXJyZW50PSRoO2E9YyhkLGUpfXdoaWxlKFRoKX1QaC5jdXJyZW50PWFpO2I9bnVsbCE9PU8mJm51bGwhPT1PLm5leHQ7Umg9MDtQPU89Tj1udWxsO1NoPSExO2lmKGIpdGhyb3cgRXJyb3IocCgzMDApKTtyZXR1cm4gYX1mdW5jdGlvbiBiaSgpe3ZhciBhPTAhPT1VaDtVaD0wO3JldHVybiBhfVxuZnVuY3Rpb24gY2koKXt2YXIgYT17bWVtb2l6ZWRTdGF0ZTpudWxsLGJhc2VTdGF0ZTpudWxsLGJhc2VRdWV1ZTpudWxsLHF1ZXVlOm51bGwsbmV4dDpudWxsfTtudWxsPT09UD9OLm1lbW9pemVkU3RhdGU9UD1hOlA9UC5uZXh0PWE7cmV0dXJuIFB9ZnVuY3Rpb24gZGkoKXtpZihudWxsPT09Tyl7dmFyIGE9Ti5hbHRlcm5hdGU7YT1udWxsIT09YT9hLm1lbW9pemVkU3RhdGU6bnVsbH1lbHNlIGE9Ty5uZXh0O3ZhciBiPW51bGw9PT1QP04ubWVtb2l6ZWRTdGF0ZTpQLm5leHQ7aWYobnVsbCE9PWIpUD1iLE89YTtlbHNle2lmKG51bGw9PT1hKXRocm93IEVycm9yKHAoMzEwKSk7Tz1hO2E9e21lbW9pemVkU3RhdGU6Ty5tZW1vaXplZFN0YXRlLGJhc2VTdGF0ZTpPLmJhc2VTdGF0ZSxiYXNlUXVldWU6Ty5iYXNlUXVldWUscXVldWU6Ty5xdWV1ZSxuZXh0Om51bGx9O251bGw9PT1QP04ubWVtb2l6ZWRTdGF0ZT1QPWE6UD1QLm5leHQ9YX1yZXR1cm4gUH1cbmZ1bmN0aW9uIGVpKGEsYil7cmV0dXJuXCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YihhKTpifVxuZnVuY3Rpb24gZmkoYSl7dmFyIGI9ZGkoKSxjPWIucXVldWU7aWYobnVsbD09PWMpdGhyb3cgRXJyb3IocCgzMTEpKTtjLmxhc3RSZW5kZXJlZFJlZHVjZXI9YTt2YXIgZD1PLGU9ZC5iYXNlUXVldWUsZj1jLnBlbmRpbmc7aWYobnVsbCE9PWYpe2lmKG51bGwhPT1lKXt2YXIgZz1lLm5leHQ7ZS5uZXh0PWYubmV4dDtmLm5leHQ9Z31kLmJhc2VRdWV1ZT1lPWY7Yy5wZW5kaW5nPW51bGx9aWYobnVsbCE9PWUpe2Y9ZS5uZXh0O2Q9ZC5iYXNlU3RhdGU7dmFyIGg9Zz1udWxsLGs9bnVsbCxsPWY7ZG97dmFyIG09bC5sYW5lO2lmKChSaCZtKT09PW0pbnVsbCE9PWsmJihrPWsubmV4dD17bGFuZTowLGFjdGlvbjpsLmFjdGlvbixoYXNFYWdlclN0YXRlOmwuaGFzRWFnZXJTdGF0ZSxlYWdlclN0YXRlOmwuZWFnZXJTdGF0ZSxuZXh0Om51bGx9KSxkPWwuaGFzRWFnZXJTdGF0ZT9sLmVhZ2VyU3RhdGU6YShkLGwuYWN0aW9uKTtlbHNle3ZhciBxPXtsYW5lOm0sYWN0aW9uOmwuYWN0aW9uLGhhc0VhZ2VyU3RhdGU6bC5oYXNFYWdlclN0YXRlLFxuZWFnZXJTdGF0ZTpsLmVhZ2VyU3RhdGUsbmV4dDpudWxsfTtudWxsPT09az8oaD1rPXEsZz1kKTprPWsubmV4dD1xO04ubGFuZXN8PW07aGh8PW19bD1sLm5leHR9d2hpbGUobnVsbCE9PWwmJmwhPT1mKTtudWxsPT09az9nPWQ6ay5uZXh0PWg7SGUoZCxiLm1lbW9pemVkU3RhdGUpfHwoVWc9ITApO2IubWVtb2l6ZWRTdGF0ZT1kO2IuYmFzZVN0YXRlPWc7Yi5iYXNlUXVldWU9aztjLmxhc3RSZW5kZXJlZFN0YXRlPWR9YT1jLmludGVybGVhdmVkO2lmKG51bGwhPT1hKXtlPWE7ZG8gZj1lLmxhbmUsTi5sYW5lc3w9ZixoaHw9ZixlPWUubmV4dDt3aGlsZShlIT09YSl9ZWxzZSBudWxsPT09ZSYmKGMubGFuZXM9MCk7cmV0dXJuW2IubWVtb2l6ZWRTdGF0ZSxjLmRpc3BhdGNoXX1cbmZ1bmN0aW9uIGdpKGEpe3ZhciBiPWRpKCksYz1iLnF1ZXVlO2lmKG51bGw9PT1jKXRocm93IEVycm9yKHAoMzExKSk7Yy5sYXN0UmVuZGVyZWRSZWR1Y2VyPWE7dmFyIGQ9Yy5kaXNwYXRjaCxlPWMucGVuZGluZyxmPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09ZSl7Yy5wZW5kaW5nPW51bGw7dmFyIGc9ZT1lLm5leHQ7ZG8gZj1hKGYsZy5hY3Rpb24pLGc9Zy5uZXh0O3doaWxlKGchPT1lKTtIZShmLGIubWVtb2l6ZWRTdGF0ZSl8fChVZz0hMCk7Yi5tZW1vaXplZFN0YXRlPWY7bnVsbD09PWIuYmFzZVF1ZXVlJiYoYi5iYXNlU3RhdGU9Zik7Yy5sYXN0UmVuZGVyZWRTdGF0ZT1mfXJldHVybltmLGRdfWZ1bmN0aW9uIGhpKCl7fVxuZnVuY3Rpb24gaWkoYSxiKXt2YXIgYz1OLGQ9ZGkoKSxlPWIoKSxmPSFIZShkLm1lbW9pemVkU3RhdGUsZSk7ZiYmKGQubWVtb2l6ZWRTdGF0ZT1lLFVnPSEwKTtkPWQucXVldWU7amkoa2kuYmluZChudWxsLGMsZCxhKSxbYV0pO2lmKGQuZ2V0U25hcHNob3QhPT1ifHxmfHxudWxsIT09UCYmUC5tZW1vaXplZFN0YXRlLnRhZyYxKXtjLmZsYWdzfD0yMDQ4O2xpKDksbWkuYmluZChudWxsLGMsZCxlLGIpLHZvaWQgMCxudWxsKTtpZihudWxsPT09Uil0aHJvdyBFcnJvcihwKDM0OSkpOzAhPT0oUmgmMzApfHxuaShjLGIsZSl9cmV0dXJuIGV9ZnVuY3Rpb24gbmkoYSxiLGMpe2EuZmxhZ3N8PTE2Mzg0O2E9e2dldFNuYXBzaG90OmIsdmFsdWU6Y307Yj1OLnVwZGF0ZVF1ZXVlO251bGw9PT1iPyhiPXtsYXN0RWZmZWN0Om51bGwsc3RvcmVzOm51bGx9LE4udXBkYXRlUXVldWU9YixiLnN0b3Jlcz1bYV0pOihjPWIuc3RvcmVzLG51bGw9PT1jP2Iuc3RvcmVzPVthXTpjLnB1c2goYSkpfVxuZnVuY3Rpb24gbWkoYSxiLGMsZCl7Yi52YWx1ZT1jO2IuZ2V0U25hcHNob3Q9ZDtvaShiKSYmcGkoYSl9ZnVuY3Rpb24ga2koYSxiLGMpe3JldHVybiBjKGZ1bmN0aW9uKCl7b2koYikmJnBpKGEpfSl9ZnVuY3Rpb24gb2koYSl7dmFyIGI9YS5nZXRTbmFwc2hvdDthPWEudmFsdWU7dHJ5e3ZhciBjPWIoKTtyZXR1cm4hSGUoYSxjKX1jYXRjaChkKXtyZXR1cm4hMH19ZnVuY3Rpb24gcGkoYSl7dmFyIGI9WmcoYSwxKTtudWxsIT09YiYmbWgoYixhLDEsLTEpfVxuZnVuY3Rpb24gcWkoYSl7dmFyIGI9Y2koKTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYSYmKGE9YSgpKTtiLm1lbW9pemVkU3RhdGU9Yi5iYXNlU3RhdGU9YTthPXtwZW5kaW5nOm51bGwsaW50ZXJsZWF2ZWQ6bnVsbCxsYW5lczowLGRpc3BhdGNoOm51bGwsbGFzdFJlbmRlcmVkUmVkdWNlcjplaSxsYXN0UmVuZGVyZWRTdGF0ZTphfTtiLnF1ZXVlPWE7YT1hLmRpc3BhdGNoPXJpLmJpbmQobnVsbCxOLGEpO3JldHVybltiLm1lbW9pemVkU3RhdGUsYV19XG5mdW5jdGlvbiBsaShhLGIsYyxkKXthPXt0YWc6YSxjcmVhdGU6YixkZXN0cm95OmMsZGVwczpkLG5leHQ6bnVsbH07Yj1OLnVwZGF0ZVF1ZXVlO251bGw9PT1iPyhiPXtsYXN0RWZmZWN0Om51bGwsc3RvcmVzOm51bGx9LE4udXBkYXRlUXVldWU9YixiLmxhc3RFZmZlY3Q9YS5uZXh0PWEpOihjPWIubGFzdEVmZmVjdCxudWxsPT09Yz9iLmxhc3RFZmZlY3Q9YS5uZXh0PWE6KGQ9Yy5uZXh0LGMubmV4dD1hLGEubmV4dD1kLGIubGFzdEVmZmVjdD1hKSk7cmV0dXJuIGF9ZnVuY3Rpb24gc2koKXtyZXR1cm4gZGkoKS5tZW1vaXplZFN0YXRlfWZ1bmN0aW9uIHRpKGEsYixjLGQpe3ZhciBlPWNpKCk7Ti5mbGFnc3w9YTtlLm1lbW9pemVkU3RhdGU9bGkoMXxiLGMsdm9pZCAwLHZvaWQgMD09PWQ/bnVsbDpkKX1cbmZ1bmN0aW9uIHVpKGEsYixjLGQpe3ZhciBlPWRpKCk7ZD12b2lkIDA9PT1kP251bGw6ZDt2YXIgZj12b2lkIDA7aWYobnVsbCE9PU8pe3ZhciBnPU8ubWVtb2l6ZWRTdGF0ZTtmPWcuZGVzdHJveTtpZihudWxsIT09ZCYmV2goZCxnLmRlcHMpKXtlLm1lbW9pemVkU3RhdGU9bGkoYixjLGYsZCk7cmV0dXJufX1OLmZsYWdzfD1hO2UubWVtb2l6ZWRTdGF0ZT1saSgxfGIsYyxmLGQpfWZ1bmN0aW9uIHZpKGEsYil7cmV0dXJuIHRpKDgzOTA2NTYsOCxhLGIpfWZ1bmN0aW9uIGppKGEsYil7cmV0dXJuIHVpKDIwNDgsOCxhLGIpfWZ1bmN0aW9uIHdpKGEsYil7cmV0dXJuIHVpKDQsMixhLGIpfWZ1bmN0aW9uIHhpKGEsYil7cmV0dXJuIHVpKDQsNCxhLGIpfVxuZnVuY3Rpb24geWkoYSxiKXtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYilyZXR1cm4gYT1hKCksYihhKSxmdW5jdGlvbigpe2IobnVsbCl9O2lmKG51bGwhPT1iJiZ2b2lkIDAhPT1iKXJldHVybiBhPWEoKSxiLmN1cnJlbnQ9YSxmdW5jdGlvbigpe2IuY3VycmVudD1udWxsfX1mdW5jdGlvbiB6aShhLGIsYyl7Yz1udWxsIT09YyYmdm9pZCAwIT09Yz9jLmNvbmNhdChbYV0pOm51bGw7cmV0dXJuIHVpKDQsNCx5aS5iaW5kKG51bGwsYixhKSxjKX1mdW5jdGlvbiBBaSgpe31mdW5jdGlvbiBCaShhLGIpe3ZhciBjPWRpKCk7Yj12b2lkIDA9PT1iP251bGw6Yjt2YXIgZD1jLm1lbW9pemVkU3RhdGU7aWYobnVsbCE9PWQmJm51bGwhPT1iJiZXaChiLGRbMV0pKXJldHVybiBkWzBdO2MubWVtb2l6ZWRTdGF0ZT1bYSxiXTtyZXR1cm4gYX1cbmZ1bmN0aW9uIENpKGEsYil7dmFyIGM9ZGkoKTtiPXZvaWQgMD09PWI/bnVsbDpiO3ZhciBkPWMubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09ZCYmbnVsbCE9PWImJldoKGIsZFsxXSkpcmV0dXJuIGRbMF07YT1hKCk7Yy5tZW1vaXplZFN0YXRlPVthLGJdO3JldHVybiBhfWZ1bmN0aW9uIERpKGEsYixjKXtpZigwPT09KFJoJjIxKSlyZXR1cm4gYS5iYXNlU3RhdGUmJihhLmJhc2VTdGF0ZT0hMSxVZz0hMCksYS5tZW1vaXplZFN0YXRlPWM7SGUoYyxiKXx8KGM9eWMoKSxOLmxhbmVzfD1jLGhofD1jLGEuYmFzZVN0YXRlPSEwKTtyZXR1cm4gYn1mdW5jdGlvbiBFaShhLGIpe3ZhciBjPUM7Qz0wIT09YyYmND5jP2M6NDthKCEwKTt2YXIgZD1RaC50cmFuc2l0aW9uO1FoLnRyYW5zaXRpb249e307dHJ5e2EoITEpLGIoKX1maW5hbGx5e0M9YyxRaC50cmFuc2l0aW9uPWR9fWZ1bmN0aW9uIEZpKCl7cmV0dXJuIGRpKCkubWVtb2l6ZWRTdGF0ZX1cbmZ1bmN0aW9uIEdpKGEsYixjKXt2YXIgZD1saChhKTtjPXtsYW5lOmQsYWN0aW9uOmMsaGFzRWFnZXJTdGF0ZTohMSxlYWdlclN0YXRlOm51bGwsbmV4dDpudWxsfTtpZihIaShhKSlJaShiLGMpO2Vsc2UgaWYoYz1ZZyhhLGIsYyxkKSxudWxsIT09Yyl7dmFyIGU9TCgpO21oKGMsYSxkLGUpO0ppKGMsYixkKX19XG5mdW5jdGlvbiByaShhLGIsYyl7dmFyIGQ9bGgoYSksZT17bGFuZTpkLGFjdGlvbjpjLGhhc0VhZ2VyU3RhdGU6ITEsZWFnZXJTdGF0ZTpudWxsLG5leHQ6bnVsbH07aWYoSGkoYSkpSWkoYixlKTtlbHNle3ZhciBmPWEuYWx0ZXJuYXRlO2lmKDA9PT1hLmxhbmVzJiYobnVsbD09PWZ8fDA9PT1mLmxhbmVzKSYmKGY9Yi5sYXN0UmVuZGVyZWRSZWR1Y2VyLG51bGwhPT1mKSl0cnl7dmFyIGc9Yi5sYXN0UmVuZGVyZWRTdGF0ZSxoPWYoZyxjKTtlLmhhc0VhZ2VyU3RhdGU9ITA7ZS5lYWdlclN0YXRlPWg7aWYoSGUoaCxnKSl7dmFyIGs9Yi5pbnRlcmxlYXZlZDtudWxsPT09az8oZS5uZXh0PWUsWGcoYikpOihlLm5leHQ9ay5uZXh0LGsubmV4dD1lKTtiLmludGVybGVhdmVkPWU7cmV0dXJufX1jYXRjaChsKXt9ZmluYWxseXt9Yz1ZZyhhLGIsZSxkKTtudWxsIT09YyYmKGU9TCgpLG1oKGMsYSxkLGUpLEppKGMsYixkKSl9fVxuZnVuY3Rpb24gSGkoYSl7dmFyIGI9YS5hbHRlcm5hdGU7cmV0dXJuIGE9PT1OfHxudWxsIT09YiYmYj09PU59ZnVuY3Rpb24gSWkoYSxiKXtUaD1TaD0hMDt2YXIgYz1hLnBlbmRpbmc7bnVsbD09PWM/Yi5uZXh0PWI6KGIubmV4dD1jLm5leHQsYy5uZXh0PWIpO2EucGVuZGluZz1ifWZ1bmN0aW9uIEppKGEsYixjKXtpZigwIT09KGMmNDE5NDI0MCkpe3ZhciBkPWIubGFuZXM7ZCY9YS5wZW5kaW5nTGFuZXM7Y3w9ZDtiLmxhbmVzPWM7Q2MoYSxjKX19XG52YXIgYWk9e3JlYWRDb250ZXh0OlZnLHVzZUNhbGxiYWNrOlEsdXNlQ29udGV4dDpRLHVzZUVmZmVjdDpRLHVzZUltcGVyYXRpdmVIYW5kbGU6USx1c2VJbnNlcnRpb25FZmZlY3Q6USx1c2VMYXlvdXRFZmZlY3Q6USx1c2VNZW1vOlEsdXNlUmVkdWNlcjpRLHVzZVJlZjpRLHVzZVN0YXRlOlEsdXNlRGVidWdWYWx1ZTpRLHVzZURlZmVycmVkVmFsdWU6USx1c2VUcmFuc2l0aW9uOlEsdXNlTXV0YWJsZVNvdXJjZTpRLHVzZVN5bmNFeHRlcm5hbFN0b3JlOlEsdXNlSWQ6USx1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6ITF9LFloPXtyZWFkQ29udGV4dDpWZyx1c2VDYWxsYmFjazpmdW5jdGlvbihhLGIpe2NpKCkubWVtb2l6ZWRTdGF0ZT1bYSx2b2lkIDA9PT1iP251bGw6Yl07cmV0dXJuIGF9LHVzZUNvbnRleHQ6VmcsdXNlRWZmZWN0OnZpLHVzZUltcGVyYXRpdmVIYW5kbGU6ZnVuY3Rpb24oYSxiLGMpe2M9bnVsbCE9PWMmJnZvaWQgMCE9PWM/Yy5jb25jYXQoW2FdKTpudWxsO3JldHVybiB0aSg0MTk0MzA4LFxuNCx5aS5iaW5kKG51bGwsYixhKSxjKX0sdXNlTGF5b3V0RWZmZWN0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRpKDQxOTQzMDgsNCxhLGIpfSx1c2VJbnNlcnRpb25FZmZlY3Q6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGkoNCwyLGEsYil9LHVzZU1lbW86ZnVuY3Rpb24oYSxiKXt2YXIgYz1jaSgpO2I9dm9pZCAwPT09Yj9udWxsOmI7YT1hKCk7Yy5tZW1vaXplZFN0YXRlPVthLGJdO3JldHVybiBhfSx1c2VSZWR1Y2VyOmZ1bmN0aW9uKGEsYixjKXt2YXIgZD1jaSgpO2I9dm9pZCAwIT09Yz9jKGIpOmI7ZC5tZW1vaXplZFN0YXRlPWQuYmFzZVN0YXRlPWI7YT17cGVuZGluZzpudWxsLGludGVybGVhdmVkOm51bGwsbGFuZXM6MCxkaXNwYXRjaDpudWxsLGxhc3RSZW5kZXJlZFJlZHVjZXI6YSxsYXN0UmVuZGVyZWRTdGF0ZTpifTtkLnF1ZXVlPWE7YT1hLmRpc3BhdGNoPUdpLmJpbmQobnVsbCxOLGEpO3JldHVybltkLm1lbW9pemVkU3RhdGUsYV19LHVzZVJlZjpmdW5jdGlvbihhKXt2YXIgYj1cbmNpKCk7YT17Y3VycmVudDphfTtyZXR1cm4gYi5tZW1vaXplZFN0YXRlPWF9LHVzZVN0YXRlOnFpLHVzZURlYnVnVmFsdWU6QWksdXNlRGVmZXJyZWRWYWx1ZTpmdW5jdGlvbihhKXtyZXR1cm4gY2koKS5tZW1vaXplZFN0YXRlPWF9LHVzZVRyYW5zaXRpb246ZnVuY3Rpb24oKXt2YXIgYT1xaSghMSksYj1hWzBdO2E9RWkuYmluZChudWxsLGFbMV0pO2NpKCkubWVtb2l6ZWRTdGF0ZT1hO3JldHVybltiLGFdfSx1c2VNdXRhYmxlU291cmNlOmZ1bmN0aW9uKCl7fSx1c2VTeW5jRXh0ZXJuYWxTdG9yZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9TixlPWNpKCk7aWYoSSl7aWYodm9pZCAwPT09Yyl0aHJvdyBFcnJvcihwKDQwNykpO2M9YygpfWVsc2V7Yz1iKCk7aWYobnVsbD09PVIpdGhyb3cgRXJyb3IocCgzNDkpKTswIT09KFJoJjMwKXx8bmkoZCxiLGMpfWUubWVtb2l6ZWRTdGF0ZT1jO3ZhciBmPXt2YWx1ZTpjLGdldFNuYXBzaG90OmJ9O2UucXVldWU9Zjt2aShraS5iaW5kKG51bGwsZCxcbmYsYSksW2FdKTtkLmZsYWdzfD0yMDQ4O2xpKDksbWkuYmluZChudWxsLGQsZixjLGIpLHZvaWQgMCxudWxsKTtyZXR1cm4gY30sdXNlSWQ6ZnVuY3Rpb24oKXt2YXIgYT1jaSgpLGI9Ui5pZGVudGlmaWVyUHJlZml4O2lmKEkpe3ZhciBjPXNnO3ZhciBkPXJnO2M9KGQmfigxPDwzMi1vYyhkKS0xKSkudG9TdHJpbmcoMzIpK2M7Yj1cIjpcIitiK1wiUlwiK2M7Yz1VaCsrOzA8YyYmKGIrPVwiSFwiK2MudG9TdHJpbmcoMzIpKTtiKz1cIjpcIn1lbHNlIGM9VmgrKyxiPVwiOlwiK2IrXCJyXCIrYy50b1N0cmluZygzMikrXCI6XCI7cmV0dXJuIGEubWVtb2l6ZWRTdGF0ZT1ifSx1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6ITF9LFpoPXtyZWFkQ29udGV4dDpWZyx1c2VDYWxsYmFjazpCaSx1c2VDb250ZXh0OlZnLHVzZUVmZmVjdDpqaSx1c2VJbXBlcmF0aXZlSGFuZGxlOnppLHVzZUluc2VydGlvbkVmZmVjdDp3aSx1c2VMYXlvdXRFZmZlY3Q6eGksdXNlTWVtbzpDaSx1c2VSZWR1Y2VyOmZpLHVzZVJlZjpzaSx1c2VTdGF0ZTpmdW5jdGlvbigpe3JldHVybiBmaShlaSl9LFxudXNlRGVidWdWYWx1ZTpBaSx1c2VEZWZlcnJlZFZhbHVlOmZ1bmN0aW9uKGEpe3ZhciBiPWRpKCk7cmV0dXJuIERpKGIsTy5tZW1vaXplZFN0YXRlLGEpfSx1c2VUcmFuc2l0aW9uOmZ1bmN0aW9uKCl7dmFyIGE9ZmkoZWkpWzBdLGI9ZGkoKS5tZW1vaXplZFN0YXRlO3JldHVyblthLGJdfSx1c2VNdXRhYmxlU291cmNlOmhpLHVzZVN5bmNFeHRlcm5hbFN0b3JlOmlpLHVzZUlkOkZpLHVuc3RhYmxlX2lzTmV3UmVjb25jaWxlcjohMX0sJGg9e3JlYWRDb250ZXh0OlZnLHVzZUNhbGxiYWNrOkJpLHVzZUNvbnRleHQ6VmcsdXNlRWZmZWN0OmppLHVzZUltcGVyYXRpdmVIYW5kbGU6emksdXNlSW5zZXJ0aW9uRWZmZWN0OndpLHVzZUxheW91dEVmZmVjdDp4aSx1c2VNZW1vOkNpLHVzZVJlZHVjZXI6Z2ksdXNlUmVmOnNpLHVzZVN0YXRlOmZ1bmN0aW9uKCl7cmV0dXJuIGdpKGVpKX0sdXNlRGVidWdWYWx1ZTpBaSx1c2VEZWZlcnJlZFZhbHVlOmZ1bmN0aW9uKGEpe3ZhciBiPWRpKCk7cmV0dXJuIG51bGw9PT1cbk8/Yi5tZW1vaXplZFN0YXRlPWE6RGkoYixPLm1lbW9pemVkU3RhdGUsYSl9LHVzZVRyYW5zaXRpb246ZnVuY3Rpb24oKXt2YXIgYT1naShlaSlbMF0sYj1kaSgpLm1lbW9pemVkU3RhdGU7cmV0dXJuW2EsYl19LHVzZU11dGFibGVTb3VyY2U6aGksdXNlU3luY0V4dGVybmFsU3RvcmU6aWksdXNlSWQ6RmksdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiExfTtmdW5jdGlvbiBLaShhLGIpe3RyeXt2YXIgYz1cIlwiLGQ9YjtkbyBjKz1QYShkKSxkPWQucmV0dXJuO3doaWxlKGQpO3ZhciBlPWN9Y2F0Y2goZil7ZT1cIlxcbkVycm9yIGdlbmVyYXRpbmcgc3RhY2s6IFwiK2YubWVzc2FnZStcIlxcblwiK2Yuc3RhY2t9cmV0dXJue3ZhbHVlOmEsc291cmNlOmIsc3RhY2s6ZSxkaWdlc3Q6bnVsbH19ZnVuY3Rpb24gTGkoYSxiLGMpe3JldHVybnt2YWx1ZTphLHNvdXJjZTpudWxsLHN0YWNrOm51bGwhPWM/YzpudWxsLGRpZ2VzdDpudWxsIT1iP2I6bnVsbH19XG5mdW5jdGlvbiBNaShhLGIpe3RyeXtjb25zb2xlLmVycm9yKGIudmFsdWUpfWNhdGNoKGMpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXt0aHJvdyBjO30pfX12YXIgTmk9XCJmdW5jdGlvblwiPT09dHlwZW9mIFdlYWtNYXA/V2Vha01hcDpNYXA7ZnVuY3Rpb24gT2koYSxiLGMpe2M9Y2goLTEsYyk7Yy50YWc9MztjLnBheWxvYWQ9e2VsZW1lbnQ6bnVsbH07dmFyIGQ9Yi52YWx1ZTtjLmNhbGxiYWNrPWZ1bmN0aW9uKCl7UGl8fChQaT0hMCxRaT1kKTtNaShhLGIpfTtyZXR1cm4gY31cbmZ1bmN0aW9uIFJpKGEsYixjKXtjPWNoKC0xLGMpO2MudGFnPTM7dmFyIGQ9YS50eXBlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcjtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZCl7dmFyIGU9Yi52YWx1ZTtjLnBheWxvYWQ9ZnVuY3Rpb24oKXtyZXR1cm4gZChlKX07Yy5jYWxsYmFjaz1mdW5jdGlvbigpe01pKGEsYil9fXZhciBmPWEuc3RhdGVOb2RlO251bGwhPT1mJiZcImZ1bmN0aW9uXCI9PT10eXBlb2YgZi5jb21wb25lbnREaWRDYXRjaCYmKGMuY2FsbGJhY2s9ZnVuY3Rpb24oKXtNaShhLGIpO1wiZnVuY3Rpb25cIiE9PXR5cGVvZiBkJiYobnVsbD09PVNpP1NpPW5ldyBTZXQoW3RoaXNdKTpTaS5hZGQodGhpcykpO3ZhciBjPWIuc3RhY2s7dGhpcy5jb21wb25lbnREaWRDYXRjaChiLnZhbHVlLHtjb21wb25lbnRTdGFjazpudWxsIT09Yz9jOlwiXCJ9KX0pO3JldHVybiBjfVxuZnVuY3Rpb24gVGkoYSxiLGMpe3ZhciBkPWEucGluZ0NhY2hlO2lmKG51bGw9PT1kKXtkPWEucGluZ0NhY2hlPW5ldyBOaTt2YXIgZT1uZXcgU2V0O2Quc2V0KGIsZSl9ZWxzZSBlPWQuZ2V0KGIpLHZvaWQgMD09PWUmJihlPW5ldyBTZXQsZC5zZXQoYixlKSk7ZS5oYXMoYyl8fChlLmFkZChjKSxhPVVpLmJpbmQobnVsbCxhLGIsYyksYi50aGVuKGEsYSkpfWZ1bmN0aW9uIFZpKGEpe2Rve3ZhciBiO2lmKGI9MTM9PT1hLnRhZyliPWEubWVtb2l6ZWRTdGF0ZSxiPW51bGwhPT1iP251bGwhPT1iLmRlaHlkcmF0ZWQ/ITA6ITE6ITA7aWYoYilyZXR1cm4gYTthPWEucmV0dXJufXdoaWxlKG51bGwhPT1hKTtyZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFdpKGEsYixjLGQsZSl7aWYoMD09PShhLm1vZGUmMSkpcmV0dXJuIGE9PT1iP2EuZmxhZ3N8PTY1NTM2OihhLmZsYWdzfD0xMjgsYy5mbGFnc3w9MTMxMDcyLGMuZmxhZ3MmPS01MjgwNSwxPT09Yy50YWcmJihudWxsPT09Yy5hbHRlcm5hdGU/Yy50YWc9MTc6KGI9Y2goLTEsMSksYi50YWc9MixkaChjLGIsMSkpKSxjLmxhbmVzfD0xKSxhO2EuZmxhZ3N8PTY1NTM2O2EubGFuZXM9ZTtyZXR1cm4gYX12YXIgWGk9dWEuUmVhY3RDdXJyZW50T3duZXIsVWc9ITE7ZnVuY3Rpb24gWWkoYSxiLGMsZCl7Yi5jaGlsZD1udWxsPT09YT9DaChiLG51bGwsYyxkKTpCaChiLGEuY2hpbGQsYyxkKX1cbmZ1bmN0aW9uIFppKGEsYixjLGQsZSl7Yz1jLnJlbmRlcjt2YXIgZj1iLnJlZjtUZyhiLGUpO2Q9WGgoYSxiLGMsZCxmLGUpO2M9YmkoKTtpZihudWxsIT09YSYmIVVnKXJldHVybiBiLnVwZGF0ZVF1ZXVlPWEudXBkYXRlUXVldWUsYi5mbGFncyY9LTIwNTMsYS5sYW5lcyY9fmUsJGkoYSxiLGUpO0kmJmMmJnZnKGIpO2IuZmxhZ3N8PTE7WWkoYSxiLGQsZSk7cmV0dXJuIGIuY2hpbGR9XG5mdW5jdGlvbiBhaihhLGIsYyxkLGUpe2lmKG51bGw9PT1hKXt2YXIgZj1jLnR5cGU7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGYmJiFiaihmKSYmdm9pZCAwPT09Zi5kZWZhdWx0UHJvcHMmJm51bGw9PT1jLmNvbXBhcmUmJnZvaWQgMD09PWMuZGVmYXVsdFByb3BzKXJldHVybiBiLnRhZz0xNSxiLnR5cGU9ZixjaihhLGIsZixkLGUpO2E9eWgoYy50eXBlLG51bGwsZCxiLGIubW9kZSxlKTthLnJlZj1iLnJlZjthLnJldHVybj1iO3JldHVybiBiLmNoaWxkPWF9Zj1hLmNoaWxkO2lmKDA9PT0oYS5sYW5lcyZlKSl7dmFyIGc9Zi5tZW1vaXplZFByb3BzO2M9Yy5jb21wYXJlO2M9bnVsbCE9PWM/YzpJZTtpZihjKGcsZCkmJmEucmVmPT09Yi5yZWYpcmV0dXJuICRpKGEsYixlKX1iLmZsYWdzfD0xO2E9d2goZixkKTthLnJlZj1iLnJlZjthLnJldHVybj1iO3JldHVybiBiLmNoaWxkPWF9XG5mdW5jdGlvbiBjaihhLGIsYyxkLGUpe2lmKG51bGwhPT1hKXt2YXIgZj1hLm1lbW9pemVkUHJvcHM7aWYoSWUoZixkKSYmYS5yZWY9PT1iLnJlZilpZihVZz0hMSxiLnBlbmRpbmdQcm9wcz1kPWYsMCE9PShhLmxhbmVzJmUpKTAhPT0oYS5mbGFncyYxMzEwNzIpJiYoVWc9ITApO2Vsc2UgcmV0dXJuIGIubGFuZXM9YS5sYW5lcywkaShhLGIsZSl9cmV0dXJuIGRqKGEsYixjLGQsZSl9XG5mdW5jdGlvbiBlaihhLGIsYyl7dmFyIGQ9Yi5wZW5kaW5nUHJvcHMsZT1kLmNoaWxkcmVuLGY9bnVsbCE9PWE/YS5tZW1vaXplZFN0YXRlOm51bGw7aWYoXCJoaWRkZW5cIj09PWQubW9kZSlpZigwPT09KGIubW9kZSYxKSliLm1lbW9pemVkU3RhdGU9e2Jhc2VMYW5lczowLGNhY2hlUG9vbDpudWxsLHRyYW5zaXRpb25zOm51bGx9LEcoZmosZ2opLGdqfD1jO2Vsc2V7aWYoMD09PShjJjEwNzM3NDE4MjQpKXJldHVybiBhPW51bGwhPT1mP2YuYmFzZUxhbmVzfGM6YyxiLmxhbmVzPWIuY2hpbGRMYW5lcz0xMDczNzQxODI0LGIubWVtb2l6ZWRTdGF0ZT17YmFzZUxhbmVzOmEsY2FjaGVQb29sOm51bGwsdHJhbnNpdGlvbnM6bnVsbH0sYi51cGRhdGVRdWV1ZT1udWxsLEcoZmosZ2opLGdqfD1hLG51bGw7Yi5tZW1vaXplZFN0YXRlPXtiYXNlTGFuZXM6MCxjYWNoZVBvb2w6bnVsbCx0cmFuc2l0aW9uczpudWxsfTtkPW51bGwhPT1mP2YuYmFzZUxhbmVzOmM7Ryhmaixnaik7Z2p8PWR9ZWxzZSBudWxsIT09XG5mPyhkPWYuYmFzZUxhbmVzfGMsYi5tZW1vaXplZFN0YXRlPW51bGwpOmQ9YyxHKGZqLGdqKSxnanw9ZDtZaShhLGIsZSxjKTtyZXR1cm4gYi5jaGlsZH1mdW5jdGlvbiBoaihhLGIpe3ZhciBjPWIucmVmO2lmKG51bGw9PT1hJiZudWxsIT09Y3x8bnVsbCE9PWEmJmEucmVmIT09YyliLmZsYWdzfD01MTIsYi5mbGFnc3w9MjA5NzE1Mn1mdW5jdGlvbiBkaihhLGIsYyxkLGUpe3ZhciBmPVpmKGMpP1hmOkguY3VycmVudDtmPVlmKGIsZik7VGcoYixlKTtjPVhoKGEsYixjLGQsZixlKTtkPWJpKCk7aWYobnVsbCE9PWEmJiFVZylyZXR1cm4gYi51cGRhdGVRdWV1ZT1hLnVwZGF0ZVF1ZXVlLGIuZmxhZ3MmPS0yMDUzLGEubGFuZXMmPX5lLCRpKGEsYixlKTtJJiZkJiZ2ZyhiKTtiLmZsYWdzfD0xO1lpKGEsYixjLGUpO3JldHVybiBiLmNoaWxkfVxuZnVuY3Rpb24gaWooYSxiLGMsZCxlKXtpZihaZihjKSl7dmFyIGY9ITA7Y2coYil9ZWxzZSBmPSExO1RnKGIsZSk7aWYobnVsbD09PWIuc3RhdGVOb2RlKWpqKGEsYikscGgoYixjLGQpLHJoKGIsYyxkLGUpLGQ9ITA7ZWxzZSBpZihudWxsPT09YSl7dmFyIGc9Yi5zdGF0ZU5vZGUsaD1iLm1lbW9pemVkUHJvcHM7Zy5wcm9wcz1oO3ZhciBrPWcuY29udGV4dCxsPWMuY29udGV4dFR5cGU7XCJvYmplY3RcIj09PXR5cGVvZiBsJiZudWxsIT09bD9sPVZnKGwpOihsPVpmKGMpP1hmOkguY3VycmVudCxsPVlmKGIsbCkpO3ZhciBtPWMuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLHE9XCJmdW5jdGlvblwiPT09dHlwZW9mIG18fFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlO3F8fFwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzfHxcbihoIT09ZHx8ayE9PWwpJiZxaChiLGcsZCxsKTskZz0hMTt2YXIgcj1iLm1lbW9pemVkU3RhdGU7Zy5zdGF0ZT1yO2doKGIsZCxnLGUpO2s9Yi5tZW1vaXplZFN0YXRlO2ghPT1kfHxyIT09a3x8V2YuY3VycmVudHx8JGc/KFwiZnVuY3Rpb25cIj09PXR5cGVvZiBtJiYoa2goYixjLG0sZCksaz1iLm1lbW9pemVkU3RhdGUpLChoPSRnfHxvaChiLGMsaCxkLHIsayxsKSk/KHF8fFwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQmJlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxNb3VudHx8KFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxNb3VudCYmZy5jb21wb25lbnRXaWxsTW91bnQoKSxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZy5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50JiZnLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQoKSksXCJmdW5jdGlvblwiPT09dHlwZW9mIGcuY29tcG9uZW50RGlkTW91bnQmJihiLmZsYWdzfD00MTk0MzA4KSk6XG4oXCJmdW5jdGlvblwiPT09dHlwZW9mIGcuY29tcG9uZW50RGlkTW91bnQmJihiLmZsYWdzfD00MTk0MzA4KSxiLm1lbW9pemVkUHJvcHM9ZCxiLm1lbW9pemVkU3RhdGU9ayksZy5wcm9wcz1kLGcuc3RhdGU9ayxnLmNvbnRleHQ9bCxkPWgpOihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZy5jb21wb25lbnREaWRNb3VudCYmKGIuZmxhZ3N8PTQxOTQzMDgpLGQ9ITEpfWVsc2V7Zz1iLnN0YXRlTm9kZTtiaChhLGIpO2g9Yi5tZW1vaXplZFByb3BzO2w9Yi50eXBlPT09Yi5lbGVtZW50VHlwZT9oOkxnKGIudHlwZSxoKTtnLnByb3BzPWw7cT1iLnBlbmRpbmdQcm9wcztyPWcuY29udGV4dDtrPWMuY29udGV4dFR5cGU7XCJvYmplY3RcIj09PXR5cGVvZiBrJiZudWxsIT09az9rPVZnKGspOihrPVpmKGMpP1hmOkguY3VycmVudCxrPVlmKGIsaykpO3ZhciB5PWMuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzOyhtPVwiZnVuY3Rpb25cIj09PXR5cGVvZiB5fHxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZy5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSl8fFxuXCJmdW5jdGlvblwiIT09dHlwZW9mIGcuVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMmJlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHN8fChoIT09cXx8ciE9PWspJiZxaChiLGcsZCxrKTskZz0hMTtyPWIubWVtb2l6ZWRTdGF0ZTtnLnN0YXRlPXI7Z2goYixkLGcsZSk7dmFyIG49Yi5tZW1vaXplZFN0YXRlO2ghPT1xfHxyIT09bnx8V2YuY3VycmVudHx8JGc/KFwiZnVuY3Rpb25cIj09PXR5cGVvZiB5JiYoa2goYixjLHksZCksbj1iLm1lbW9pemVkU3RhdGUpLChsPSRnfHxvaChiLGMsbCxkLHIsbixrKXx8ITEpPyhtfHxcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSYmXCJmdW5jdGlvblwiIT09dHlwZW9mIGcuY29tcG9uZW50V2lsbFVwZGF0ZXx8KFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxVcGRhdGUmJmcuY29tcG9uZW50V2lsbFVwZGF0ZShkLG4sayksXCJmdW5jdGlvblwiPT09dHlwZW9mIGcuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUmJlxuZy5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZShkLG4saykpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmNvbXBvbmVudERpZFVwZGF0ZSYmKGIuZmxhZ3N8PTQpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlJiYoYi5mbGFnc3w9MTAyNCkpOihcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5jb21wb25lbnREaWRVcGRhdGV8fGg9PT1hLm1lbW9pemVkUHJvcHMmJnI9PT1hLm1lbW9pemVkU3RhdGV8fChiLmZsYWdzfD00KSxcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZXx8aD09PWEubWVtb2l6ZWRQcm9wcyYmcj09PWEubWVtb2l6ZWRTdGF0ZXx8KGIuZmxhZ3N8PTEwMjQpLGIubWVtb2l6ZWRQcm9wcz1kLGIubWVtb2l6ZWRTdGF0ZT1uKSxnLnByb3BzPWQsZy5zdGF0ZT1uLGcuY29udGV4dD1rLGQ9bCk6KFwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLmNvbXBvbmVudERpZFVwZGF0ZXx8aD09PWEubWVtb2l6ZWRQcm9wcyYmcj09PVxuYS5tZW1vaXplZFN0YXRlfHwoYi5mbGFnc3w9NCksXCJmdW5jdGlvblwiIT09dHlwZW9mIGcuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGV8fGg9PT1hLm1lbW9pemVkUHJvcHMmJnI9PT1hLm1lbW9pemVkU3RhdGV8fChiLmZsYWdzfD0xMDI0KSxkPSExKX1yZXR1cm4ga2ooYSxiLGMsZCxmLGUpfVxuZnVuY3Rpb24ga2ooYSxiLGMsZCxlLGYpe2hqKGEsYik7dmFyIGc9MCE9PShiLmZsYWdzJjEyOCk7aWYoIWQmJiFnKXJldHVybiBlJiZkZyhiLGMsITEpLCRpKGEsYixmKTtkPWIuc3RhdGVOb2RlO1hpLmN1cnJlbnQ9Yjt2YXIgaD1nJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgYy5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3I/bnVsbDpkLnJlbmRlcigpO2IuZmxhZ3N8PTE7bnVsbCE9PWEmJmc/KGIuY2hpbGQ9QmgoYixhLmNoaWxkLG51bGwsZiksYi5jaGlsZD1CaChiLG51bGwsaCxmKSk6WWkoYSxiLGgsZik7Yi5tZW1vaXplZFN0YXRlPWQuc3RhdGU7ZSYmZGcoYixjLCEwKTtyZXR1cm4gYi5jaGlsZH1mdW5jdGlvbiBsaihhKXt2YXIgYj1hLnN0YXRlTm9kZTtiLnBlbmRpbmdDb250ZXh0P2FnKGEsYi5wZW5kaW5nQ29udGV4dCxiLnBlbmRpbmdDb250ZXh0IT09Yi5jb250ZXh0KTpiLmNvbnRleHQmJmFnKGEsYi5jb250ZXh0LCExKTtJaChhLGIuY29udGFpbmVySW5mbyl9XG5mdW5jdGlvbiBtaihhLGIsYyxkLGUpe0lnKCk7SmcoZSk7Yi5mbGFnc3w9MjU2O1lpKGEsYixjLGQpO3JldHVybiBiLmNoaWxkfXZhciBuaj17ZGVoeWRyYXRlZDpudWxsLHRyZWVDb250ZXh0Om51bGwscmV0cnlMYW5lOjB9O2Z1bmN0aW9uIG9qKGEpe3JldHVybntiYXNlTGFuZXM6YSxjYWNoZVBvb2w6bnVsbCx0cmFuc2l0aW9uczpudWxsfX1cbmZ1bmN0aW9uIHBqKGEsYixjKXt2YXIgZD1iLnBlbmRpbmdQcm9wcyxlPU0uY3VycmVudCxmPSExLGc9MCE9PShiLmZsYWdzJjEyOCksaDsoaD1nKXx8KGg9bnVsbCE9PWEmJm51bGw9PT1hLm1lbW9pemVkU3RhdGU/ITE6MCE9PShlJjIpKTtpZihoKWY9ITAsYi5mbGFncyY9LTEyOTtlbHNlIGlmKG51bGw9PT1hfHxudWxsIT09YS5tZW1vaXplZFN0YXRlKWV8PTE7RyhNLGUmMSk7aWYobnVsbD09PWEpe0VnKGIpO2E9Yi5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1hJiYoYT1hLmRlaHlkcmF0ZWQsbnVsbCE9PWEpKXJldHVybiAwPT09KGIubW9kZSYxKT9iLmxhbmVzPTE6XCIkIVwiPT09YS5kYXRhP2IubGFuZXM9ODpiLmxhbmVzPTEwNzM3NDE4MjQsbnVsbDtnPWQuY2hpbGRyZW47YT1kLmZhbGxiYWNrO3JldHVybiBmPyhkPWIubW9kZSxmPWIuY2hpbGQsZz17bW9kZTpcImhpZGRlblwiLGNoaWxkcmVuOmd9LDA9PT0oZCYxKSYmbnVsbCE9PWY/KGYuY2hpbGRMYW5lcz0wLGYucGVuZGluZ1Byb3BzPVxuZyk6Zj1xaihnLGQsMCxudWxsKSxhPUFoKGEsZCxjLG51bGwpLGYucmV0dXJuPWIsYS5yZXR1cm49YixmLnNpYmxpbmc9YSxiLmNoaWxkPWYsYi5jaGlsZC5tZW1vaXplZFN0YXRlPW9qKGMpLGIubWVtb2l6ZWRTdGF0ZT1uaixhKTpyaihiLGcpfWU9YS5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1lJiYoaD1lLmRlaHlkcmF0ZWQsbnVsbCE9PWgpKXJldHVybiBzaihhLGIsZyxkLGgsZSxjKTtpZihmKXtmPWQuZmFsbGJhY2s7Zz1iLm1vZGU7ZT1hLmNoaWxkO2g9ZS5zaWJsaW5nO3ZhciBrPXttb2RlOlwiaGlkZGVuXCIsY2hpbGRyZW46ZC5jaGlsZHJlbn07MD09PShnJjEpJiZiLmNoaWxkIT09ZT8oZD1iLmNoaWxkLGQuY2hpbGRMYW5lcz0wLGQucGVuZGluZ1Byb3BzPWssYi5kZWxldGlvbnM9bnVsbCk6KGQ9d2goZSxrKSxkLnN1YnRyZWVGbGFncz1lLnN1YnRyZWVGbGFncyYxNDY4MDA2NCk7bnVsbCE9PWg/Zj13aChoLGYpOihmPUFoKGYsZyxjLG51bGwpLGYuZmxhZ3N8PTIpO2YucmV0dXJuPVxuYjtkLnJldHVybj1iO2Quc2libGluZz1mO2IuY2hpbGQ9ZDtkPWY7Zj1iLmNoaWxkO2c9YS5jaGlsZC5tZW1vaXplZFN0YXRlO2c9bnVsbD09PWc/b2ooYyk6e2Jhc2VMYW5lczpnLmJhc2VMYW5lc3xjLGNhY2hlUG9vbDpudWxsLHRyYW5zaXRpb25zOmcudHJhbnNpdGlvbnN9O2YubWVtb2l6ZWRTdGF0ZT1nO2YuY2hpbGRMYW5lcz1hLmNoaWxkTGFuZXMmfmM7Yi5tZW1vaXplZFN0YXRlPW5qO3JldHVybiBkfWY9YS5jaGlsZDthPWYuc2libGluZztkPXdoKGYse21vZGU6XCJ2aXNpYmxlXCIsY2hpbGRyZW46ZC5jaGlsZHJlbn0pOzA9PT0oYi5tb2RlJjEpJiYoZC5sYW5lcz1jKTtkLnJldHVybj1iO2Quc2libGluZz1udWxsO251bGwhPT1hJiYoYz1iLmRlbGV0aW9ucyxudWxsPT09Yz8oYi5kZWxldGlvbnM9W2FdLGIuZmxhZ3N8PTE2KTpjLnB1c2goYSkpO2IuY2hpbGQ9ZDtiLm1lbW9pemVkU3RhdGU9bnVsbDtyZXR1cm4gZH1cbmZ1bmN0aW9uIHJqKGEsYil7Yj1xaih7bW9kZTpcInZpc2libGVcIixjaGlsZHJlbjpifSxhLm1vZGUsMCxudWxsKTtiLnJldHVybj1hO3JldHVybiBhLmNoaWxkPWJ9ZnVuY3Rpb24gdGooYSxiLGMsZCl7bnVsbCE9PWQmJkpnKGQpO0JoKGIsYS5jaGlsZCxudWxsLGMpO2E9cmooYixiLnBlbmRpbmdQcm9wcy5jaGlsZHJlbik7YS5mbGFnc3w9MjtiLm1lbW9pemVkU3RhdGU9bnVsbDtyZXR1cm4gYX1cbmZ1bmN0aW9uIHNqKGEsYixjLGQsZSxmLGcpe2lmKGMpe2lmKGIuZmxhZ3MmMjU2KXJldHVybiBiLmZsYWdzJj0tMjU3LGQ9TGkoRXJyb3IocCg0MjIpKSksdGooYSxiLGcsZCk7aWYobnVsbCE9PWIubWVtb2l6ZWRTdGF0ZSlyZXR1cm4gYi5jaGlsZD1hLmNoaWxkLGIuZmxhZ3N8PTEyOCxudWxsO2Y9ZC5mYWxsYmFjaztlPWIubW9kZTtkPXFqKHttb2RlOlwidmlzaWJsZVwiLGNoaWxkcmVuOmQuY2hpbGRyZW59LGUsMCxudWxsKTtmPUFoKGYsZSxnLG51bGwpO2YuZmxhZ3N8PTI7ZC5yZXR1cm49YjtmLnJldHVybj1iO2Quc2libGluZz1mO2IuY2hpbGQ9ZDswIT09KGIubW9kZSYxKSYmQmgoYixhLmNoaWxkLG51bGwsZyk7Yi5jaGlsZC5tZW1vaXplZFN0YXRlPW9qKGcpO2IubWVtb2l6ZWRTdGF0ZT1uajtyZXR1cm4gZn1pZigwPT09KGIubW9kZSYxKSlyZXR1cm4gdGooYSxiLGcsbnVsbCk7aWYoXCIkIVwiPT09ZS5kYXRhKXtkPWUubmV4dFNpYmxpbmcmJmUubmV4dFNpYmxpbmcuZGF0YXNldDtcbmlmKGQpdmFyIGg9ZC5kZ3N0O2Q9aDtmPUVycm9yKHAoNDE5KSk7ZD1MaShmLGQsdm9pZCAwKTtyZXR1cm4gdGooYSxiLGcsZCl9aD0wIT09KGcmYS5jaGlsZExhbmVzKTtpZihVZ3x8aCl7ZD1SO2lmKG51bGwhPT1kKXtzd2l0Y2goZyYtZyl7Y2FzZSA0OmU9MjticmVhaztjYXNlIDE2OmU9ODticmVhaztjYXNlIDY0OmNhc2UgMTI4OmNhc2UgMjU2OmNhc2UgNTEyOmNhc2UgMTAyNDpjYXNlIDIwNDg6Y2FzZSA0MDk2OmNhc2UgODE5MjpjYXNlIDE2Mzg0OmNhc2UgMzI3Njg6Y2FzZSA2NTUzNjpjYXNlIDEzMTA3MjpjYXNlIDI2MjE0NDpjYXNlIDUyNDI4ODpjYXNlIDEwNDg1NzY6Y2FzZSAyMDk3MTUyOmNhc2UgNDE5NDMwNDpjYXNlIDgzODg2MDg6Y2FzZSAxNjc3NzIxNjpjYXNlIDMzNTU0NDMyOmNhc2UgNjcxMDg4NjQ6ZT0zMjticmVhaztjYXNlIDUzNjg3MDkxMjplPTI2ODQzNTQ1NjticmVhaztkZWZhdWx0OmU9MH1lPTAhPT0oZSYoZC5zdXNwZW5kZWRMYW5lc3xnKSk/MDplO1xuMCE9PWUmJmUhPT1mLnJldHJ5TGFuZSYmKGYucmV0cnlMYW5lPWUsWmcoYSxlKSxtaChkLGEsZSwtMSkpfXVqKCk7ZD1MaShFcnJvcihwKDQyMSkpKTtyZXR1cm4gdGooYSxiLGcsZCl9aWYoXCIkP1wiPT09ZS5kYXRhKXJldHVybiBiLmZsYWdzfD0xMjgsYi5jaGlsZD1hLmNoaWxkLGI9dmouYmluZChudWxsLGEpLGUuX3JlYWN0UmV0cnk9YixudWxsO2E9Zi50cmVlQ29udGV4dDt5Zz1MZihlLm5leHRTaWJsaW5nKTt4Zz1iO0k9ITA7emc9bnVsbDtudWxsIT09YSYmKG9nW3BnKytdPXJnLG9nW3BnKytdPXNnLG9nW3BnKytdPXFnLHJnPWEuaWQsc2c9YS5vdmVyZmxvdyxxZz1iKTtiPXJqKGIsZC5jaGlsZHJlbik7Yi5mbGFnc3w9NDA5NjtyZXR1cm4gYn1mdW5jdGlvbiB3aihhLGIsYyl7YS5sYW5lc3w9Yjt2YXIgZD1hLmFsdGVybmF0ZTtudWxsIT09ZCYmKGQubGFuZXN8PWIpO1NnKGEucmV0dXJuLGIsYyl9XG5mdW5jdGlvbiB4aihhLGIsYyxkLGUpe3ZhciBmPWEubWVtb2l6ZWRTdGF0ZTtudWxsPT09Zj9hLm1lbW9pemVkU3RhdGU9e2lzQmFja3dhcmRzOmIscmVuZGVyaW5nOm51bGwscmVuZGVyaW5nU3RhcnRUaW1lOjAsbGFzdDpkLHRhaWw6Yyx0YWlsTW9kZTplfTooZi5pc0JhY2t3YXJkcz1iLGYucmVuZGVyaW5nPW51bGwsZi5yZW5kZXJpbmdTdGFydFRpbWU9MCxmLmxhc3Q9ZCxmLnRhaWw9YyxmLnRhaWxNb2RlPWUpfVxuZnVuY3Rpb24geWooYSxiLGMpe3ZhciBkPWIucGVuZGluZ1Byb3BzLGU9ZC5yZXZlYWxPcmRlcixmPWQudGFpbDtZaShhLGIsZC5jaGlsZHJlbixjKTtkPU0uY3VycmVudDtpZigwIT09KGQmMikpZD1kJjF8MixiLmZsYWdzfD0xMjg7ZWxzZXtpZihudWxsIT09YSYmMCE9PShhLmZsYWdzJjEyOCkpYTpmb3IoYT1iLmNoaWxkO251bGwhPT1hOyl7aWYoMTM9PT1hLnRhZyludWxsIT09YS5tZW1vaXplZFN0YXRlJiZ3aihhLGMsYik7ZWxzZSBpZigxOT09PWEudGFnKXdqKGEsYyxiKTtlbHNlIGlmKG51bGwhPT1hLmNoaWxkKXthLmNoaWxkLnJldHVybj1hO2E9YS5jaGlsZDtjb250aW51ZX1pZihhPT09YilicmVhayBhO2Zvcig7bnVsbD09PWEuc2libGluZzspe2lmKG51bGw9PT1hLnJldHVybnx8YS5yZXR1cm49PT1iKWJyZWFrIGE7YT1hLnJldHVybn1hLnNpYmxpbmcucmV0dXJuPWEucmV0dXJuO2E9YS5zaWJsaW5nfWQmPTF9RyhNLGQpO2lmKDA9PT0oYi5tb2RlJjEpKWIubWVtb2l6ZWRTdGF0ZT1cbm51bGw7ZWxzZSBzd2l0Y2goZSl7Y2FzZSBcImZvcndhcmRzXCI6Yz1iLmNoaWxkO2ZvcihlPW51bGw7bnVsbCE9PWM7KWE9Yy5hbHRlcm5hdGUsbnVsbCE9PWEmJm51bGw9PT1NaChhKSYmKGU9YyksYz1jLnNpYmxpbmc7Yz1lO251bGw9PT1jPyhlPWIuY2hpbGQsYi5jaGlsZD1udWxsKTooZT1jLnNpYmxpbmcsYy5zaWJsaW5nPW51bGwpO3hqKGIsITEsZSxjLGYpO2JyZWFrO2Nhc2UgXCJiYWNrd2FyZHNcIjpjPW51bGw7ZT1iLmNoaWxkO2ZvcihiLmNoaWxkPW51bGw7bnVsbCE9PWU7KXthPWUuYWx0ZXJuYXRlO2lmKG51bGwhPT1hJiZudWxsPT09TWgoYSkpe2IuY2hpbGQ9ZTticmVha31hPWUuc2libGluZztlLnNpYmxpbmc9YztjPWU7ZT1hfXhqKGIsITAsYyxudWxsLGYpO2JyZWFrO2Nhc2UgXCJ0b2dldGhlclwiOnhqKGIsITEsbnVsbCxudWxsLHZvaWQgMCk7YnJlYWs7ZGVmYXVsdDpiLm1lbW9pemVkU3RhdGU9bnVsbH1yZXR1cm4gYi5jaGlsZH1cbmZ1bmN0aW9uIGpqKGEsYil7MD09PShiLm1vZGUmMSkmJm51bGwhPT1hJiYoYS5hbHRlcm5hdGU9bnVsbCxiLmFsdGVybmF0ZT1udWxsLGIuZmxhZ3N8PTIpfWZ1bmN0aW9uICRpKGEsYixjKXtudWxsIT09YSYmKGIuZGVwZW5kZW5jaWVzPWEuZGVwZW5kZW5jaWVzKTtoaHw9Yi5sYW5lcztpZigwPT09KGMmYi5jaGlsZExhbmVzKSlyZXR1cm4gbnVsbDtpZihudWxsIT09YSYmYi5jaGlsZCE9PWEuY2hpbGQpdGhyb3cgRXJyb3IocCgxNTMpKTtpZihudWxsIT09Yi5jaGlsZCl7YT1iLmNoaWxkO2M9d2goYSxhLnBlbmRpbmdQcm9wcyk7Yi5jaGlsZD1jO2ZvcihjLnJldHVybj1iO251bGwhPT1hLnNpYmxpbmc7KWE9YS5zaWJsaW5nLGM9Yy5zaWJsaW5nPXdoKGEsYS5wZW5kaW5nUHJvcHMpLGMucmV0dXJuPWI7Yy5zaWJsaW5nPW51bGx9cmV0dXJuIGIuY2hpbGR9XG5mdW5jdGlvbiB6aihhLGIsYyl7c3dpdGNoKGIudGFnKXtjYXNlIDM6bGooYik7SWcoKTticmVhaztjYXNlIDU6S2goYik7YnJlYWs7Y2FzZSAxOlpmKGIudHlwZSkmJmNnKGIpO2JyZWFrO2Nhc2UgNDpJaChiLGIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8pO2JyZWFrO2Nhc2UgMTA6dmFyIGQ9Yi50eXBlLl9jb250ZXh0LGU9Yi5tZW1vaXplZFByb3BzLnZhbHVlO0coTWcsZC5fY3VycmVudFZhbHVlKTtkLl9jdXJyZW50VmFsdWU9ZTticmVhaztjYXNlIDEzOmQ9Yi5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1kKXtpZihudWxsIT09ZC5kZWh5ZHJhdGVkKXJldHVybiBHKE0sTS5jdXJyZW50JjEpLGIuZmxhZ3N8PTEyOCxudWxsO2lmKDAhPT0oYyZiLmNoaWxkLmNoaWxkTGFuZXMpKXJldHVybiBwaihhLGIsYyk7RyhNLE0uY3VycmVudCYxKTthPSRpKGEsYixjKTtyZXR1cm4gbnVsbCE9PWE/YS5zaWJsaW5nOm51bGx9RyhNLE0uY3VycmVudCYxKTticmVhaztjYXNlIDE5OmQ9MCE9PShjJlxuYi5jaGlsZExhbmVzKTtpZigwIT09KGEuZmxhZ3MmMTI4KSl7aWYoZClyZXR1cm4geWooYSxiLGMpO2IuZmxhZ3N8PTEyOH1lPWIubWVtb2l6ZWRTdGF0ZTtudWxsIT09ZSYmKGUucmVuZGVyaW5nPW51bGwsZS50YWlsPW51bGwsZS5sYXN0RWZmZWN0PW51bGwpO0coTSxNLmN1cnJlbnQpO2lmKGQpYnJlYWs7ZWxzZSByZXR1cm4gbnVsbDtjYXNlIDIyOmNhc2UgMjM6cmV0dXJuIGIubGFuZXM9MCxlaihhLGIsYyl9cmV0dXJuICRpKGEsYixjKX12YXIgQWosQmosQ2osRGo7XG5Baj1mdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1iLmNoaWxkO251bGwhPT1jOyl7aWYoNT09PWMudGFnfHw2PT09Yy50YWcpYS5hcHBlbmRDaGlsZChjLnN0YXRlTm9kZSk7ZWxzZSBpZig0IT09Yy50YWcmJm51bGwhPT1jLmNoaWxkKXtjLmNoaWxkLnJldHVybj1jO2M9Yy5jaGlsZDtjb250aW51ZX1pZihjPT09YilicmVhaztmb3IoO251bGw9PT1jLnNpYmxpbmc7KXtpZihudWxsPT09Yy5yZXR1cm58fGMucmV0dXJuPT09YilyZXR1cm47Yz1jLnJldHVybn1jLnNpYmxpbmcucmV0dXJuPWMucmV0dXJuO2M9Yy5zaWJsaW5nfX07Qmo9ZnVuY3Rpb24oKXt9O1xuQ2o9ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9YS5tZW1vaXplZFByb3BzO2lmKGUhPT1kKXthPWIuc3RhdGVOb2RlO0hoKEVoLmN1cnJlbnQpO3ZhciBmPW51bGw7c3dpdGNoKGMpe2Nhc2UgXCJpbnB1dFwiOmU9WWEoYSxlKTtkPVlhKGEsZCk7Zj1bXTticmVhaztjYXNlIFwic2VsZWN0XCI6ZT1BKHt9LGUse3ZhbHVlOnZvaWQgMH0pO2Q9QSh7fSxkLHt2YWx1ZTp2b2lkIDB9KTtmPVtdO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmU9Z2IoYSxlKTtkPWdiKGEsZCk7Zj1bXTticmVhaztkZWZhdWx0OlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBlLm9uQ2xpY2smJlwiZnVuY3Rpb25cIj09PXR5cGVvZiBkLm9uQ2xpY2smJihhLm9uY2xpY2s9QmYpfXViKGMsZCk7dmFyIGc7Yz1udWxsO2ZvcihsIGluIGUpaWYoIWQuaGFzT3duUHJvcGVydHkobCkmJmUuaGFzT3duUHJvcGVydHkobCkmJm51bGwhPWVbbF0paWYoXCJzdHlsZVwiPT09bCl7dmFyIGg9ZVtsXTtmb3IoZyBpbiBoKWguaGFzT3duUHJvcGVydHkoZykmJlxuKGN8fChjPXt9KSxjW2ddPVwiXCIpfWVsc2VcImRhbmdlcm91c2x5U2V0SW5uZXJIVE1MXCIhPT1sJiZcImNoaWxkcmVuXCIhPT1sJiZcInN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZ1wiIT09bCYmXCJzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmdcIiE9PWwmJlwiYXV0b0ZvY3VzXCIhPT1sJiYoZWEuaGFzT3duUHJvcGVydHkobCk/Znx8KGY9W10pOihmPWZ8fFtdKS5wdXNoKGwsbnVsbCkpO2ZvcihsIGluIGQpe3ZhciBrPWRbbF07aD1udWxsIT1lP2VbbF06dm9pZCAwO2lmKGQuaGFzT3duUHJvcGVydHkobCkmJmshPT1oJiYobnVsbCE9a3x8bnVsbCE9aCkpaWYoXCJzdHlsZVwiPT09bClpZihoKXtmb3IoZyBpbiBoKSFoLmhhc093blByb3BlcnR5KGcpfHxrJiZrLmhhc093blByb3BlcnR5KGcpfHwoY3x8KGM9e30pLGNbZ109XCJcIik7Zm9yKGcgaW4gaylrLmhhc093blByb3BlcnR5KGcpJiZoW2ddIT09a1tnXSYmKGN8fChjPXt9KSxjW2ddPWtbZ10pfWVsc2UgY3x8KGZ8fChmPVtdKSxmLnB1c2gobCxcbmMpKSxjPWs7ZWxzZVwiZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUxcIj09PWw/KGs9az9rLl9faHRtbDp2b2lkIDAsaD1oP2guX19odG1sOnZvaWQgMCxudWxsIT1rJiZoIT09ayYmKGY9Znx8W10pLnB1c2gobCxrKSk6XCJjaGlsZHJlblwiPT09bD9cInN0cmluZ1wiIT09dHlwZW9mIGsmJlwibnVtYmVyXCIhPT10eXBlb2Yga3x8KGY9Znx8W10pLnB1c2gobCxcIlwiK2spOlwic3VwcHJlc3NDb250ZW50RWRpdGFibGVXYXJuaW5nXCIhPT1sJiZcInN1cHByZXNzSHlkcmF0aW9uV2FybmluZ1wiIT09bCYmKGVhLmhhc093blByb3BlcnR5KGwpPyhudWxsIT1rJiZcIm9uU2Nyb2xsXCI9PT1sJiZEKFwic2Nyb2xsXCIsYSksZnx8aD09PWt8fChmPVtdKSk6KGY9Znx8W10pLnB1c2gobCxrKSl9YyYmKGY9Znx8W10pLnB1c2goXCJzdHlsZVwiLGMpO3ZhciBsPWY7aWYoYi51cGRhdGVRdWV1ZT1sKWIuZmxhZ3N8PTR9fTtEaj1mdW5jdGlvbihhLGIsYyxkKXtjIT09ZCYmKGIuZmxhZ3N8PTQpfTtcbmZ1bmN0aW9uIEVqKGEsYil7aWYoIUkpc3dpdGNoKGEudGFpbE1vZGUpe2Nhc2UgXCJoaWRkZW5cIjpiPWEudGFpbDtmb3IodmFyIGM9bnVsbDtudWxsIT09YjspbnVsbCE9PWIuYWx0ZXJuYXRlJiYoYz1iKSxiPWIuc2libGluZztudWxsPT09Yz9hLnRhaWw9bnVsbDpjLnNpYmxpbmc9bnVsbDticmVhaztjYXNlIFwiY29sbGFwc2VkXCI6Yz1hLnRhaWw7Zm9yKHZhciBkPW51bGw7bnVsbCE9PWM7KW51bGwhPT1jLmFsdGVybmF0ZSYmKGQ9YyksYz1jLnNpYmxpbmc7bnVsbD09PWQ/Ynx8bnVsbD09PWEudGFpbD9hLnRhaWw9bnVsbDphLnRhaWwuc2libGluZz1udWxsOmQuc2libGluZz1udWxsfX1cbmZ1bmN0aW9uIFMoYSl7dmFyIGI9bnVsbCE9PWEuYWx0ZXJuYXRlJiZhLmFsdGVybmF0ZS5jaGlsZD09PWEuY2hpbGQsYz0wLGQ9MDtpZihiKWZvcih2YXIgZT1hLmNoaWxkO251bGwhPT1lOyljfD1lLmxhbmVzfGUuY2hpbGRMYW5lcyxkfD1lLnN1YnRyZWVGbGFncyYxNDY4MDA2NCxkfD1lLmZsYWdzJjE0NjgwMDY0LGUucmV0dXJuPWEsZT1lLnNpYmxpbmc7ZWxzZSBmb3IoZT1hLmNoaWxkO251bGwhPT1lOyljfD1lLmxhbmVzfGUuY2hpbGRMYW5lcyxkfD1lLnN1YnRyZWVGbGFncyxkfD1lLmZsYWdzLGUucmV0dXJuPWEsZT1lLnNpYmxpbmc7YS5zdWJ0cmVlRmxhZ3N8PWQ7YS5jaGlsZExhbmVzPWM7cmV0dXJuIGJ9XG5mdW5jdGlvbiBGaihhLGIsYyl7dmFyIGQ9Yi5wZW5kaW5nUHJvcHM7d2coYik7c3dpdGNoKGIudGFnKXtjYXNlIDI6Y2FzZSAxNjpjYXNlIDE1OmNhc2UgMDpjYXNlIDExOmNhc2UgNzpjYXNlIDg6Y2FzZSAxMjpjYXNlIDk6Y2FzZSAxNDpyZXR1cm4gUyhiKSxudWxsO2Nhc2UgMTpyZXR1cm4gWmYoYi50eXBlKSYmJGYoKSxTKGIpLG51bGw7Y2FzZSAzOmQ9Yi5zdGF0ZU5vZGU7SmgoKTtFKFdmKTtFKEgpO09oKCk7ZC5wZW5kaW5nQ29udGV4dCYmKGQuY29udGV4dD1kLnBlbmRpbmdDb250ZXh0LGQucGVuZGluZ0NvbnRleHQ9bnVsbCk7aWYobnVsbD09PWF8fG51bGw9PT1hLmNoaWxkKUdnKGIpP2IuZmxhZ3N8PTQ6bnVsbD09PWF8fGEubWVtb2l6ZWRTdGF0ZS5pc0RlaHlkcmF0ZWQmJjA9PT0oYi5mbGFncyYyNTYpfHwoYi5mbGFnc3w9MTAyNCxudWxsIT09emcmJihHaih6Zyksemc9bnVsbCkpO0JqKGEsYik7UyhiKTtyZXR1cm4gbnVsbDtjYXNlIDU6TGgoYik7dmFyIGU9SGgoR2guY3VycmVudCk7XG5jPWIudHlwZTtpZihudWxsIT09YSYmbnVsbCE9Yi5zdGF0ZU5vZGUpQ2ooYSxiLGMsZCxlKSxhLnJlZiE9PWIucmVmJiYoYi5mbGFnc3w9NTEyLGIuZmxhZ3N8PTIwOTcxNTIpO2Vsc2V7aWYoIWQpe2lmKG51bGw9PT1iLnN0YXRlTm9kZSl0aHJvdyBFcnJvcihwKDE2NikpO1MoYik7cmV0dXJuIG51bGx9YT1IaChFaC5jdXJyZW50KTtpZihHZyhiKSl7ZD1iLnN0YXRlTm9kZTtjPWIudHlwZTt2YXIgZj1iLm1lbW9pemVkUHJvcHM7ZFtPZl09YjtkW1BmXT1mO2E9MCE9PShiLm1vZGUmMSk7c3dpdGNoKGMpe2Nhc2UgXCJkaWFsb2dcIjpEKFwiY2FuY2VsXCIsZCk7RChcImNsb3NlXCIsZCk7YnJlYWs7Y2FzZSBcImlmcmFtZVwiOmNhc2UgXCJvYmplY3RcIjpjYXNlIFwiZW1iZWRcIjpEKFwibG9hZFwiLGQpO2JyZWFrO2Nhc2UgXCJ2aWRlb1wiOmNhc2UgXCJhdWRpb1wiOmZvcihlPTA7ZTxsZi5sZW5ndGg7ZSsrKUQobGZbZV0sZCk7YnJlYWs7Y2FzZSBcInNvdXJjZVwiOkQoXCJlcnJvclwiLGQpO2JyZWFrO2Nhc2UgXCJpbWdcIjpjYXNlIFwiaW1hZ2VcIjpjYXNlIFwibGlua1wiOkQoXCJlcnJvclwiLFxuZCk7RChcImxvYWRcIixkKTticmVhaztjYXNlIFwiZGV0YWlsc1wiOkQoXCJ0b2dnbGVcIixkKTticmVhaztjYXNlIFwiaW5wdXRcIjpaYShkLGYpO0QoXCJpbnZhbGlkXCIsZCk7YnJlYWs7Y2FzZSBcInNlbGVjdFwiOmQuX3dyYXBwZXJTdGF0ZT17d2FzTXVsdGlwbGU6ISFmLm11bHRpcGxlfTtEKFwiaW52YWxpZFwiLGQpO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmhiKGQsZiksRChcImludmFsaWRcIixkKX11YihjLGYpO2U9bnVsbDtmb3IodmFyIGcgaW4gZilpZihmLmhhc093blByb3BlcnR5KGcpKXt2YXIgaD1mW2ddO1wiY2hpbGRyZW5cIj09PWc/XCJzdHJpbmdcIj09PXR5cGVvZiBoP2QudGV4dENvbnRlbnQhPT1oJiYoITAhPT1mLnN1cHByZXNzSHlkcmF0aW9uV2FybmluZyYmQWYoZC50ZXh0Q29udGVudCxoLGEpLGU9W1wiY2hpbGRyZW5cIixoXSk6XCJudW1iZXJcIj09PXR5cGVvZiBoJiZkLnRleHRDb250ZW50IT09XCJcIitoJiYoITAhPT1mLnN1cHByZXNzSHlkcmF0aW9uV2FybmluZyYmQWYoZC50ZXh0Q29udGVudCxcbmgsYSksZT1bXCJjaGlsZHJlblwiLFwiXCIraF0pOmVhLmhhc093blByb3BlcnR5KGcpJiZudWxsIT1oJiZcIm9uU2Nyb2xsXCI9PT1nJiZEKFwic2Nyb2xsXCIsZCl9c3dpdGNoKGMpe2Nhc2UgXCJpbnB1dFwiOlZhKGQpO2RiKGQsZiwhMCk7YnJlYWs7Y2FzZSBcInRleHRhcmVhXCI6VmEoZCk7amIoZCk7YnJlYWs7Y2FzZSBcInNlbGVjdFwiOmNhc2UgXCJvcHRpb25cIjpicmVhaztkZWZhdWx0OlwiZnVuY3Rpb25cIj09PXR5cGVvZiBmLm9uQ2xpY2smJihkLm9uY2xpY2s9QmYpfWQ9ZTtiLnVwZGF0ZVF1ZXVlPWQ7bnVsbCE9PWQmJihiLmZsYWdzfD00KX1lbHNle2c9OT09PWUubm9kZVR5cGU/ZTplLm93bmVyRG9jdW1lbnQ7XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI9PT1hJiYoYT1rYihjKSk7XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI9PT1hP1wic2NyaXB0XCI9PT1jPyhhPWcuY3JlYXRlRWxlbWVudChcImRpdlwiKSxhLmlubmVySFRNTD1cIjxzY3JpcHQ+XFx4M2Mvc2NyaXB0PlwiLGE9YS5yZW1vdmVDaGlsZChhLmZpcnN0Q2hpbGQpKTpcblwic3RyaW5nXCI9PT10eXBlb2YgZC5pcz9hPWcuY3JlYXRlRWxlbWVudChjLHtpczpkLmlzfSk6KGE9Zy5jcmVhdGVFbGVtZW50KGMpLFwic2VsZWN0XCI9PT1jJiYoZz1hLGQubXVsdGlwbGU/Zy5tdWx0aXBsZT0hMDpkLnNpemUmJihnLnNpemU9ZC5zaXplKSkpOmE9Zy5jcmVhdGVFbGVtZW50TlMoYSxjKTthW09mXT1iO2FbUGZdPWQ7QWooYSxiLCExLCExKTtiLnN0YXRlTm9kZT1hO2E6e2c9dmIoYyxkKTtzd2l0Y2goYyl7Y2FzZSBcImRpYWxvZ1wiOkQoXCJjYW5jZWxcIixhKTtEKFwiY2xvc2VcIixhKTtlPWQ7YnJlYWs7Y2FzZSBcImlmcmFtZVwiOmNhc2UgXCJvYmplY3RcIjpjYXNlIFwiZW1iZWRcIjpEKFwibG9hZFwiLGEpO2U9ZDticmVhaztjYXNlIFwidmlkZW9cIjpjYXNlIFwiYXVkaW9cIjpmb3IoZT0wO2U8bGYubGVuZ3RoO2UrKylEKGxmW2VdLGEpO2U9ZDticmVhaztjYXNlIFwic291cmNlXCI6RChcImVycm9yXCIsYSk7ZT1kO2JyZWFrO2Nhc2UgXCJpbWdcIjpjYXNlIFwiaW1hZ2VcIjpjYXNlIFwibGlua1wiOkQoXCJlcnJvclwiLFxuYSk7RChcImxvYWRcIixhKTtlPWQ7YnJlYWs7Y2FzZSBcImRldGFpbHNcIjpEKFwidG9nZ2xlXCIsYSk7ZT1kO2JyZWFrO2Nhc2UgXCJpbnB1dFwiOlphKGEsZCk7ZT1ZYShhLGQpO0QoXCJpbnZhbGlkXCIsYSk7YnJlYWs7Y2FzZSBcIm9wdGlvblwiOmU9ZDticmVhaztjYXNlIFwic2VsZWN0XCI6YS5fd3JhcHBlclN0YXRlPXt3YXNNdWx0aXBsZTohIWQubXVsdGlwbGV9O2U9QSh7fSxkLHt2YWx1ZTp2b2lkIDB9KTtEKFwiaW52YWxpZFwiLGEpO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmhiKGEsZCk7ZT1nYihhLGQpO0QoXCJpbnZhbGlkXCIsYSk7YnJlYWs7ZGVmYXVsdDplPWR9dWIoYyxlKTtoPWU7Zm9yKGYgaW4gaClpZihoLmhhc093blByb3BlcnR5KGYpKXt2YXIgaz1oW2ZdO1wic3R5bGVcIj09PWY/c2IoYSxrKTpcImRhbmdlcm91c2x5U2V0SW5uZXJIVE1MXCI9PT1mPyhrPWs/ay5fX2h0bWw6dm9pZCAwLG51bGwhPWsmJm5iKGEsaykpOlwiY2hpbGRyZW5cIj09PWY/XCJzdHJpbmdcIj09PXR5cGVvZiBrPyhcInRleHRhcmVhXCIhPT1cbmN8fFwiXCIhPT1rKSYmb2IoYSxrKTpcIm51bWJlclwiPT09dHlwZW9mIGsmJm9iKGEsXCJcIitrKTpcInN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZ1wiIT09ZiYmXCJzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmdcIiE9PWYmJlwiYXV0b0ZvY3VzXCIhPT1mJiYoZWEuaGFzT3duUHJvcGVydHkoZik/bnVsbCE9ayYmXCJvblNjcm9sbFwiPT09ZiYmRChcInNjcm9sbFwiLGEpOm51bGwhPWsmJnRhKGEsZixrLGcpKX1zd2l0Y2goYyl7Y2FzZSBcImlucHV0XCI6VmEoYSk7ZGIoYSxkLCExKTticmVhaztjYXNlIFwidGV4dGFyZWFcIjpWYShhKTtqYihhKTticmVhaztjYXNlIFwib3B0aW9uXCI6bnVsbCE9ZC52YWx1ZSYmYS5zZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiLFwiXCIrU2EoZC52YWx1ZSkpO2JyZWFrO2Nhc2UgXCJzZWxlY3RcIjphLm11bHRpcGxlPSEhZC5tdWx0aXBsZTtmPWQudmFsdWU7bnVsbCE9Zj9mYihhLCEhZC5tdWx0aXBsZSxmLCExKTpudWxsIT1kLmRlZmF1bHRWYWx1ZSYmZmIoYSwhIWQubXVsdGlwbGUsZC5kZWZhdWx0VmFsdWUsXG4hMCk7YnJlYWs7ZGVmYXVsdDpcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5vbkNsaWNrJiYoYS5vbmNsaWNrPUJmKX1zd2l0Y2goYyl7Y2FzZSBcImJ1dHRvblwiOmNhc2UgXCJpbnB1dFwiOmNhc2UgXCJzZWxlY3RcIjpjYXNlIFwidGV4dGFyZWFcIjpkPSEhZC5hdXRvRm9jdXM7YnJlYWsgYTtjYXNlIFwiaW1nXCI6ZD0hMDticmVhayBhO2RlZmF1bHQ6ZD0hMX19ZCYmKGIuZmxhZ3N8PTQpfW51bGwhPT1iLnJlZiYmKGIuZmxhZ3N8PTUxMixiLmZsYWdzfD0yMDk3MTUyKX1TKGIpO3JldHVybiBudWxsO2Nhc2UgNjppZihhJiZudWxsIT1iLnN0YXRlTm9kZSlEaihhLGIsYS5tZW1vaXplZFByb3BzLGQpO2Vsc2V7aWYoXCJzdHJpbmdcIiE9PXR5cGVvZiBkJiZudWxsPT09Yi5zdGF0ZU5vZGUpdGhyb3cgRXJyb3IocCgxNjYpKTtjPUhoKEdoLmN1cnJlbnQpO0hoKEVoLmN1cnJlbnQpO2lmKEdnKGIpKXtkPWIuc3RhdGVOb2RlO2M9Yi5tZW1vaXplZFByb3BzO2RbT2ZdPWI7aWYoZj1kLm5vZGVWYWx1ZSE9PWMpaWYoYT1cbnhnLG51bGwhPT1hKXN3aXRjaChhLnRhZyl7Y2FzZSAzOkFmKGQubm9kZVZhbHVlLGMsMCE9PShhLm1vZGUmMSkpO2JyZWFrO2Nhc2UgNTohMCE9PWEubWVtb2l6ZWRQcm9wcy5zdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcmJkFmKGQubm9kZVZhbHVlLGMsMCE9PShhLm1vZGUmMSkpfWYmJihiLmZsYWdzfD00KX1lbHNlIGQ9KDk9PT1jLm5vZGVUeXBlP2M6Yy5vd25lckRvY3VtZW50KS5jcmVhdGVUZXh0Tm9kZShkKSxkW09mXT1iLGIuc3RhdGVOb2RlPWR9UyhiKTtyZXR1cm4gbnVsbDtjYXNlIDEzOkUoTSk7ZD1iLm1lbW9pemVkU3RhdGU7aWYobnVsbD09PWF8fG51bGwhPT1hLm1lbW9pemVkU3RhdGUmJm51bGwhPT1hLm1lbW9pemVkU3RhdGUuZGVoeWRyYXRlZCl7aWYoSSYmbnVsbCE9PXlnJiYwIT09KGIubW9kZSYxKSYmMD09PShiLmZsYWdzJjEyOCkpSGcoKSxJZygpLGIuZmxhZ3N8PTk4NTYwLGY9ITE7ZWxzZSBpZihmPUdnKGIpLG51bGwhPT1kJiZudWxsIT09ZC5kZWh5ZHJhdGVkKXtpZihudWxsPT09XG5hKXtpZighZil0aHJvdyBFcnJvcihwKDMxOCkpO2Y9Yi5tZW1vaXplZFN0YXRlO2Y9bnVsbCE9PWY/Zi5kZWh5ZHJhdGVkOm51bGw7aWYoIWYpdGhyb3cgRXJyb3IocCgzMTcpKTtmW09mXT1ifWVsc2UgSWcoKSwwPT09KGIuZmxhZ3MmMTI4KSYmKGIubWVtb2l6ZWRTdGF0ZT1udWxsKSxiLmZsYWdzfD00O1MoYik7Zj0hMX1lbHNlIG51bGwhPT16ZyYmKEdqKHpnKSx6Zz1udWxsKSxmPSEwO2lmKCFmKXJldHVybiBiLmZsYWdzJjY1NTM2P2I6bnVsbH1pZigwIT09KGIuZmxhZ3MmMTI4KSlyZXR1cm4gYi5sYW5lcz1jLGI7ZD1udWxsIT09ZDtkIT09KG51bGwhPT1hJiZudWxsIT09YS5tZW1vaXplZFN0YXRlKSYmZCYmKGIuY2hpbGQuZmxhZ3N8PTgxOTIsMCE9PShiLm1vZGUmMSkmJihudWxsPT09YXx8MCE9PShNLmN1cnJlbnQmMSk/MD09PVQmJihUPTMpOnVqKCkpKTtudWxsIT09Yi51cGRhdGVRdWV1ZSYmKGIuZmxhZ3N8PTQpO1MoYik7cmV0dXJuIG51bGw7Y2FzZSA0OnJldHVybiBKaCgpLFxuQmooYSxiKSxudWxsPT09YSYmc2YoYi5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyksUyhiKSxudWxsO2Nhc2UgMTA6cmV0dXJuIFJnKGIudHlwZS5fY29udGV4dCksUyhiKSxudWxsO2Nhc2UgMTc6cmV0dXJuIFpmKGIudHlwZSkmJiRmKCksUyhiKSxudWxsO2Nhc2UgMTk6RShNKTtmPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsPT09ZilyZXR1cm4gUyhiKSxudWxsO2Q9MCE9PShiLmZsYWdzJjEyOCk7Zz1mLnJlbmRlcmluZztpZihudWxsPT09ZylpZihkKUVqKGYsITEpO2Vsc2V7aWYoMCE9PVR8fG51bGwhPT1hJiYwIT09KGEuZmxhZ3MmMTI4KSlmb3IoYT1iLmNoaWxkO251bGwhPT1hOyl7Zz1NaChhKTtpZihudWxsIT09Zyl7Yi5mbGFnc3w9MTI4O0VqKGYsITEpO2Q9Zy51cGRhdGVRdWV1ZTtudWxsIT09ZCYmKGIudXBkYXRlUXVldWU9ZCxiLmZsYWdzfD00KTtiLnN1YnRyZWVGbGFncz0wO2Q9Yztmb3IoYz1iLmNoaWxkO251bGwhPT1jOylmPWMsYT1kLGYuZmxhZ3MmPTE0NjgwMDY2LFxuZz1mLmFsdGVybmF0ZSxudWxsPT09Zz8oZi5jaGlsZExhbmVzPTAsZi5sYW5lcz1hLGYuY2hpbGQ9bnVsbCxmLnN1YnRyZWVGbGFncz0wLGYubWVtb2l6ZWRQcm9wcz1udWxsLGYubWVtb2l6ZWRTdGF0ZT1udWxsLGYudXBkYXRlUXVldWU9bnVsbCxmLmRlcGVuZGVuY2llcz1udWxsLGYuc3RhdGVOb2RlPW51bGwpOihmLmNoaWxkTGFuZXM9Zy5jaGlsZExhbmVzLGYubGFuZXM9Zy5sYW5lcyxmLmNoaWxkPWcuY2hpbGQsZi5zdWJ0cmVlRmxhZ3M9MCxmLmRlbGV0aW9ucz1udWxsLGYubWVtb2l6ZWRQcm9wcz1nLm1lbW9pemVkUHJvcHMsZi5tZW1vaXplZFN0YXRlPWcubWVtb2l6ZWRTdGF0ZSxmLnVwZGF0ZVF1ZXVlPWcudXBkYXRlUXVldWUsZi50eXBlPWcudHlwZSxhPWcuZGVwZW5kZW5jaWVzLGYuZGVwZW5kZW5jaWVzPW51bGw9PT1hP251bGw6e2xhbmVzOmEubGFuZXMsZmlyc3RDb250ZXh0OmEuZmlyc3RDb250ZXh0fSksYz1jLnNpYmxpbmc7RyhNLE0uY3VycmVudCYxfDIpO3JldHVybiBiLmNoaWxkfWE9XG5hLnNpYmxpbmd9bnVsbCE9PWYudGFpbCYmQigpPkhqJiYoYi5mbGFnc3w9MTI4LGQ9ITAsRWooZiwhMSksYi5sYW5lcz00MTk0MzA0KX1lbHNle2lmKCFkKWlmKGE9TWgoZyksbnVsbCE9PWEpe2lmKGIuZmxhZ3N8PTEyOCxkPSEwLGM9YS51cGRhdGVRdWV1ZSxudWxsIT09YyYmKGIudXBkYXRlUXVldWU9YyxiLmZsYWdzfD00KSxFaihmLCEwKSxudWxsPT09Zi50YWlsJiZcImhpZGRlblwiPT09Zi50YWlsTW9kZSYmIWcuYWx0ZXJuYXRlJiYhSSlyZXR1cm4gUyhiKSxudWxsfWVsc2UgMipCKCktZi5yZW5kZXJpbmdTdGFydFRpbWU+SGomJjEwNzM3NDE4MjQhPT1jJiYoYi5mbGFnc3w9MTI4LGQ9ITAsRWooZiwhMSksYi5sYW5lcz00MTk0MzA0KTtmLmlzQmFja3dhcmRzPyhnLnNpYmxpbmc9Yi5jaGlsZCxiLmNoaWxkPWcpOihjPWYubGFzdCxudWxsIT09Yz9jLnNpYmxpbmc9ZzpiLmNoaWxkPWcsZi5sYXN0PWcpfWlmKG51bGwhPT1mLnRhaWwpcmV0dXJuIGI9Zi50YWlsLGYucmVuZGVyaW5nPVxuYixmLnRhaWw9Yi5zaWJsaW5nLGYucmVuZGVyaW5nU3RhcnRUaW1lPUIoKSxiLnNpYmxpbmc9bnVsbCxjPU0uY3VycmVudCxHKE0sZD9jJjF8MjpjJjEpLGI7UyhiKTtyZXR1cm4gbnVsbDtjYXNlIDIyOmNhc2UgMjM6cmV0dXJuIElqKCksZD1udWxsIT09Yi5tZW1vaXplZFN0YXRlLG51bGwhPT1hJiZudWxsIT09YS5tZW1vaXplZFN0YXRlIT09ZCYmKGIuZmxhZ3N8PTgxOTIpLGQmJjAhPT0oYi5tb2RlJjEpPzAhPT0oZ2omMTA3Mzc0MTgyNCkmJihTKGIpLGIuc3VidHJlZUZsYWdzJjYmJihiLmZsYWdzfD04MTkyKSk6UyhiKSxudWxsO2Nhc2UgMjQ6cmV0dXJuIG51bGw7Y2FzZSAyNTpyZXR1cm4gbnVsbH10aHJvdyBFcnJvcihwKDE1NixiLnRhZykpO31cbmZ1bmN0aW9uIEpqKGEsYil7d2coYik7c3dpdGNoKGIudGFnKXtjYXNlIDE6cmV0dXJuIFpmKGIudHlwZSkmJiRmKCksYT1iLmZsYWdzLGEmNjU1MzY/KGIuZmxhZ3M9YSYtNjU1Mzd8MTI4LGIpOm51bGw7Y2FzZSAzOnJldHVybiBKaCgpLEUoV2YpLEUoSCksT2goKSxhPWIuZmxhZ3MsMCE9PShhJjY1NTM2KSYmMD09PShhJjEyOCk/KGIuZmxhZ3M9YSYtNjU1Mzd8MTI4LGIpOm51bGw7Y2FzZSA1OnJldHVybiBMaChiKSxudWxsO2Nhc2UgMTM6RShNKTthPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09YSYmbnVsbCE9PWEuZGVoeWRyYXRlZCl7aWYobnVsbD09PWIuYWx0ZXJuYXRlKXRocm93IEVycm9yKHAoMzQwKSk7SWcoKX1hPWIuZmxhZ3M7cmV0dXJuIGEmNjU1MzY/KGIuZmxhZ3M9YSYtNjU1Mzd8MTI4LGIpOm51bGw7Y2FzZSAxOTpyZXR1cm4gRShNKSxudWxsO2Nhc2UgNDpyZXR1cm4gSmgoKSxudWxsO2Nhc2UgMTA6cmV0dXJuIFJnKGIudHlwZS5fY29udGV4dCksbnVsbDtjYXNlIDIyOmNhc2UgMjM6cmV0dXJuIElqKCksXG5udWxsO2Nhc2UgMjQ6cmV0dXJuIG51bGw7ZGVmYXVsdDpyZXR1cm4gbnVsbH19dmFyIEtqPSExLFU9ITEsTGo9XCJmdW5jdGlvblwiPT09dHlwZW9mIFdlYWtTZXQ/V2Vha1NldDpTZXQsVj1udWxsO2Z1bmN0aW9uIE1qKGEsYil7dmFyIGM9YS5yZWY7aWYobnVsbCE9PWMpaWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGMpdHJ5e2MobnVsbCl9Y2F0Y2goZCl7VyhhLGIsZCl9ZWxzZSBjLmN1cnJlbnQ9bnVsbH1mdW5jdGlvbiBOaihhLGIsYyl7dHJ5e2MoKX1jYXRjaChkKXtXKGEsYixkKX19dmFyIE9qPSExO1xuZnVuY3Rpb24gUGooYSxiKXtDZj1kZDthPU1lKCk7aWYoTmUoYSkpe2lmKFwic2VsZWN0aW9uU3RhcnRcImluIGEpdmFyIGM9e3N0YXJ0OmEuc2VsZWN0aW9uU3RhcnQsZW5kOmEuc2VsZWN0aW9uRW5kfTtlbHNlIGE6e2M9KGM9YS5vd25lckRvY3VtZW50KSYmYy5kZWZhdWx0Vmlld3x8d2luZG93O3ZhciBkPWMuZ2V0U2VsZWN0aW9uJiZjLmdldFNlbGVjdGlvbigpO2lmKGQmJjAhPT1kLnJhbmdlQ291bnQpe2M9ZC5hbmNob3JOb2RlO3ZhciBlPWQuYW5jaG9yT2Zmc2V0LGY9ZC5mb2N1c05vZGU7ZD1kLmZvY3VzT2Zmc2V0O3RyeXtjLm5vZGVUeXBlLGYubm9kZVR5cGV9Y2F0Y2goRil7Yz1udWxsO2JyZWFrIGF9dmFyIGc9MCxoPS0xLGs9LTEsbD0wLG09MCxxPWEscj1udWxsO2I6Zm9yKDs7KXtmb3IodmFyIHk7Oyl7cSE9PWN8fDAhPT1lJiYzIT09cS5ub2RlVHlwZXx8KGg9ZytlKTtxIT09Znx8MCE9PWQmJjMhPT1xLm5vZGVUeXBlfHwoaz1nK2QpOzM9PT1xLm5vZGVUeXBlJiYoZys9XG5xLm5vZGVWYWx1ZS5sZW5ndGgpO2lmKG51bGw9PT0oeT1xLmZpcnN0Q2hpbGQpKWJyZWFrO3I9cTtxPXl9Zm9yKDs7KXtpZihxPT09YSlicmVhayBiO3I9PT1jJiYrK2w9PT1lJiYoaD1nKTtyPT09ZiYmKyttPT09ZCYmKGs9Zyk7aWYobnVsbCE9PSh5PXEubmV4dFNpYmxpbmcpKWJyZWFrO3E9cjtyPXEucGFyZW50Tm9kZX1xPXl9Yz0tMT09PWh8fC0xPT09az9udWxsOntzdGFydDpoLGVuZDprfX1lbHNlIGM9bnVsbH1jPWN8fHtzdGFydDowLGVuZDowfX1lbHNlIGM9bnVsbDtEZj17Zm9jdXNlZEVsZW06YSxzZWxlY3Rpb25SYW5nZTpjfTtkZD0hMTtmb3IoVj1iO251bGwhPT1WOylpZihiPVYsYT1iLmNoaWxkLDAhPT0oYi5zdWJ0cmVlRmxhZ3MmMTAyOCkmJm51bGwhPT1hKWEucmV0dXJuPWIsVj1hO2Vsc2UgZm9yKDtudWxsIT09Vjspe2I9Vjt0cnl7dmFyIG49Yi5hbHRlcm5hdGU7aWYoMCE9PShiLmZsYWdzJjEwMjQpKXN3aXRjaChiLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNTpicmVhaztcbmNhc2UgMTppZihudWxsIT09bil7dmFyIHQ9bi5tZW1vaXplZFByb3BzLEo9bi5tZW1vaXplZFN0YXRlLHg9Yi5zdGF0ZU5vZGUsdz14LmdldFNuYXBzaG90QmVmb3JlVXBkYXRlKGIuZWxlbWVudFR5cGU9PT1iLnR5cGU/dDpMZyhiLnR5cGUsdCksSik7eC5fX3JlYWN0SW50ZXJuYWxTbmFwc2hvdEJlZm9yZVVwZGF0ZT13fWJyZWFrO2Nhc2UgMzp2YXIgdT1iLnN0YXRlTm9kZS5jb250YWluZXJJbmZvOzE9PT11Lm5vZGVUeXBlP3UudGV4dENvbnRlbnQ9XCJcIjo5PT09dS5ub2RlVHlwZSYmdS5kb2N1bWVudEVsZW1lbnQmJnUucmVtb3ZlQ2hpbGQodS5kb2N1bWVudEVsZW1lbnQpO2JyZWFrO2Nhc2UgNTpjYXNlIDY6Y2FzZSA0OmNhc2UgMTc6YnJlYWs7ZGVmYXVsdDp0aHJvdyBFcnJvcihwKDE2MykpO319Y2F0Y2goRil7VyhiLGIucmV0dXJuLEYpfWE9Yi5zaWJsaW5nO2lmKG51bGwhPT1hKXthLnJldHVybj1iLnJldHVybjtWPWE7YnJlYWt9Vj1iLnJldHVybn1uPU9qO09qPSExO3JldHVybiBufVxuZnVuY3Rpb24gUWooYSxiLGMpe3ZhciBkPWIudXBkYXRlUXVldWU7ZD1udWxsIT09ZD9kLmxhc3RFZmZlY3Q6bnVsbDtpZihudWxsIT09ZCl7dmFyIGU9ZD1kLm5leHQ7ZG97aWYoKGUudGFnJmEpPT09YSl7dmFyIGY9ZS5kZXN0cm95O2UuZGVzdHJveT12b2lkIDA7dm9pZCAwIT09ZiYmTmooYixjLGYpfWU9ZS5uZXh0fXdoaWxlKGUhPT1kKX19ZnVuY3Rpb24gUmooYSxiKXtiPWIudXBkYXRlUXVldWU7Yj1udWxsIT09Yj9iLmxhc3RFZmZlY3Q6bnVsbDtpZihudWxsIT09Yil7dmFyIGM9Yj1iLm5leHQ7ZG97aWYoKGMudGFnJmEpPT09YSl7dmFyIGQ9Yy5jcmVhdGU7Yy5kZXN0cm95PWQoKX1jPWMubmV4dH13aGlsZShjIT09Yil9fWZ1bmN0aW9uIFNqKGEpe3ZhciBiPWEucmVmO2lmKG51bGwhPT1iKXt2YXIgYz1hLnN0YXRlTm9kZTtzd2l0Y2goYS50YWcpe2Nhc2UgNTphPWM7YnJlYWs7ZGVmYXVsdDphPWN9XCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YihhKTpiLmN1cnJlbnQ9YX19XG5mdW5jdGlvbiBUaihhKXt2YXIgYj1hLmFsdGVybmF0ZTtudWxsIT09YiYmKGEuYWx0ZXJuYXRlPW51bGwsVGooYikpO2EuY2hpbGQ9bnVsbDthLmRlbGV0aW9ucz1udWxsO2Euc2libGluZz1udWxsOzU9PT1hLnRhZyYmKGI9YS5zdGF0ZU5vZGUsbnVsbCE9PWImJihkZWxldGUgYltPZl0sZGVsZXRlIGJbUGZdLGRlbGV0ZSBiW29mXSxkZWxldGUgYltRZl0sZGVsZXRlIGJbUmZdKSk7YS5zdGF0ZU5vZGU9bnVsbDthLnJldHVybj1udWxsO2EuZGVwZW5kZW5jaWVzPW51bGw7YS5tZW1vaXplZFByb3BzPW51bGw7YS5tZW1vaXplZFN0YXRlPW51bGw7YS5wZW5kaW5nUHJvcHM9bnVsbDthLnN0YXRlTm9kZT1udWxsO2EudXBkYXRlUXVldWU9bnVsbH1mdW5jdGlvbiBVaihhKXtyZXR1cm4gNT09PWEudGFnfHwzPT09YS50YWd8fDQ9PT1hLnRhZ31cbmZ1bmN0aW9uIFZqKGEpe2E6Zm9yKDs7KXtmb3IoO251bGw9PT1hLnNpYmxpbmc7KXtpZihudWxsPT09YS5yZXR1cm58fFVqKGEucmV0dXJuKSlyZXR1cm4gbnVsbDthPWEucmV0dXJufWEuc2libGluZy5yZXR1cm49YS5yZXR1cm47Zm9yKGE9YS5zaWJsaW5nOzUhPT1hLnRhZyYmNiE9PWEudGFnJiYxOCE9PWEudGFnOyl7aWYoYS5mbGFncyYyKWNvbnRpbnVlIGE7aWYobnVsbD09PWEuY2hpbGR8fDQ9PT1hLnRhZyljb250aW51ZSBhO2Vsc2UgYS5jaGlsZC5yZXR1cm49YSxhPWEuY2hpbGR9aWYoIShhLmZsYWdzJjIpKXJldHVybiBhLnN0YXRlTm9kZX19XG5mdW5jdGlvbiBXaihhLGIsYyl7dmFyIGQ9YS50YWc7aWYoNT09PWR8fDY9PT1kKWE9YS5zdGF0ZU5vZGUsYj84PT09Yy5ub2RlVHlwZT9jLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsYik6Yy5pbnNlcnRCZWZvcmUoYSxiKTooOD09PWMubm9kZVR5cGU/KGI9Yy5wYXJlbnROb2RlLGIuaW5zZXJ0QmVmb3JlKGEsYykpOihiPWMsYi5hcHBlbmRDaGlsZChhKSksYz1jLl9yZWFjdFJvb3RDb250YWluZXIsbnVsbCE9PWMmJnZvaWQgMCE9PWN8fG51bGwhPT1iLm9uY2xpY2t8fChiLm9uY2xpY2s9QmYpKTtlbHNlIGlmKDQhPT1kJiYoYT1hLmNoaWxkLG51bGwhPT1hKSlmb3IoV2ooYSxiLGMpLGE9YS5zaWJsaW5nO251bGwhPT1hOylXaihhLGIsYyksYT1hLnNpYmxpbmd9XG5mdW5jdGlvbiBYaihhLGIsYyl7dmFyIGQ9YS50YWc7aWYoNT09PWR8fDY9PT1kKWE9YS5zdGF0ZU5vZGUsYj9jLmluc2VydEJlZm9yZShhLGIpOmMuYXBwZW5kQ2hpbGQoYSk7ZWxzZSBpZig0IT09ZCYmKGE9YS5jaGlsZCxudWxsIT09YSkpZm9yKFhqKGEsYixjKSxhPWEuc2libGluZztudWxsIT09YTspWGooYSxiLGMpLGE9YS5zaWJsaW5nfXZhciBYPW51bGwsWWo9ITE7ZnVuY3Rpb24gWmooYSxiLGMpe2ZvcihjPWMuY2hpbGQ7bnVsbCE9PWM7KWFrKGEsYixjKSxjPWMuc2libGluZ31cbmZ1bmN0aW9uIGFrKGEsYixjKXtpZihsYyYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGxjLm9uQ29tbWl0RmliZXJVbm1vdW50KXRyeXtsYy5vbkNvbW1pdEZpYmVyVW5tb3VudChrYyxjKX1jYXRjaChoKXt9c3dpdGNoKGMudGFnKXtjYXNlIDU6VXx8TWooYyxiKTtjYXNlIDY6dmFyIGQ9WCxlPVlqO1g9bnVsbDtaaihhLGIsYyk7WD1kO1lqPWU7bnVsbCE9PVgmJihZaj8oYT1YLGM9Yy5zdGF0ZU5vZGUsOD09PWEubm9kZVR5cGU/YS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGMpOmEucmVtb3ZlQ2hpbGQoYykpOlgucmVtb3ZlQ2hpbGQoYy5zdGF0ZU5vZGUpKTticmVhaztjYXNlIDE4Om51bGwhPT1YJiYoWWo/KGE9WCxjPWMuc3RhdGVOb2RlLDg9PT1hLm5vZGVUeXBlP0tmKGEucGFyZW50Tm9kZSxjKToxPT09YS5ub2RlVHlwZSYmS2YoYSxjKSxiZChhKSk6S2YoWCxjLnN0YXRlTm9kZSkpO2JyZWFrO2Nhc2UgNDpkPVg7ZT1ZajtYPWMuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87WWo9ITA7XG5aaihhLGIsYyk7WD1kO1lqPWU7YnJlYWs7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNDpjYXNlIDE1OmlmKCFVJiYoZD1jLnVwZGF0ZVF1ZXVlLG51bGwhPT1kJiYoZD1kLmxhc3RFZmZlY3QsbnVsbCE9PWQpKSl7ZT1kPWQubmV4dDtkb3t2YXIgZj1lLGc9Zi5kZXN0cm95O2Y9Zi50YWc7dm9pZCAwIT09ZyYmKDAhPT0oZiYyKT9OaihjLGIsZyk6MCE9PShmJjQpJiZOaihjLGIsZykpO2U9ZS5uZXh0fXdoaWxlKGUhPT1kKX1aaihhLGIsYyk7YnJlYWs7Y2FzZSAxOmlmKCFVJiYoTWooYyxiKSxkPWMuc3RhdGVOb2RlLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBkLmNvbXBvbmVudFdpbGxVbm1vdW50KSl0cnl7ZC5wcm9wcz1jLm1lbW9pemVkUHJvcHMsZC5zdGF0ZT1jLm1lbW9pemVkU3RhdGUsZC5jb21wb25lbnRXaWxsVW5tb3VudCgpfWNhdGNoKGgpe1coYyxiLGgpfVpqKGEsYixjKTticmVhaztjYXNlIDIxOlpqKGEsYixjKTticmVhaztjYXNlIDIyOmMubW9kZSYxPyhVPShkPVUpfHxudWxsIT09XG5jLm1lbW9pemVkU3RhdGUsWmooYSxiLGMpLFU9ZCk6WmooYSxiLGMpO2JyZWFrO2RlZmF1bHQ6WmooYSxiLGMpfX1mdW5jdGlvbiBiayhhKXt2YXIgYj1hLnVwZGF0ZVF1ZXVlO2lmKG51bGwhPT1iKXthLnVwZGF0ZVF1ZXVlPW51bGw7dmFyIGM9YS5zdGF0ZU5vZGU7bnVsbD09PWMmJihjPWEuc3RhdGVOb2RlPW5ldyBMaik7Yi5mb3JFYWNoKGZ1bmN0aW9uKGIpe3ZhciBkPWNrLmJpbmQobnVsbCxhLGIpO2MuaGFzKGIpfHwoYy5hZGQoYiksYi50aGVuKGQsZCkpfSl9fVxuZnVuY3Rpb24gZGsoYSxiKXt2YXIgYz1iLmRlbGV0aW9ucztpZihudWxsIT09Yylmb3IodmFyIGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGU9Y1tkXTt0cnl7dmFyIGY9YSxnPWIsaD1nO2E6Zm9yKDtudWxsIT09aDspe3N3aXRjaChoLnRhZyl7Y2FzZSA1Olg9aC5zdGF0ZU5vZGU7WWo9ITE7YnJlYWsgYTtjYXNlIDM6WD1oLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1lqPSEwO2JyZWFrIGE7Y2FzZSA0Olg9aC5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztZaj0hMDticmVhayBhfWg9aC5yZXR1cm59aWYobnVsbD09PVgpdGhyb3cgRXJyb3IocCgxNjApKTthayhmLGcsZSk7WD1udWxsO1lqPSExO3ZhciBrPWUuYWx0ZXJuYXRlO251bGwhPT1rJiYoay5yZXR1cm49bnVsbCk7ZS5yZXR1cm49bnVsbH1jYXRjaChsKXtXKGUsYixsKX19aWYoYi5zdWJ0cmVlRmxhZ3MmMTI4NTQpZm9yKGI9Yi5jaGlsZDtudWxsIT09YjspZWsoYixhKSxiPWIuc2libGluZ31cbmZ1bmN0aW9uIGVrKGEsYil7dmFyIGM9YS5hbHRlcm5hdGUsZD1hLmZsYWdzO3N3aXRjaChhLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNDpjYXNlIDE1OmRrKGIsYSk7ZmsoYSk7aWYoZCY0KXt0cnl7UWooMyxhLGEucmV0dXJuKSxSaigzLGEpfWNhdGNoKHQpe1coYSxhLnJldHVybix0KX10cnl7UWooNSxhLGEucmV0dXJuKX1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWJyZWFrO2Nhc2UgMTpkayhiLGEpO2ZrKGEpO2QmNTEyJiZudWxsIT09YyYmTWooYyxjLnJldHVybik7YnJlYWs7Y2FzZSA1OmRrKGIsYSk7ZmsoYSk7ZCY1MTImJm51bGwhPT1jJiZNaihjLGMucmV0dXJuKTtpZihhLmZsYWdzJjMyKXt2YXIgZT1hLnN0YXRlTm9kZTt0cnl7b2IoZSxcIlwiKX1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWlmKGQmNCYmKGU9YS5zdGF0ZU5vZGUsbnVsbCE9ZSkpe3ZhciBmPWEubWVtb2l6ZWRQcm9wcyxnPW51bGwhPT1jP2MubWVtb2l6ZWRQcm9wczpmLGg9YS50eXBlLGs9YS51cGRhdGVRdWV1ZTtcbmEudXBkYXRlUXVldWU9bnVsbDtpZihudWxsIT09ayl0cnl7XCJpbnB1dFwiPT09aCYmXCJyYWRpb1wiPT09Zi50eXBlJiZudWxsIT1mLm5hbWUmJmFiKGUsZik7dmIoaCxnKTt2YXIgbD12YihoLGYpO2ZvcihnPTA7ZzxrLmxlbmd0aDtnKz0yKXt2YXIgbT1rW2ddLHE9a1tnKzFdO1wic3R5bGVcIj09PW0/c2IoZSxxKTpcImRhbmdlcm91c2x5U2V0SW5uZXJIVE1MXCI9PT1tP25iKGUscSk6XCJjaGlsZHJlblwiPT09bT9vYihlLHEpOnRhKGUsbSxxLGwpfXN3aXRjaChoKXtjYXNlIFwiaW5wdXRcIjpiYihlLGYpO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmliKGUsZik7YnJlYWs7Y2FzZSBcInNlbGVjdFwiOnZhciByPWUuX3dyYXBwZXJTdGF0ZS53YXNNdWx0aXBsZTtlLl93cmFwcGVyU3RhdGUud2FzTXVsdGlwbGU9ISFmLm11bHRpcGxlO3ZhciB5PWYudmFsdWU7bnVsbCE9eT9mYihlLCEhZi5tdWx0aXBsZSx5LCExKTpyIT09ISFmLm11bHRpcGxlJiYobnVsbCE9Zi5kZWZhdWx0VmFsdWU/ZmIoZSwhIWYubXVsdGlwbGUsXG5mLmRlZmF1bHRWYWx1ZSwhMCk6ZmIoZSwhIWYubXVsdGlwbGUsZi5tdWx0aXBsZT9bXTpcIlwiLCExKSl9ZVtQZl09Zn1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWJyZWFrO2Nhc2UgNjpkayhiLGEpO2ZrKGEpO2lmKGQmNCl7aWYobnVsbD09PWEuc3RhdGVOb2RlKXRocm93IEVycm9yKHAoMTYyKSk7ZT1hLnN0YXRlTm9kZTtmPWEubWVtb2l6ZWRQcm9wczt0cnl7ZS5ub2RlVmFsdWU9Zn1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWJyZWFrO2Nhc2UgMzpkayhiLGEpO2ZrKGEpO2lmKGQmNCYmbnVsbCE9PWMmJmMubWVtb2l6ZWRTdGF0ZS5pc0RlaHlkcmF0ZWQpdHJ5e2JkKGIuY29udGFpbmVySW5mbyl9Y2F0Y2godCl7VyhhLGEucmV0dXJuLHQpfWJyZWFrO2Nhc2UgNDpkayhiLGEpO2ZrKGEpO2JyZWFrO2Nhc2UgMTM6ZGsoYixhKTtmayhhKTtlPWEuY2hpbGQ7ZS5mbGFncyY4MTkyJiYoZj1udWxsIT09ZS5tZW1vaXplZFN0YXRlLGUuc3RhdGVOb2RlLmlzSGlkZGVuPWYsIWZ8fFxubnVsbCE9PWUuYWx0ZXJuYXRlJiZudWxsIT09ZS5hbHRlcm5hdGUubWVtb2l6ZWRTdGF0ZXx8KGdrPUIoKSkpO2QmNCYmYmsoYSk7YnJlYWs7Y2FzZSAyMjptPW51bGwhPT1jJiZudWxsIT09Yy5tZW1vaXplZFN0YXRlO2EubW9kZSYxPyhVPShsPVUpfHxtLGRrKGIsYSksVT1sKTpkayhiLGEpO2ZrKGEpO2lmKGQmODE5Mil7bD1udWxsIT09YS5tZW1vaXplZFN0YXRlO2lmKChhLnN0YXRlTm9kZS5pc0hpZGRlbj1sKSYmIW0mJjAhPT0oYS5tb2RlJjEpKWZvcihWPWEsbT1hLmNoaWxkO251bGwhPT1tOyl7Zm9yKHE9Vj1tO251bGwhPT1WOyl7cj1WO3k9ci5jaGlsZDtzd2l0Y2goci50YWcpe2Nhc2UgMDpjYXNlIDExOmNhc2UgMTQ6Y2FzZSAxNTpRaig0LHIsci5yZXR1cm4pO2JyZWFrO2Nhc2UgMTpNaihyLHIucmV0dXJuKTt2YXIgbj1yLnN0YXRlTm9kZTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2Ygbi5jb21wb25lbnRXaWxsVW5tb3VudCl7ZD1yO2M9ci5yZXR1cm47dHJ5e2I9ZCxuLnByb3BzPVxuYi5tZW1vaXplZFByb3BzLG4uc3RhdGU9Yi5tZW1vaXplZFN0YXRlLG4uY29tcG9uZW50V2lsbFVubW91bnQoKX1jYXRjaCh0KXtXKGQsYyx0KX19YnJlYWs7Y2FzZSA1Ok1qKHIsci5yZXR1cm4pO2JyZWFrO2Nhc2UgMjI6aWYobnVsbCE9PXIubWVtb2l6ZWRTdGF0ZSl7aGsocSk7Y29udGludWV9fW51bGwhPT15Pyh5LnJldHVybj1yLFY9eSk6aGsocSl9bT1tLnNpYmxpbmd9YTpmb3IobT1udWxsLHE9YTs7KXtpZig1PT09cS50YWcpe2lmKG51bGw9PT1tKXttPXE7dHJ5e2U9cS5zdGF0ZU5vZGUsbD8oZj1lLnN0eWxlLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBmLnNldFByb3BlcnR5P2Yuc2V0UHJvcGVydHkoXCJkaXNwbGF5XCIsXCJub25lXCIsXCJpbXBvcnRhbnRcIik6Zi5kaXNwbGF5PVwibm9uZVwiKTooaD1xLnN0YXRlTm9kZSxrPXEubWVtb2l6ZWRQcm9wcy5zdHlsZSxnPXZvaWQgMCE9PWsmJm51bGwhPT1rJiZrLmhhc093blByb3BlcnR5KFwiZGlzcGxheVwiKT9rLmRpc3BsYXk6bnVsbCxoLnN0eWxlLmRpc3BsYXk9XG5yYihcImRpc3BsYXlcIixnKSl9Y2F0Y2godCl7VyhhLGEucmV0dXJuLHQpfX19ZWxzZSBpZig2PT09cS50YWcpe2lmKG51bGw9PT1tKXRyeXtxLnN0YXRlTm9kZS5ub2RlVmFsdWU9bD9cIlwiOnEubWVtb2l6ZWRQcm9wc31jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWVsc2UgaWYoKDIyIT09cS50YWcmJjIzIT09cS50YWd8fG51bGw9PT1xLm1lbW9pemVkU3RhdGV8fHE9PT1hKSYmbnVsbCE9PXEuY2hpbGQpe3EuY2hpbGQucmV0dXJuPXE7cT1xLmNoaWxkO2NvbnRpbnVlfWlmKHE9PT1hKWJyZWFrIGE7Zm9yKDtudWxsPT09cS5zaWJsaW5nOyl7aWYobnVsbD09PXEucmV0dXJufHxxLnJldHVybj09PWEpYnJlYWsgYTttPT09cSYmKG09bnVsbCk7cT1xLnJldHVybn1tPT09cSYmKG09bnVsbCk7cS5zaWJsaW5nLnJldHVybj1xLnJldHVybjtxPXEuc2libGluZ319YnJlYWs7Y2FzZSAxOTpkayhiLGEpO2ZrKGEpO2QmNCYmYmsoYSk7YnJlYWs7Y2FzZSAyMTpicmVhaztkZWZhdWx0OmRrKGIsXG5hKSxmayhhKX19ZnVuY3Rpb24gZmsoYSl7dmFyIGI9YS5mbGFncztpZihiJjIpe3RyeXthOntmb3IodmFyIGM9YS5yZXR1cm47bnVsbCE9PWM7KXtpZihVaihjKSl7dmFyIGQ9YzticmVhayBhfWM9Yy5yZXR1cm59dGhyb3cgRXJyb3IocCgxNjApKTt9c3dpdGNoKGQudGFnKXtjYXNlIDU6dmFyIGU9ZC5zdGF0ZU5vZGU7ZC5mbGFncyYzMiYmKG9iKGUsXCJcIiksZC5mbGFncyY9LTMzKTt2YXIgZj1WaihhKTtYaihhLGYsZSk7YnJlYWs7Y2FzZSAzOmNhc2UgNDp2YXIgZz1kLnN0YXRlTm9kZS5jb250YWluZXJJbmZvLGg9VmooYSk7V2ooYSxoLGcpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IocCgxNjEpKTt9fWNhdGNoKGspe1coYSxhLnJldHVybixrKX1hLmZsYWdzJj0tM31iJjQwOTYmJihhLmZsYWdzJj0tNDA5Nyl9ZnVuY3Rpb24gaWsoYSxiLGMpe1Y9YTtqayhhLGIsYyl9XG5mdW5jdGlvbiBqayhhLGIsYyl7Zm9yKHZhciBkPTAhPT0oYS5tb2RlJjEpO251bGwhPT1WOyl7dmFyIGU9VixmPWUuY2hpbGQ7aWYoMjI9PT1lLnRhZyYmZCl7dmFyIGc9bnVsbCE9PWUubWVtb2l6ZWRTdGF0ZXx8S2o7aWYoIWcpe3ZhciBoPWUuYWx0ZXJuYXRlLGs9bnVsbCE9PWgmJm51bGwhPT1oLm1lbW9pemVkU3RhdGV8fFU7aD1Lajt2YXIgbD1VO0tqPWc7aWYoKFU9aykmJiFsKWZvcihWPWU7bnVsbCE9PVY7KWc9VixrPWcuY2hpbGQsMjI9PT1nLnRhZyYmbnVsbCE9PWcubWVtb2l6ZWRTdGF0ZT9rayhlKTpudWxsIT09az8oay5yZXR1cm49ZyxWPWspOmtrKGUpO2Zvcig7bnVsbCE9PWY7KVY9ZixqayhmLGIsYyksZj1mLnNpYmxpbmc7Vj1lO0tqPWg7VT1sfWxrKGEsYixjKX1lbHNlIDAhPT0oZS5zdWJ0cmVlRmxhZ3MmODc3MikmJm51bGwhPT1mPyhmLnJldHVybj1lLFY9Zik6bGsoYSxiLGMpfX1cbmZ1bmN0aW9uIGxrKGEpe2Zvcig7bnVsbCE9PVY7KXt2YXIgYj1WO2lmKDAhPT0oYi5mbGFncyY4NzcyKSl7dmFyIGM9Yi5hbHRlcm5hdGU7dHJ5e2lmKDAhPT0oYi5mbGFncyY4NzcyKSlzd2l0Y2goYi50YWcpe2Nhc2UgMDpjYXNlIDExOmNhc2UgMTU6VXx8UmooNSxiKTticmVhaztjYXNlIDE6dmFyIGQ9Yi5zdGF0ZU5vZGU7aWYoYi5mbGFncyY0JiYhVSlpZihudWxsPT09YylkLmNvbXBvbmVudERpZE1vdW50KCk7ZWxzZXt2YXIgZT1iLmVsZW1lbnRUeXBlPT09Yi50eXBlP2MubWVtb2l6ZWRQcm9wczpMZyhiLnR5cGUsYy5tZW1vaXplZFByb3BzKTtkLmNvbXBvbmVudERpZFVwZGF0ZShlLGMubWVtb2l6ZWRTdGF0ZSxkLl9fcmVhY3RJbnRlcm5hbFNuYXBzaG90QmVmb3JlVXBkYXRlKX12YXIgZj1iLnVwZGF0ZVF1ZXVlO251bGwhPT1mJiZpaChiLGYsZCk7YnJlYWs7Y2FzZSAzOnZhciBnPWIudXBkYXRlUXVldWU7aWYobnVsbCE9PWcpe2M9bnVsbDtpZihudWxsIT09Yi5jaGlsZClzd2l0Y2goYi5jaGlsZC50YWcpe2Nhc2UgNTpjPVxuYi5jaGlsZC5zdGF0ZU5vZGU7YnJlYWs7Y2FzZSAxOmM9Yi5jaGlsZC5zdGF0ZU5vZGV9aWgoYixnLGMpfWJyZWFrO2Nhc2UgNTp2YXIgaD1iLnN0YXRlTm9kZTtpZihudWxsPT09YyYmYi5mbGFncyY0KXtjPWg7dmFyIGs9Yi5tZW1vaXplZFByb3BzO3N3aXRjaChiLnR5cGUpe2Nhc2UgXCJidXR0b25cIjpjYXNlIFwiaW5wdXRcIjpjYXNlIFwic2VsZWN0XCI6Y2FzZSBcInRleHRhcmVhXCI6ay5hdXRvRm9jdXMmJmMuZm9jdXMoKTticmVhaztjYXNlIFwiaW1nXCI6ay5zcmMmJihjLnNyYz1rLnNyYyl9fWJyZWFrO2Nhc2UgNjpicmVhaztjYXNlIDQ6YnJlYWs7Y2FzZSAxMjpicmVhaztjYXNlIDEzOmlmKG51bGw9PT1iLm1lbW9pemVkU3RhdGUpe3ZhciBsPWIuYWx0ZXJuYXRlO2lmKG51bGwhPT1sKXt2YXIgbT1sLm1lbW9pemVkU3RhdGU7aWYobnVsbCE9PW0pe3ZhciBxPW0uZGVoeWRyYXRlZDtudWxsIT09cSYmYmQocSl9fX1icmVhaztjYXNlIDE5OmNhc2UgMTc6Y2FzZSAyMTpjYXNlIDIyOmNhc2UgMjM6Y2FzZSAyNTpicmVhaztcbmRlZmF1bHQ6dGhyb3cgRXJyb3IocCgxNjMpKTt9VXx8Yi5mbGFncyY1MTImJlNqKGIpfWNhdGNoKHIpe1coYixiLnJldHVybixyKX19aWYoYj09PWEpe1Y9bnVsbDticmVha31jPWIuc2libGluZztpZihudWxsIT09Yyl7Yy5yZXR1cm49Yi5yZXR1cm47Vj1jO2JyZWFrfVY9Yi5yZXR1cm59fWZ1bmN0aW9uIGhrKGEpe2Zvcig7bnVsbCE9PVY7KXt2YXIgYj1WO2lmKGI9PT1hKXtWPW51bGw7YnJlYWt9dmFyIGM9Yi5zaWJsaW5nO2lmKG51bGwhPT1jKXtjLnJldHVybj1iLnJldHVybjtWPWM7YnJlYWt9Vj1iLnJldHVybn19XG5mdW5jdGlvbiBrayhhKXtmb3IoO251bGwhPT1WOyl7dmFyIGI9Vjt0cnl7c3dpdGNoKGIudGFnKXtjYXNlIDA6Y2FzZSAxMTpjYXNlIDE1OnZhciBjPWIucmV0dXJuO3RyeXtSaig0LGIpfWNhdGNoKGspe1coYixjLGspfWJyZWFrO2Nhc2UgMTp2YXIgZD1iLnN0YXRlTm9kZTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZC5jb21wb25lbnREaWRNb3VudCl7dmFyIGU9Yi5yZXR1cm47dHJ5e2QuY29tcG9uZW50RGlkTW91bnQoKX1jYXRjaChrKXtXKGIsZSxrKX19dmFyIGY9Yi5yZXR1cm47dHJ5e1NqKGIpfWNhdGNoKGspe1coYixmLGspfWJyZWFrO2Nhc2UgNTp2YXIgZz1iLnJldHVybjt0cnl7U2ooYil9Y2F0Y2goayl7VyhiLGcsayl9fX1jYXRjaChrKXtXKGIsYi5yZXR1cm4sayl9aWYoYj09PWEpe1Y9bnVsbDticmVha312YXIgaD1iLnNpYmxpbmc7aWYobnVsbCE9PWgpe2gucmV0dXJuPWIucmV0dXJuO1Y9aDticmVha31WPWIucmV0dXJufX1cbnZhciBtaz1NYXRoLmNlaWwsbms9dWEuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixvaz11YS5SZWFjdEN1cnJlbnRPd25lcixwaz11YS5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZyxLPTAsUj1udWxsLFk9bnVsbCxaPTAsZ2o9MCxmaj1VZigwKSxUPTAscWs9bnVsbCxoaD0wLHJrPTAsc2s9MCx0az1udWxsLHVrPW51bGwsZ2s9MCxIaj1JbmZpbml0eSx2az1udWxsLFBpPSExLFFpPW51bGwsU2k9bnVsbCx3az0hMSx4az1udWxsLHlrPTAsems9MCxBaz1udWxsLEJrPS0xLENrPTA7ZnVuY3Rpb24gTCgpe3JldHVybiAwIT09KEsmNik/QigpOi0xIT09Qms/Qms6Qms9QigpfVxuZnVuY3Rpb24gbGgoYSl7aWYoMD09PShhLm1vZGUmMSkpcmV0dXJuIDE7aWYoMCE9PShLJjIpJiYwIT09WilyZXR1cm4gWiYtWjtpZihudWxsIT09S2cudHJhbnNpdGlvbilyZXR1cm4gMD09PUNrJiYoQ2s9eWMoKSksQ2s7YT1DO2lmKDAhPT1hKXJldHVybiBhO2E9d2luZG93LmV2ZW50O2E9dm9pZCAwPT09YT8xNjpqZChhLnR5cGUpO3JldHVybiBhfWZ1bmN0aW9uIG1oKGEsYixjLGQpe2lmKDUwPHprKXRocm93IHprPTAsQWs9bnVsbCxFcnJvcihwKDE4NSkpO0FjKGEsYyxkKTtpZigwPT09KEsmMil8fGEhPT1SKWE9PT1SJiYoMD09PShLJjIpJiYocmt8PWMpLDQ9PT1UJiZEayhhLFopKSxFayhhLGQpLDE9PT1jJiYwPT09SyYmMD09PShiLm1vZGUmMSkmJihIaj1CKCkrNTAwLGZnJiZqZygpKX1cbmZ1bmN0aW9uIEVrKGEsYil7dmFyIGM9YS5jYWxsYmFja05vZGU7d2MoYSxiKTt2YXIgZD11YyhhLGE9PT1SP1o6MCk7aWYoMD09PWQpbnVsbCE9PWMmJmJjKGMpLGEuY2FsbGJhY2tOb2RlPW51bGwsYS5jYWxsYmFja1ByaW9yaXR5PTA7ZWxzZSBpZihiPWQmLWQsYS5jYWxsYmFja1ByaW9yaXR5IT09Yil7bnVsbCE9YyYmYmMoYyk7aWYoMT09PWIpMD09PWEudGFnP2lnKEZrLmJpbmQobnVsbCxhKSk6aGcoRmsuYmluZChudWxsLGEpKSxKZihmdW5jdGlvbigpezA9PT0oSyY2KSYmamcoKX0pLGM9bnVsbDtlbHNle3N3aXRjaChEYyhkKSl7Y2FzZSAxOmM9ZmM7YnJlYWs7Y2FzZSA0OmM9Z2M7YnJlYWs7Y2FzZSAxNjpjPWhjO2JyZWFrO2Nhc2UgNTM2ODcwOTEyOmM9amM7YnJlYWs7ZGVmYXVsdDpjPWhjfWM9R2soYyxIay5iaW5kKG51bGwsYSkpfWEuY2FsbGJhY2tQcmlvcml0eT1iO2EuY2FsbGJhY2tOb2RlPWN9fVxuZnVuY3Rpb24gSGsoYSxiKXtCaz0tMTtDaz0wO2lmKDAhPT0oSyY2KSl0aHJvdyBFcnJvcihwKDMyNykpO3ZhciBjPWEuY2FsbGJhY2tOb2RlO2lmKElrKCkmJmEuY2FsbGJhY2tOb2RlIT09YylyZXR1cm4gbnVsbDt2YXIgZD11YyhhLGE9PT1SP1o6MCk7aWYoMD09PWQpcmV0dXJuIG51bGw7aWYoMCE9PShkJjMwKXx8MCE9PShkJmEuZXhwaXJlZExhbmVzKXx8YiliPUprKGEsZCk7ZWxzZXtiPWQ7dmFyIGU9SztLfD0yO3ZhciBmPUtrKCk7aWYoUiE9PWF8fFohPT1iKXZrPW51bGwsSGo9QigpKzUwMCxMayhhLGIpO2RvIHRyeXtNaygpO2JyZWFrfWNhdGNoKGgpe05rKGEsaCl9d2hpbGUoMSk7UWcoKTtuay5jdXJyZW50PWY7Sz1lO251bGwhPT1ZP2I9MDooUj1udWxsLFo9MCxiPVQpfWlmKDAhPT1iKXsyPT09YiYmKGU9eGMoYSksMCE9PWUmJihkPWUsYj1PayhhLGUpKSk7aWYoMT09PWIpdGhyb3cgYz1xayxMayhhLDApLERrKGEsZCksRWsoYSxCKCkpLGM7aWYoNj09PWIpRGsoYSxkKTtcbmVsc2V7ZT1hLmN1cnJlbnQuYWx0ZXJuYXRlO2lmKDA9PT0oZCYzMCkmJiFQayhlKSYmKGI9SmsoYSxkKSwyPT09YiYmKGY9eGMoYSksMCE9PWYmJihkPWYsYj1PayhhLGYpKSksMT09PWIpKXRocm93IGM9cWssTGsoYSwwKSxEayhhLGQpLEVrKGEsQigpKSxjO2EuZmluaXNoZWRXb3JrPWU7YS5maW5pc2hlZExhbmVzPWQ7c3dpdGNoKGIpe2Nhc2UgMDpjYXNlIDE6dGhyb3cgRXJyb3IocCgzNDUpKTtjYXNlIDI6UWsoYSx1ayx2ayk7YnJlYWs7Y2FzZSAzOkRrKGEsZCk7aWYoKGQmMTMwMDIzNDI0KT09PWQmJihiPWdrKzUwMC1CKCksMTA8Yikpe2lmKDAhPT11YyhhLDApKWJyZWFrO2U9YS5zdXNwZW5kZWRMYW5lcztpZigoZSZkKSE9PWQpe0woKTthLnBpbmdlZExhbmVzfD1hLnN1c3BlbmRlZExhbmVzJmU7YnJlYWt9YS50aW1lb3V0SGFuZGxlPUZmKFFrLmJpbmQobnVsbCxhLHVrLHZrKSxiKTticmVha31RayhhLHVrLHZrKTticmVhaztjYXNlIDQ6RGsoYSxkKTtpZigoZCY0MTk0MjQwKT09PVxuZClicmVhaztiPWEuZXZlbnRUaW1lcztmb3IoZT0tMTswPGQ7KXt2YXIgZz0zMS1vYyhkKTtmPTE8PGc7Zz1iW2ddO2c+ZSYmKGU9Zyk7ZCY9fmZ9ZD1lO2Q9QigpLWQ7ZD0oMTIwPmQ/MTIwOjQ4MD5kPzQ4MDoxMDgwPmQ/MTA4MDoxOTIwPmQ/MTkyMDozRTM+ZD8zRTM6NDMyMD5kPzQzMjA6MTk2MCptayhkLzE5NjApKS1kO2lmKDEwPGQpe2EudGltZW91dEhhbmRsZT1GZihRay5iaW5kKG51bGwsYSx1ayx2ayksZCk7YnJlYWt9UWsoYSx1ayx2ayk7YnJlYWs7Y2FzZSA1OlFrKGEsdWssdmspO2JyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IocCgzMjkpKTt9fX1FayhhLEIoKSk7cmV0dXJuIGEuY2FsbGJhY2tOb2RlPT09Yz9Iay5iaW5kKG51bGwsYSk6bnVsbH1cbmZ1bmN0aW9uIE9rKGEsYil7dmFyIGM9dGs7YS5jdXJyZW50Lm1lbW9pemVkU3RhdGUuaXNEZWh5ZHJhdGVkJiYoTGsoYSxiKS5mbGFnc3w9MjU2KTthPUprKGEsYik7MiE9PWEmJihiPXVrLHVrPWMsbnVsbCE9PWImJkdqKGIpKTtyZXR1cm4gYX1mdW5jdGlvbiBHaihhKXtudWxsPT09dWs/dWs9YTp1ay5wdXNoLmFwcGx5KHVrLGEpfVxuZnVuY3Rpb24gUGsoYSl7Zm9yKHZhciBiPWE7Oyl7aWYoYi5mbGFncyYxNjM4NCl7dmFyIGM9Yi51cGRhdGVRdWV1ZTtpZihudWxsIT09YyYmKGM9Yy5zdG9yZXMsbnVsbCE9PWMpKWZvcih2YXIgZD0wO2Q8Yy5sZW5ndGg7ZCsrKXt2YXIgZT1jW2RdLGY9ZS5nZXRTbmFwc2hvdDtlPWUudmFsdWU7dHJ5e2lmKCFIZShmKCksZSkpcmV0dXJuITF9Y2F0Y2goZyl7cmV0dXJuITF9fX1jPWIuY2hpbGQ7aWYoYi5zdWJ0cmVlRmxhZ3MmMTYzODQmJm51bGwhPT1jKWMucmV0dXJuPWIsYj1jO2Vsc2V7aWYoYj09PWEpYnJlYWs7Zm9yKDtudWxsPT09Yi5zaWJsaW5nOyl7aWYobnVsbD09PWIucmV0dXJufHxiLnJldHVybj09PWEpcmV0dXJuITA7Yj1iLnJldHVybn1iLnNpYmxpbmcucmV0dXJuPWIucmV0dXJuO2I9Yi5zaWJsaW5nfX1yZXR1cm4hMH1cbmZ1bmN0aW9uIERrKGEsYil7YiY9fnNrO2ImPX5yazthLnN1c3BlbmRlZExhbmVzfD1iO2EucGluZ2VkTGFuZXMmPX5iO2ZvcihhPWEuZXhwaXJhdGlvblRpbWVzOzA8Yjspe3ZhciBjPTMxLW9jKGIpLGQ9MTw8YzthW2NdPS0xO2ImPX5kfX1mdW5jdGlvbiBGayhhKXtpZigwIT09KEsmNikpdGhyb3cgRXJyb3IocCgzMjcpKTtJaygpO3ZhciBiPXVjKGEsMCk7aWYoMD09PShiJjEpKXJldHVybiBFayhhLEIoKSksbnVsbDt2YXIgYz1KayhhLGIpO2lmKDAhPT1hLnRhZyYmMj09PWMpe3ZhciBkPXhjKGEpOzAhPT1kJiYoYj1kLGM9T2soYSxkKSl9aWYoMT09PWMpdGhyb3cgYz1xayxMayhhLDApLERrKGEsYiksRWsoYSxCKCkpLGM7aWYoNj09PWMpdGhyb3cgRXJyb3IocCgzNDUpKTthLmZpbmlzaGVkV29yaz1hLmN1cnJlbnQuYWx0ZXJuYXRlO2EuZmluaXNoZWRMYW5lcz1iO1FrKGEsdWssdmspO0VrKGEsQigpKTtyZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFJrKGEsYil7dmFyIGM9SztLfD0xO3RyeXtyZXR1cm4gYShiKX1maW5hbGx5e0s9YywwPT09SyYmKEhqPUIoKSs1MDAsZmcmJmpnKCkpfX1mdW5jdGlvbiBTayhhKXtudWxsIT09eGsmJjA9PT14ay50YWcmJjA9PT0oSyY2KSYmSWsoKTt2YXIgYj1LO0t8PTE7dmFyIGM9cGsudHJhbnNpdGlvbixkPUM7dHJ5e2lmKHBrLnRyYW5zaXRpb249bnVsbCxDPTEsYSlyZXR1cm4gYSgpfWZpbmFsbHl7Qz1kLHBrLnRyYW5zaXRpb249YyxLPWIsMD09PShLJjYpJiZqZygpfX1mdW5jdGlvbiBJaigpe2dqPWZqLmN1cnJlbnQ7RShmail9XG5mdW5jdGlvbiBMayhhLGIpe2EuZmluaXNoZWRXb3JrPW51bGw7YS5maW5pc2hlZExhbmVzPTA7dmFyIGM9YS50aW1lb3V0SGFuZGxlOy0xIT09YyYmKGEudGltZW91dEhhbmRsZT0tMSxHZihjKSk7aWYobnVsbCE9PVkpZm9yKGM9WS5yZXR1cm47bnVsbCE9PWM7KXt2YXIgZD1jO3dnKGQpO3N3aXRjaChkLnRhZyl7Y2FzZSAxOmQ9ZC50eXBlLmNoaWxkQ29udGV4dFR5cGVzO251bGwhPT1kJiZ2b2lkIDAhPT1kJiYkZigpO2JyZWFrO2Nhc2UgMzpKaCgpO0UoV2YpO0UoSCk7T2goKTticmVhaztjYXNlIDU6TGgoZCk7YnJlYWs7Y2FzZSA0OkpoKCk7YnJlYWs7Y2FzZSAxMzpFKE0pO2JyZWFrO2Nhc2UgMTk6RShNKTticmVhaztjYXNlIDEwOlJnKGQudHlwZS5fY29udGV4dCk7YnJlYWs7Y2FzZSAyMjpjYXNlIDIzOklqKCl9Yz1jLnJldHVybn1SPWE7WT1hPXdoKGEuY3VycmVudCxudWxsKTtaPWdqPWI7VD0wO3FrPW51bGw7c2s9cms9aGg9MDt1az10az1udWxsO2lmKG51bGwhPT1XZyl7Zm9yKGI9XG4wO2I8V2cubGVuZ3RoO2IrKylpZihjPVdnW2JdLGQ9Yy5pbnRlcmxlYXZlZCxudWxsIT09ZCl7Yy5pbnRlcmxlYXZlZD1udWxsO3ZhciBlPWQubmV4dCxmPWMucGVuZGluZztpZihudWxsIT09Zil7dmFyIGc9Zi5uZXh0O2YubmV4dD1lO2QubmV4dD1nfWMucGVuZGluZz1kfVdnPW51bGx9cmV0dXJuIGF9XG5mdW5jdGlvbiBOayhhLGIpe2Rve3ZhciBjPVk7dHJ5e1FnKCk7UGguY3VycmVudD1haTtpZihTaCl7Zm9yKHZhciBkPU4ubWVtb2l6ZWRTdGF0ZTtudWxsIT09ZDspe3ZhciBlPWQucXVldWU7bnVsbCE9PWUmJihlLnBlbmRpbmc9bnVsbCk7ZD1kLm5leHR9U2g9ITF9Umg9MDtQPU89Tj1udWxsO1RoPSExO1VoPTA7b2suY3VycmVudD1udWxsO2lmKG51bGw9PT1jfHxudWxsPT09Yy5yZXR1cm4pe1Q9MTtxaz1iO1k9bnVsbDticmVha31hOnt2YXIgZj1hLGc9Yy5yZXR1cm4saD1jLGs9YjtiPVo7aC5mbGFnc3w9MzI3Njg7aWYobnVsbCE9PWsmJlwib2JqZWN0XCI9PT10eXBlb2YgayYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGsudGhlbil7dmFyIGw9ayxtPWgscT1tLnRhZztpZigwPT09KG0ubW9kZSYxKSYmKDA9PT1xfHwxMT09PXF8fDE1PT09cSkpe3ZhciByPW0uYWx0ZXJuYXRlO3I/KG0udXBkYXRlUXVldWU9ci51cGRhdGVRdWV1ZSxtLm1lbW9pemVkU3RhdGU9ci5tZW1vaXplZFN0YXRlLFxubS5sYW5lcz1yLmxhbmVzKToobS51cGRhdGVRdWV1ZT1udWxsLG0ubWVtb2l6ZWRTdGF0ZT1udWxsKX12YXIgeT1WaShnKTtpZihudWxsIT09eSl7eS5mbGFncyY9LTI1NztXaSh5LGcsaCxmLGIpO3kubW9kZSYxJiZUaShmLGwsYik7Yj15O2s9bDt2YXIgbj1iLnVwZGF0ZVF1ZXVlO2lmKG51bGw9PT1uKXt2YXIgdD1uZXcgU2V0O3QuYWRkKGspO2IudXBkYXRlUXVldWU9dH1lbHNlIG4uYWRkKGspO2JyZWFrIGF9ZWxzZXtpZigwPT09KGImMSkpe1RpKGYsbCxiKTt1aigpO2JyZWFrIGF9az1FcnJvcihwKDQyNikpfX1lbHNlIGlmKEkmJmgubW9kZSYxKXt2YXIgSj1WaShnKTtpZihudWxsIT09Sil7MD09PShKLmZsYWdzJjY1NTM2KSYmKEouZmxhZ3N8PTI1Nik7V2koSixnLGgsZixiKTtKZyhLaShrLGgpKTticmVhayBhfX1mPWs9S2koayxoKTs0IT09VCYmKFQ9Mik7bnVsbD09PXRrP3RrPVtmXTp0ay5wdXNoKGYpO2Y9Zztkb3tzd2l0Y2goZi50YWcpe2Nhc2UgMzpmLmZsYWdzfD02NTUzNjtcbmImPS1iO2YubGFuZXN8PWI7dmFyIHg9T2koZixrLGIpO2ZoKGYseCk7YnJlYWsgYTtjYXNlIDE6aD1rO3ZhciB3PWYudHlwZSx1PWYuc3RhdGVOb2RlO2lmKDA9PT0oZi5mbGFncyYxMjgpJiYoXCJmdW5jdGlvblwiPT09dHlwZW9mIHcuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yfHxudWxsIT09dSYmXCJmdW5jdGlvblwiPT09dHlwZW9mIHUuY29tcG9uZW50RGlkQ2F0Y2gmJihudWxsPT09U2l8fCFTaS5oYXModSkpKSl7Zi5mbGFnc3w9NjU1MzY7YiY9LWI7Zi5sYW5lc3w9Yjt2YXIgRj1SaShmLGgsYik7ZmgoZixGKTticmVhayBhfX1mPWYucmV0dXJufXdoaWxlKG51bGwhPT1mKX1UayhjKX1jYXRjaChuYSl7Yj1uYTtZPT09YyYmbnVsbCE9PWMmJihZPWM9Yy5yZXR1cm4pO2NvbnRpbnVlfWJyZWFrfXdoaWxlKDEpfWZ1bmN0aW9uIEtrKCl7dmFyIGE9bmsuY3VycmVudDtuay5jdXJyZW50PWFpO3JldHVybiBudWxsPT09YT9haTphfVxuZnVuY3Rpb24gdWooKXtpZigwPT09VHx8Mz09PVR8fDI9PT1UKVQ9NDtudWxsPT09Unx8MD09PShoaCYyNjg0MzU0NTUpJiYwPT09KHJrJjI2ODQzNTQ1NSl8fERrKFIsWil9ZnVuY3Rpb24gSmsoYSxiKXt2YXIgYz1LO0t8PTI7dmFyIGQ9S2soKTtpZihSIT09YXx8WiE9PWIpdms9bnVsbCxMayhhLGIpO2RvIHRyeXtVaygpO2JyZWFrfWNhdGNoKGUpe05rKGEsZSl9d2hpbGUoMSk7UWcoKTtLPWM7bmsuY3VycmVudD1kO2lmKG51bGwhPT1ZKXRocm93IEVycm9yKHAoMjYxKSk7Uj1udWxsO1o9MDtyZXR1cm4gVH1mdW5jdGlvbiBVaygpe2Zvcig7bnVsbCE9PVk7KVZrKFkpfWZ1bmN0aW9uIE1rKCl7Zm9yKDtudWxsIT09WSYmIWNjKCk7KVZrKFkpfWZ1bmN0aW9uIFZrKGEpe3ZhciBiPVdrKGEuYWx0ZXJuYXRlLGEsZ2opO2EubWVtb2l6ZWRQcm9wcz1hLnBlbmRpbmdQcm9wcztudWxsPT09Yj9UayhhKTpZPWI7b2suY3VycmVudD1udWxsfVxuZnVuY3Rpb24gVGsoYSl7dmFyIGI9YTtkb3t2YXIgYz1iLmFsdGVybmF0ZTthPWIucmV0dXJuO2lmKDA9PT0oYi5mbGFncyYzMjc2OCkpe2lmKGM9RmooYyxiLGdqKSxudWxsIT09Yyl7WT1jO3JldHVybn19ZWxzZXtjPUpqKGMsYik7aWYobnVsbCE9PWMpe2MuZmxhZ3MmPTMyNzY3O1k9YztyZXR1cm59aWYobnVsbCE9PWEpYS5mbGFnc3w9MzI3NjgsYS5zdWJ0cmVlRmxhZ3M9MCxhLmRlbGV0aW9ucz1udWxsO2Vsc2V7VD02O1k9bnVsbDtyZXR1cm59fWI9Yi5zaWJsaW5nO2lmKG51bGwhPT1iKXtZPWI7cmV0dXJufVk9Yj1hfXdoaWxlKG51bGwhPT1iKTswPT09VCYmKFQ9NSl9ZnVuY3Rpb24gUWsoYSxiLGMpe3ZhciBkPUMsZT1way50cmFuc2l0aW9uO3RyeXtway50cmFuc2l0aW9uPW51bGwsQz0xLFhrKGEsYixjLGQpfWZpbmFsbHl7cGsudHJhbnNpdGlvbj1lLEM9ZH1yZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFhrKGEsYixjLGQpe2RvIElrKCk7d2hpbGUobnVsbCE9PXhrKTtpZigwIT09KEsmNikpdGhyb3cgRXJyb3IocCgzMjcpKTtjPWEuZmluaXNoZWRXb3JrO3ZhciBlPWEuZmluaXNoZWRMYW5lcztpZihudWxsPT09YylyZXR1cm4gbnVsbDthLmZpbmlzaGVkV29yaz1udWxsO2EuZmluaXNoZWRMYW5lcz0wO2lmKGM9PT1hLmN1cnJlbnQpdGhyb3cgRXJyb3IocCgxNzcpKTthLmNhbGxiYWNrTm9kZT1udWxsO2EuY2FsbGJhY2tQcmlvcml0eT0wO3ZhciBmPWMubGFuZXN8Yy5jaGlsZExhbmVzO0JjKGEsZik7YT09PVImJihZPVI9bnVsbCxaPTApOzA9PT0oYy5zdWJ0cmVlRmxhZ3MmMjA2NCkmJjA9PT0oYy5mbGFncyYyMDY0KXx8d2t8fCh3az0hMCxHayhoYyxmdW5jdGlvbigpe0lrKCk7cmV0dXJuIG51bGx9KSk7Zj0wIT09KGMuZmxhZ3MmMTU5OTApO2lmKDAhPT0oYy5zdWJ0cmVlRmxhZ3MmMTU5OTApfHxmKXtmPXBrLnRyYW5zaXRpb247cGsudHJhbnNpdGlvbj1udWxsO1xudmFyIGc9QztDPTE7dmFyIGg9SztLfD00O29rLmN1cnJlbnQ9bnVsbDtQaihhLGMpO2VrKGMsYSk7T2UoRGYpO2RkPSEhQ2Y7RGY9Q2Y9bnVsbDthLmN1cnJlbnQ9YztpayhjLGEsZSk7ZGMoKTtLPWg7Qz1nO3BrLnRyYW5zaXRpb249Zn1lbHNlIGEuY3VycmVudD1jO3drJiYod2s9ITEseGs9YSx5az1lKTtmPWEucGVuZGluZ0xhbmVzOzA9PT1mJiYoU2k9bnVsbCk7bWMoYy5zdGF0ZU5vZGUsZCk7RWsoYSxCKCkpO2lmKG51bGwhPT1iKWZvcihkPWEub25SZWNvdmVyYWJsZUVycm9yLGM9MDtjPGIubGVuZ3RoO2MrKyllPWJbY10sZChlLnZhbHVlLHtjb21wb25lbnRTdGFjazplLnN0YWNrLGRpZ2VzdDplLmRpZ2VzdH0pO2lmKFBpKXRocm93IFBpPSExLGE9UWksUWk9bnVsbCxhOzAhPT0oeWsmMSkmJjAhPT1hLnRhZyYmSWsoKTtmPWEucGVuZGluZ0xhbmVzOzAhPT0oZiYxKT9hPT09QWs/emsrKzooems9MCxBaz1hKTp6az0wO2pnKCk7cmV0dXJuIG51bGx9XG5mdW5jdGlvbiBJaygpe2lmKG51bGwhPT14ayl7dmFyIGE9RGMoeWspLGI9cGsudHJhbnNpdGlvbixjPUM7dHJ5e3BrLnRyYW5zaXRpb249bnVsbDtDPTE2PmE/MTY6YTtpZihudWxsPT09eGspdmFyIGQ9ITE7ZWxzZXthPXhrO3hrPW51bGw7eWs9MDtpZigwIT09KEsmNikpdGhyb3cgRXJyb3IocCgzMzEpKTt2YXIgZT1LO0t8PTQ7Zm9yKFY9YS5jdXJyZW50O251bGwhPT1WOyl7dmFyIGY9VixnPWYuY2hpbGQ7aWYoMCE9PShWLmZsYWdzJjE2KSl7dmFyIGg9Zi5kZWxldGlvbnM7aWYobnVsbCE9PWgpe2Zvcih2YXIgaz0wO2s8aC5sZW5ndGg7aysrKXt2YXIgbD1oW2tdO2ZvcihWPWw7bnVsbCE9PVY7KXt2YXIgbT1WO3N3aXRjaChtLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNTpRaig4LG0sZil9dmFyIHE9bS5jaGlsZDtpZihudWxsIT09cSlxLnJldHVybj1tLFY9cTtlbHNlIGZvcig7bnVsbCE9PVY7KXttPVY7dmFyIHI9bS5zaWJsaW5nLHk9bS5yZXR1cm47VGoobSk7aWYobT09PVxubCl7Vj1udWxsO2JyZWFrfWlmKG51bGwhPT1yKXtyLnJldHVybj15O1Y9cjticmVha31WPXl9fX12YXIgbj1mLmFsdGVybmF0ZTtpZihudWxsIT09bil7dmFyIHQ9bi5jaGlsZDtpZihudWxsIT09dCl7bi5jaGlsZD1udWxsO2Rve3ZhciBKPXQuc2libGluZzt0LnNpYmxpbmc9bnVsbDt0PUp9d2hpbGUobnVsbCE9PXQpfX1WPWZ9fWlmKDAhPT0oZi5zdWJ0cmVlRmxhZ3MmMjA2NCkmJm51bGwhPT1nKWcucmV0dXJuPWYsVj1nO2Vsc2UgYjpmb3IoO251bGwhPT1WOyl7Zj1WO2lmKDAhPT0oZi5mbGFncyYyMDQ4KSlzd2l0Y2goZi50YWcpe2Nhc2UgMDpjYXNlIDExOmNhc2UgMTU6UWooOSxmLGYucmV0dXJuKX12YXIgeD1mLnNpYmxpbmc7aWYobnVsbCE9PXgpe3gucmV0dXJuPWYucmV0dXJuO1Y9eDticmVhayBifVY9Zi5yZXR1cm59fXZhciB3PWEuY3VycmVudDtmb3IoVj13O251bGwhPT1WOyl7Zz1WO3ZhciB1PWcuY2hpbGQ7aWYoMCE9PShnLnN1YnRyZWVGbGFncyYyMDY0KSYmbnVsbCE9PVxudSl1LnJldHVybj1nLFY9dTtlbHNlIGI6Zm9yKGc9dztudWxsIT09Vjspe2g9VjtpZigwIT09KGguZmxhZ3MmMjA0OCkpdHJ5e3N3aXRjaChoLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNTpSaig5LGgpfX1jYXRjaChuYSl7VyhoLGgucmV0dXJuLG5hKX1pZihoPT09Zyl7Vj1udWxsO2JyZWFrIGJ9dmFyIEY9aC5zaWJsaW5nO2lmKG51bGwhPT1GKXtGLnJldHVybj1oLnJldHVybjtWPUY7YnJlYWsgYn1WPWgucmV0dXJufX1LPWU7amcoKTtpZihsYyYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGxjLm9uUG9zdENvbW1pdEZpYmVyUm9vdCl0cnl7bGMub25Qb3N0Q29tbWl0RmliZXJSb290KGtjLGEpfWNhdGNoKG5hKXt9ZD0hMH1yZXR1cm4gZH1maW5hbGx5e0M9Yyxway50cmFuc2l0aW9uPWJ9fXJldHVybiExfWZ1bmN0aW9uIFlrKGEsYixjKXtiPUtpKGMsYik7Yj1PaShhLGIsMSk7YT1kaChhLGIsMSk7Yj1MKCk7bnVsbCE9PWEmJihBYyhhLDEsYiksRWsoYSxiKSl9XG5mdW5jdGlvbiBXKGEsYixjKXtpZigzPT09YS50YWcpWWsoYSxhLGMpO2Vsc2UgZm9yKDtudWxsIT09Yjspe2lmKDM9PT1iLnRhZyl7WWsoYixhLGMpO2JyZWFrfWVsc2UgaWYoMT09PWIudGFnKXt2YXIgZD1iLnN0YXRlTm9kZTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi50eXBlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcnx8XCJmdW5jdGlvblwiPT09dHlwZW9mIGQuY29tcG9uZW50RGlkQ2F0Y2gmJihudWxsPT09U2l8fCFTaS5oYXMoZCkpKXthPUtpKGMsYSk7YT1SaShiLGEsMSk7Yj1kaChiLGEsMSk7YT1MKCk7bnVsbCE9PWImJihBYyhiLDEsYSksRWsoYixhKSk7YnJlYWt9fWI9Yi5yZXR1cm59fVxuZnVuY3Rpb24gVWkoYSxiLGMpe3ZhciBkPWEucGluZ0NhY2hlO251bGwhPT1kJiZkLmRlbGV0ZShiKTtiPUwoKTthLnBpbmdlZExhbmVzfD1hLnN1c3BlbmRlZExhbmVzJmM7Uj09PWEmJihaJmMpPT09YyYmKDQ9PT1UfHwzPT09VCYmKFomMTMwMDIzNDI0KT09PVomJjUwMD5CKCktZ2s/TGsoYSwwKTpza3w9Yyk7RWsoYSxiKX1mdW5jdGlvbiBaayhhLGIpezA9PT1iJiYoMD09PShhLm1vZGUmMSk/Yj0xOihiPXNjLHNjPDw9MSwwPT09KHNjJjEzMDAyMzQyNCkmJihzYz00MTk0MzA0KSkpO3ZhciBjPUwoKTthPVpnKGEsYik7bnVsbCE9PWEmJihBYyhhLGIsYyksRWsoYSxjKSl9ZnVuY3Rpb24gdmooYSl7dmFyIGI9YS5tZW1vaXplZFN0YXRlLGM9MDtudWxsIT09YiYmKGM9Yi5yZXRyeUxhbmUpO1prKGEsYyl9XG5mdW5jdGlvbiBjayhhLGIpe3ZhciBjPTA7c3dpdGNoKGEudGFnKXtjYXNlIDEzOnZhciBkPWEuc3RhdGVOb2RlO3ZhciBlPWEubWVtb2l6ZWRTdGF0ZTtudWxsIT09ZSYmKGM9ZS5yZXRyeUxhbmUpO2JyZWFrO2Nhc2UgMTk6ZD1hLnN0YXRlTm9kZTticmVhaztkZWZhdWx0OnRocm93IEVycm9yKHAoMzE0KSk7fW51bGwhPT1kJiZkLmRlbGV0ZShiKTtaayhhLGMpfXZhciBXaztcbldrPWZ1bmN0aW9uKGEsYixjKXtpZihudWxsIT09YSlpZihhLm1lbW9pemVkUHJvcHMhPT1iLnBlbmRpbmdQcm9wc3x8V2YuY3VycmVudClVZz0hMDtlbHNle2lmKDA9PT0oYS5sYW5lcyZjKSYmMD09PShiLmZsYWdzJjEyOCkpcmV0dXJuIFVnPSExLHpqKGEsYixjKTtVZz0wIT09KGEuZmxhZ3MmMTMxMDcyKT8hMDohMX1lbHNlIFVnPSExLEkmJjAhPT0oYi5mbGFncyYxMDQ4NTc2KSYmdWcoYixuZyxiLmluZGV4KTtiLmxhbmVzPTA7c3dpdGNoKGIudGFnKXtjYXNlIDI6dmFyIGQ9Yi50eXBlO2pqKGEsYik7YT1iLnBlbmRpbmdQcm9wczt2YXIgZT1ZZihiLEguY3VycmVudCk7VGcoYixjKTtlPVhoKG51bGwsYixkLGEsZSxjKTt2YXIgZj1iaSgpO2IuZmxhZ3N8PTE7XCJvYmplY3RcIj09PXR5cGVvZiBlJiZudWxsIT09ZSYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGUucmVuZGVyJiZ2b2lkIDA9PT1lLiQkdHlwZW9mPyhiLnRhZz0xLGIubWVtb2l6ZWRTdGF0ZT1udWxsLGIudXBkYXRlUXVldWU9XG5udWxsLFpmKGQpPyhmPSEwLGNnKGIpKTpmPSExLGIubWVtb2l6ZWRTdGF0ZT1udWxsIT09ZS5zdGF0ZSYmdm9pZCAwIT09ZS5zdGF0ZT9lLnN0YXRlOm51bGwsYWgoYiksZS51cGRhdGVyPW5oLGIuc3RhdGVOb2RlPWUsZS5fcmVhY3RJbnRlcm5hbHM9YixyaChiLGQsYSxjKSxiPWtqKG51bGwsYixkLCEwLGYsYykpOihiLnRhZz0wLEkmJmYmJnZnKGIpLFlpKG51bGwsYixlLGMpLGI9Yi5jaGlsZCk7cmV0dXJuIGI7Y2FzZSAxNjpkPWIuZWxlbWVudFR5cGU7YTp7amooYSxiKTthPWIucGVuZGluZ1Byb3BzO2U9ZC5faW5pdDtkPWUoZC5fcGF5bG9hZCk7Yi50eXBlPWQ7ZT1iLnRhZz0kayhkKTthPUxnKGQsYSk7c3dpdGNoKGUpe2Nhc2UgMDpiPWRqKG51bGwsYixkLGEsYyk7YnJlYWsgYTtjYXNlIDE6Yj1paihudWxsLGIsZCxhLGMpO2JyZWFrIGE7Y2FzZSAxMTpiPVppKG51bGwsYixkLGEsYyk7YnJlYWsgYTtjYXNlIDE0OmI9YWoobnVsbCxiLGQsTGcoZC50eXBlLGEpLGMpO2JyZWFrIGF9dGhyb3cgRXJyb3IocCgzMDYsXG5kLFwiXCIpKTt9cmV0dXJuIGI7Y2FzZSAwOnJldHVybiBkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGU9Yi5lbGVtZW50VHlwZT09PWQ/ZTpMZyhkLGUpLGRqKGEsYixkLGUsYyk7Y2FzZSAxOnJldHVybiBkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGU9Yi5lbGVtZW50VHlwZT09PWQ/ZTpMZyhkLGUpLGlqKGEsYixkLGUsYyk7Y2FzZSAzOmE6e2xqKGIpO2lmKG51bGw9PT1hKXRocm93IEVycm9yKHAoMzg3KSk7ZD1iLnBlbmRpbmdQcm9wcztmPWIubWVtb2l6ZWRTdGF0ZTtlPWYuZWxlbWVudDtiaChhLGIpO2doKGIsZCxudWxsLGMpO3ZhciBnPWIubWVtb2l6ZWRTdGF0ZTtkPWcuZWxlbWVudDtpZihmLmlzRGVoeWRyYXRlZClpZihmPXtlbGVtZW50OmQsaXNEZWh5ZHJhdGVkOiExLGNhY2hlOmcuY2FjaGUscGVuZGluZ1N1c3BlbnNlQm91bmRhcmllczpnLnBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXMsdHJhbnNpdGlvbnM6Zy50cmFuc2l0aW9uc30sYi51cGRhdGVRdWV1ZS5iYXNlU3RhdGU9XG5mLGIubWVtb2l6ZWRTdGF0ZT1mLGIuZmxhZ3MmMjU2KXtlPUtpKEVycm9yKHAoNDIzKSksYik7Yj1taihhLGIsZCxjLGUpO2JyZWFrIGF9ZWxzZSBpZihkIT09ZSl7ZT1LaShFcnJvcihwKDQyNCkpLGIpO2I9bWooYSxiLGQsYyxlKTticmVhayBhfWVsc2UgZm9yKHlnPUxmKGIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8uZmlyc3RDaGlsZCkseGc9YixJPSEwLHpnPW51bGwsYz1DaChiLG51bGwsZCxjKSxiLmNoaWxkPWM7YzspYy5mbGFncz1jLmZsYWdzJi0zfDQwOTYsYz1jLnNpYmxpbmc7ZWxzZXtJZygpO2lmKGQ9PT1lKXtiPSRpKGEsYixjKTticmVhayBhfVlpKGEsYixkLGMpfWI9Yi5jaGlsZH1yZXR1cm4gYjtjYXNlIDU6cmV0dXJuIEtoKGIpLG51bGw9PT1hJiZFZyhiKSxkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGY9bnVsbCE9PWE/YS5tZW1vaXplZFByb3BzOm51bGwsZz1lLmNoaWxkcmVuLEVmKGQsZSk/Zz1udWxsOm51bGwhPT1mJiZFZihkLGYpJiYoYi5mbGFnc3w9MzIpLFxuaGooYSxiKSxZaShhLGIsZyxjKSxiLmNoaWxkO2Nhc2UgNjpyZXR1cm4gbnVsbD09PWEmJkVnKGIpLG51bGw7Y2FzZSAxMzpyZXR1cm4gcGooYSxiLGMpO2Nhc2UgNDpyZXR1cm4gSWgoYixiLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKSxkPWIucGVuZGluZ1Byb3BzLG51bGw9PT1hP2IuY2hpbGQ9QmgoYixudWxsLGQsYyk6WWkoYSxiLGQsYyksYi5jaGlsZDtjYXNlIDExOnJldHVybiBkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGU9Yi5lbGVtZW50VHlwZT09PWQ/ZTpMZyhkLGUpLFppKGEsYixkLGUsYyk7Y2FzZSA3OnJldHVybiBZaShhLGIsYi5wZW5kaW5nUHJvcHMsYyksYi5jaGlsZDtjYXNlIDg6cmV0dXJuIFlpKGEsYixiLnBlbmRpbmdQcm9wcy5jaGlsZHJlbixjKSxiLmNoaWxkO2Nhc2UgMTI6cmV0dXJuIFlpKGEsYixiLnBlbmRpbmdQcm9wcy5jaGlsZHJlbixjKSxiLmNoaWxkO2Nhc2UgMTA6YTp7ZD1iLnR5cGUuX2NvbnRleHQ7ZT1iLnBlbmRpbmdQcm9wcztmPWIubWVtb2l6ZWRQcm9wcztcbmc9ZS52YWx1ZTtHKE1nLGQuX2N1cnJlbnRWYWx1ZSk7ZC5fY3VycmVudFZhbHVlPWc7aWYobnVsbCE9PWYpaWYoSGUoZi52YWx1ZSxnKSl7aWYoZi5jaGlsZHJlbj09PWUuY2hpbGRyZW4mJiFXZi5jdXJyZW50KXtiPSRpKGEsYixjKTticmVhayBhfX1lbHNlIGZvcihmPWIuY2hpbGQsbnVsbCE9PWYmJihmLnJldHVybj1iKTtudWxsIT09Zjspe3ZhciBoPWYuZGVwZW5kZW5jaWVzO2lmKG51bGwhPT1oKXtnPWYuY2hpbGQ7Zm9yKHZhciBrPWguZmlyc3RDb250ZXh0O251bGwhPT1rOyl7aWYoay5jb250ZXh0PT09ZCl7aWYoMT09PWYudGFnKXtrPWNoKC0xLGMmLWMpO2sudGFnPTI7dmFyIGw9Zi51cGRhdGVRdWV1ZTtpZihudWxsIT09bCl7bD1sLnNoYXJlZDt2YXIgbT1sLnBlbmRpbmc7bnVsbD09PW0/ay5uZXh0PWs6KGsubmV4dD1tLm5leHQsbS5uZXh0PWspO2wucGVuZGluZz1rfX1mLmxhbmVzfD1jO2s9Zi5hbHRlcm5hdGU7bnVsbCE9PWsmJihrLmxhbmVzfD1jKTtTZyhmLnJldHVybixcbmMsYik7aC5sYW5lc3w9YzticmVha31rPWsubmV4dH19ZWxzZSBpZigxMD09PWYudGFnKWc9Zi50eXBlPT09Yi50eXBlP251bGw6Zi5jaGlsZDtlbHNlIGlmKDE4PT09Zi50YWcpe2c9Zi5yZXR1cm47aWYobnVsbD09PWcpdGhyb3cgRXJyb3IocCgzNDEpKTtnLmxhbmVzfD1jO2g9Zy5hbHRlcm5hdGU7bnVsbCE9PWgmJihoLmxhbmVzfD1jKTtTZyhnLGMsYik7Zz1mLnNpYmxpbmd9ZWxzZSBnPWYuY2hpbGQ7aWYobnVsbCE9PWcpZy5yZXR1cm49ZjtlbHNlIGZvcihnPWY7bnVsbCE9PWc7KXtpZihnPT09Yil7Zz1udWxsO2JyZWFrfWY9Zy5zaWJsaW5nO2lmKG51bGwhPT1mKXtmLnJldHVybj1nLnJldHVybjtnPWY7YnJlYWt9Zz1nLnJldHVybn1mPWd9WWkoYSxiLGUuY2hpbGRyZW4sYyk7Yj1iLmNoaWxkfXJldHVybiBiO2Nhc2UgOTpyZXR1cm4gZT1iLnR5cGUsZD1iLnBlbmRpbmdQcm9wcy5jaGlsZHJlbixUZyhiLGMpLGU9VmcoZSksZD1kKGUpLGIuZmxhZ3N8PTEsWWkoYSxiLGQsYyksXG5iLmNoaWxkO2Nhc2UgMTQ6cmV0dXJuIGQ9Yi50eXBlLGU9TGcoZCxiLnBlbmRpbmdQcm9wcyksZT1MZyhkLnR5cGUsZSksYWooYSxiLGQsZSxjKTtjYXNlIDE1OnJldHVybiBjaihhLGIsYi50eXBlLGIucGVuZGluZ1Byb3BzLGMpO2Nhc2UgMTc6cmV0dXJuIGQ9Yi50eXBlLGU9Yi5wZW5kaW5nUHJvcHMsZT1iLmVsZW1lbnRUeXBlPT09ZD9lOkxnKGQsZSksamooYSxiKSxiLnRhZz0xLFpmKGQpPyhhPSEwLGNnKGIpKTphPSExLFRnKGIsYykscGgoYixkLGUpLHJoKGIsZCxlLGMpLGtqKG51bGwsYixkLCEwLGEsYyk7Y2FzZSAxOTpyZXR1cm4geWooYSxiLGMpO2Nhc2UgMjI6cmV0dXJuIGVqKGEsYixjKX10aHJvdyBFcnJvcihwKDE1NixiLnRhZykpO307ZnVuY3Rpb24gR2soYSxiKXtyZXR1cm4gYWMoYSxiKX1cbmZ1bmN0aW9uIGFsKGEsYixjLGQpe3RoaXMudGFnPWE7dGhpcy5rZXk9Yzt0aGlzLnNpYmxpbmc9dGhpcy5jaGlsZD10aGlzLnJldHVybj10aGlzLnN0YXRlTm9kZT10aGlzLnR5cGU9dGhpcy5lbGVtZW50VHlwZT1udWxsO3RoaXMuaW5kZXg9MDt0aGlzLnJlZj1udWxsO3RoaXMucGVuZGluZ1Byb3BzPWI7dGhpcy5kZXBlbmRlbmNpZXM9dGhpcy5tZW1vaXplZFN0YXRlPXRoaXMudXBkYXRlUXVldWU9dGhpcy5tZW1vaXplZFByb3BzPW51bGw7dGhpcy5tb2RlPWQ7dGhpcy5zdWJ0cmVlRmxhZ3M9dGhpcy5mbGFncz0wO3RoaXMuZGVsZXRpb25zPW51bGw7dGhpcy5jaGlsZExhbmVzPXRoaXMubGFuZXM9MDt0aGlzLmFsdGVybmF0ZT1udWxsfWZ1bmN0aW9uIEJnKGEsYixjLGQpe3JldHVybiBuZXcgYWwoYSxiLGMsZCl9ZnVuY3Rpb24gYmooYSl7YT1hLnByb3RvdHlwZTtyZXR1cm4hKCFhfHwhYS5pc1JlYWN0Q29tcG9uZW50KX1cbmZ1bmN0aW9uICRrKGEpe2lmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBhKXJldHVybiBiaihhKT8xOjA7aWYodm9pZCAwIT09YSYmbnVsbCE9PWEpe2E9YS4kJHR5cGVvZjtpZihhPT09RGEpcmV0dXJuIDExO2lmKGE9PT1HYSlyZXR1cm4gMTR9cmV0dXJuIDJ9XG5mdW5jdGlvbiB3aChhLGIpe3ZhciBjPWEuYWx0ZXJuYXRlO251bGw9PT1jPyhjPUJnKGEudGFnLGIsYS5rZXksYS5tb2RlKSxjLmVsZW1lbnRUeXBlPWEuZWxlbWVudFR5cGUsYy50eXBlPWEudHlwZSxjLnN0YXRlTm9kZT1hLnN0YXRlTm9kZSxjLmFsdGVybmF0ZT1hLGEuYWx0ZXJuYXRlPWMpOihjLnBlbmRpbmdQcm9wcz1iLGMudHlwZT1hLnR5cGUsYy5mbGFncz0wLGMuc3VidHJlZUZsYWdzPTAsYy5kZWxldGlvbnM9bnVsbCk7Yy5mbGFncz1hLmZsYWdzJjE0NjgwMDY0O2MuY2hpbGRMYW5lcz1hLmNoaWxkTGFuZXM7Yy5sYW5lcz1hLmxhbmVzO2MuY2hpbGQ9YS5jaGlsZDtjLm1lbW9pemVkUHJvcHM9YS5tZW1vaXplZFByb3BzO2MubWVtb2l6ZWRTdGF0ZT1hLm1lbW9pemVkU3RhdGU7Yy51cGRhdGVRdWV1ZT1hLnVwZGF0ZVF1ZXVlO2I9YS5kZXBlbmRlbmNpZXM7Yy5kZXBlbmRlbmNpZXM9bnVsbD09PWI/bnVsbDp7bGFuZXM6Yi5sYW5lcyxmaXJzdENvbnRleHQ6Yi5maXJzdENvbnRleHR9O1xuYy5zaWJsaW5nPWEuc2libGluZztjLmluZGV4PWEuaW5kZXg7Yy5yZWY9YS5yZWY7cmV0dXJuIGN9XG5mdW5jdGlvbiB5aChhLGIsYyxkLGUsZil7dmFyIGc9MjtkPWE7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGEpYmooYSkmJihnPTEpO2Vsc2UgaWYoXCJzdHJpbmdcIj09PXR5cGVvZiBhKWc9NTtlbHNlIGE6c3dpdGNoKGEpe2Nhc2UgeWE6cmV0dXJuIEFoKGMuY2hpbGRyZW4sZSxmLGIpO2Nhc2UgemE6Zz04O2V8PTg7YnJlYWs7Y2FzZSBBYTpyZXR1cm4gYT1CZygxMixjLGIsZXwyKSxhLmVsZW1lbnRUeXBlPUFhLGEubGFuZXM9ZixhO2Nhc2UgRWE6cmV0dXJuIGE9QmcoMTMsYyxiLGUpLGEuZWxlbWVudFR5cGU9RWEsYS5sYW5lcz1mLGE7Y2FzZSBGYTpyZXR1cm4gYT1CZygxOSxjLGIsZSksYS5lbGVtZW50VHlwZT1GYSxhLmxhbmVzPWYsYTtjYXNlIElhOnJldHVybiBxaihjLGUsZixiKTtkZWZhdWx0OmlmKFwib2JqZWN0XCI9PT10eXBlb2YgYSYmbnVsbCE9PWEpc3dpdGNoKGEuJCR0eXBlb2Ype2Nhc2UgQmE6Zz0xMDticmVhayBhO2Nhc2UgQ2E6Zz05O2JyZWFrIGE7Y2FzZSBEYTpnPTExO1xuYnJlYWsgYTtjYXNlIEdhOmc9MTQ7YnJlYWsgYTtjYXNlIEhhOmc9MTY7ZD1udWxsO2JyZWFrIGF9dGhyb3cgRXJyb3IocCgxMzAsbnVsbD09YT9hOnR5cGVvZiBhLFwiXCIpKTt9Yj1CZyhnLGMsYixlKTtiLmVsZW1lbnRUeXBlPWE7Yi50eXBlPWQ7Yi5sYW5lcz1mO3JldHVybiBifWZ1bmN0aW9uIEFoKGEsYixjLGQpe2E9QmcoNyxhLGQsYik7YS5sYW5lcz1jO3JldHVybiBhfWZ1bmN0aW9uIHFqKGEsYixjLGQpe2E9QmcoMjIsYSxkLGIpO2EuZWxlbWVudFR5cGU9SWE7YS5sYW5lcz1jO2Euc3RhdGVOb2RlPXtpc0hpZGRlbjohMX07cmV0dXJuIGF9ZnVuY3Rpb24geGgoYSxiLGMpe2E9QmcoNixhLG51bGwsYik7YS5sYW5lcz1jO3JldHVybiBhfVxuZnVuY3Rpb24gemgoYSxiLGMpe2I9QmcoNCxudWxsIT09YS5jaGlsZHJlbj9hLmNoaWxkcmVuOltdLGEua2V5LGIpO2IubGFuZXM9YztiLnN0YXRlTm9kZT17Y29udGFpbmVySW5mbzphLmNvbnRhaW5lckluZm8scGVuZGluZ0NoaWxkcmVuOm51bGwsaW1wbGVtZW50YXRpb246YS5pbXBsZW1lbnRhdGlvbn07cmV0dXJuIGJ9XG5mdW5jdGlvbiBibChhLGIsYyxkLGUpe3RoaXMudGFnPWI7dGhpcy5jb250YWluZXJJbmZvPWE7dGhpcy5maW5pc2hlZFdvcms9dGhpcy5waW5nQ2FjaGU9dGhpcy5jdXJyZW50PXRoaXMucGVuZGluZ0NoaWxkcmVuPW51bGw7dGhpcy50aW1lb3V0SGFuZGxlPS0xO3RoaXMuY2FsbGJhY2tOb2RlPXRoaXMucGVuZGluZ0NvbnRleHQ9dGhpcy5jb250ZXh0PW51bGw7dGhpcy5jYWxsYmFja1ByaW9yaXR5PTA7dGhpcy5ldmVudFRpbWVzPXpjKDApO3RoaXMuZXhwaXJhdGlvblRpbWVzPXpjKC0xKTt0aGlzLmVudGFuZ2xlZExhbmVzPXRoaXMuZmluaXNoZWRMYW5lcz10aGlzLm11dGFibGVSZWFkTGFuZXM9dGhpcy5leHBpcmVkTGFuZXM9dGhpcy5waW5nZWRMYW5lcz10aGlzLnN1c3BlbmRlZExhbmVzPXRoaXMucGVuZGluZ0xhbmVzPTA7dGhpcy5lbnRhbmdsZW1lbnRzPXpjKDApO3RoaXMuaWRlbnRpZmllclByZWZpeD1kO3RoaXMub25SZWNvdmVyYWJsZUVycm9yPWU7dGhpcy5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhPVxubnVsbH1mdW5jdGlvbiBjbChhLGIsYyxkLGUsZixnLGgsayl7YT1uZXcgYmwoYSxiLGMsaCxrKTsxPT09Yj8oYj0xLCEwPT09ZiYmKGJ8PTgpKTpiPTA7Zj1CZygzLG51bGwsbnVsbCxiKTthLmN1cnJlbnQ9ZjtmLnN0YXRlTm9kZT1hO2YubWVtb2l6ZWRTdGF0ZT17ZWxlbWVudDpkLGlzRGVoeWRyYXRlZDpjLGNhY2hlOm51bGwsdHJhbnNpdGlvbnM6bnVsbCxwZW5kaW5nU3VzcGVuc2VCb3VuZGFyaWVzOm51bGx9O2FoKGYpO3JldHVybiBhfWZ1bmN0aW9uIGRsKGEsYixjKXt2YXIgZD0zPGFyZ3VtZW50cy5sZW5ndGgmJnZvaWQgMCE9PWFyZ3VtZW50c1szXT9hcmd1bWVudHNbM106bnVsbDtyZXR1cm57JCR0eXBlb2Y6d2Esa2V5Om51bGw9PWQ/bnVsbDpcIlwiK2QsY2hpbGRyZW46YSxjb250YWluZXJJbmZvOmIsaW1wbGVtZW50YXRpb246Y319XG5mdW5jdGlvbiBlbChhKXtpZighYSlyZXR1cm4gVmY7YT1hLl9yZWFjdEludGVybmFsczthOntpZihWYihhKSE9PWF8fDEhPT1hLnRhZyl0aHJvdyBFcnJvcihwKDE3MCkpO3ZhciBiPWE7ZG97c3dpdGNoKGIudGFnKXtjYXNlIDM6Yj1iLnN0YXRlTm9kZS5jb250ZXh0O2JyZWFrIGE7Y2FzZSAxOmlmKFpmKGIudHlwZSkpe2I9Yi5zdGF0ZU5vZGUuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNZXJnZWRDaGlsZENvbnRleHQ7YnJlYWsgYX19Yj1iLnJldHVybn13aGlsZShudWxsIT09Yik7dGhyb3cgRXJyb3IocCgxNzEpKTt9aWYoMT09PWEudGFnKXt2YXIgYz1hLnR5cGU7aWYoWmYoYykpcmV0dXJuIGJnKGEsYyxiKX1yZXR1cm4gYn1cbmZ1bmN0aW9uIGZsKGEsYixjLGQsZSxmLGcsaCxrKXthPWNsKGMsZCwhMCxhLGUsZixnLGgsayk7YS5jb250ZXh0PWVsKG51bGwpO2M9YS5jdXJyZW50O2Q9TCgpO2U9bGgoYyk7Zj1jaChkLGUpO2YuY2FsbGJhY2s9dm9pZCAwIT09YiYmbnVsbCE9PWI/YjpudWxsO2RoKGMsZixlKTthLmN1cnJlbnQubGFuZXM9ZTtBYyhhLGUsZCk7RWsoYSxkKTtyZXR1cm4gYX1mdW5jdGlvbiBnbChhLGIsYyxkKXt2YXIgZT1iLmN1cnJlbnQsZj1MKCksZz1saChlKTtjPWVsKGMpO251bGw9PT1iLmNvbnRleHQ/Yi5jb250ZXh0PWM6Yi5wZW5kaW5nQ29udGV4dD1jO2I9Y2goZixnKTtiLnBheWxvYWQ9e2VsZW1lbnQ6YX07ZD12b2lkIDA9PT1kP251bGw6ZDtudWxsIT09ZCYmKGIuY2FsbGJhY2s9ZCk7YT1kaChlLGIsZyk7bnVsbCE9PWEmJihtaChhLGUsZyxmKSxlaChhLGUsZykpO3JldHVybiBnfVxuZnVuY3Rpb24gaGwoYSl7YT1hLmN1cnJlbnQ7aWYoIWEuY2hpbGQpcmV0dXJuIG51bGw7c3dpdGNoKGEuY2hpbGQudGFnKXtjYXNlIDU6cmV0dXJuIGEuY2hpbGQuc3RhdGVOb2RlO2RlZmF1bHQ6cmV0dXJuIGEuY2hpbGQuc3RhdGVOb2RlfX1mdW5jdGlvbiBpbChhLGIpe2E9YS5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1hJiZudWxsIT09YS5kZWh5ZHJhdGVkKXt2YXIgYz1hLnJldHJ5TGFuZTthLnJldHJ5TGFuZT0wIT09YyYmYzxiP2M6Yn19ZnVuY3Rpb24gamwoYSxiKXtpbChhLGIpOyhhPWEuYWx0ZXJuYXRlKSYmaWwoYSxiKX1mdW5jdGlvbiBrbCgpe3JldHVybiBudWxsfXZhciBsbD1cImZ1bmN0aW9uXCI9PT10eXBlb2YgcmVwb3J0RXJyb3I/cmVwb3J0RXJyb3I6ZnVuY3Rpb24oYSl7Y29uc29sZS5lcnJvcihhKX07ZnVuY3Rpb24gbWwoYSl7dGhpcy5faW50ZXJuYWxSb290PWF9XG5ubC5wcm90b3R5cGUucmVuZGVyPW1sLnByb3RvdHlwZS5yZW5kZXI9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5faW50ZXJuYWxSb290O2lmKG51bGw9PT1iKXRocm93IEVycm9yKHAoNDA5KSk7Z2woYSxiLG51bGwsbnVsbCl9O25sLnByb3RvdHlwZS51bm1vdW50PW1sLnByb3RvdHlwZS51bm1vdW50PWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5faW50ZXJuYWxSb290O2lmKG51bGwhPT1hKXt0aGlzLl9pbnRlcm5hbFJvb3Q9bnVsbDt2YXIgYj1hLmNvbnRhaW5lckluZm87U2soZnVuY3Rpb24oKXtnbChudWxsLGEsbnVsbCxudWxsKX0pO2JbdWZdPW51bGx9fTtmdW5jdGlvbiBubChhKXt0aGlzLl9pbnRlcm5hbFJvb3Q9YX1cbm5sLnByb3RvdHlwZS51bnN0YWJsZV9zY2hlZHVsZUh5ZHJhdGlvbj1mdW5jdGlvbihhKXtpZihhKXt2YXIgYj1IYygpO2E9e2Jsb2NrZWRPbjpudWxsLHRhcmdldDphLHByaW9yaXR5OmJ9O2Zvcih2YXIgYz0wO2M8UWMubGVuZ3RoJiYwIT09YiYmYjxRY1tjXS5wcmlvcml0eTtjKyspO1FjLnNwbGljZShjLDAsYSk7MD09PWMmJlZjKGEpfX07ZnVuY3Rpb24gb2woYSl7cmV0dXJuISghYXx8MSE9PWEubm9kZVR5cGUmJjkhPT1hLm5vZGVUeXBlJiYxMSE9PWEubm9kZVR5cGUpfWZ1bmN0aW9uIHBsKGEpe3JldHVybiEoIWF8fDEhPT1hLm5vZGVUeXBlJiY5IT09YS5ub2RlVHlwZSYmMTEhPT1hLm5vZGVUeXBlJiYoOCE9PWEubm9kZVR5cGV8fFwiIHJlYWN0LW1vdW50LXBvaW50LXVuc3RhYmxlIFwiIT09YS5ub2RlVmFsdWUpKX1mdW5jdGlvbiBxbCgpe31cbmZ1bmN0aW9uIHJsKGEsYixjLGQsZSl7aWYoZSl7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGQpe3ZhciBmPWQ7ZD1mdW5jdGlvbigpe3ZhciBhPWhsKGcpO2YuY2FsbChhKX19dmFyIGc9ZmwoYixkLGEsMCxudWxsLCExLCExLFwiXCIscWwpO2EuX3JlYWN0Um9vdENvbnRhaW5lcj1nO2FbdWZdPWcuY3VycmVudDtzZig4PT09YS5ub2RlVHlwZT9hLnBhcmVudE5vZGU6YSk7U2soKTtyZXR1cm4gZ31mb3IoO2U9YS5sYXN0Q2hpbGQ7KWEucmVtb3ZlQ2hpbGQoZSk7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGQpe3ZhciBoPWQ7ZD1mdW5jdGlvbigpe3ZhciBhPWhsKGspO2guY2FsbChhKX19dmFyIGs9Y2woYSwwLCExLG51bGwsbnVsbCwhMSwhMSxcIlwiLHFsKTthLl9yZWFjdFJvb3RDb250YWluZXI9azthW3VmXT1rLmN1cnJlbnQ7c2YoOD09PWEubm9kZVR5cGU/YS5wYXJlbnROb2RlOmEpO1NrKGZ1bmN0aW9uKCl7Z2woYixrLGMsZCl9KTtyZXR1cm4ga31cbmZ1bmN0aW9uIHNsKGEsYixjLGQsZSl7dmFyIGY9Yy5fcmVhY3RSb290Q29udGFpbmVyO2lmKGYpe3ZhciBnPWY7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGUpe3ZhciBoPWU7ZT1mdW5jdGlvbigpe3ZhciBhPWhsKGcpO2guY2FsbChhKX19Z2woYixnLGEsZSl9ZWxzZSBnPXJsKGMsYixhLGUsZCk7cmV0dXJuIGhsKGcpfUVjPWZ1bmN0aW9uKGEpe3N3aXRjaChhLnRhZyl7Y2FzZSAzOnZhciBiPWEuc3RhdGVOb2RlO2lmKGIuY3VycmVudC5tZW1vaXplZFN0YXRlLmlzRGVoeWRyYXRlZCl7dmFyIGM9dGMoYi5wZW5kaW5nTGFuZXMpOzAhPT1jJiYoQ2MoYixjfDEpLEVrKGIsQigpKSwwPT09KEsmNikmJihIaj1CKCkrNTAwLGpnKCkpKX1icmVhaztjYXNlIDEzOlNrKGZ1bmN0aW9uKCl7dmFyIGI9WmcoYSwxKTtpZihudWxsIT09Yil7dmFyIGM9TCgpO21oKGIsYSwxLGMpfX0pLGpsKGEsMSl9fTtcbkZjPWZ1bmN0aW9uKGEpe2lmKDEzPT09YS50YWcpe3ZhciBiPVpnKGEsMTM0MjE3NzI4KTtpZihudWxsIT09Yil7dmFyIGM9TCgpO21oKGIsYSwxMzQyMTc3MjgsYyl9amwoYSwxMzQyMTc3MjgpfX07R2M9ZnVuY3Rpb24oYSl7aWYoMTM9PT1hLnRhZyl7dmFyIGI9bGgoYSksYz1aZyhhLGIpO2lmKG51bGwhPT1jKXt2YXIgZD1MKCk7bWgoYyxhLGIsZCl9amwoYSxiKX19O0hjPWZ1bmN0aW9uKCl7cmV0dXJuIEN9O0ljPWZ1bmN0aW9uKGEsYil7dmFyIGM9Qzt0cnl7cmV0dXJuIEM9YSxiKCl9ZmluYWxseXtDPWN9fTtcbnliPWZ1bmN0aW9uKGEsYixjKXtzd2l0Y2goYil7Y2FzZSBcImlucHV0XCI6YmIoYSxjKTtiPWMubmFtZTtpZihcInJhZGlvXCI9PT1jLnR5cGUmJm51bGwhPWIpe2ZvcihjPWE7Yy5wYXJlbnROb2RlOyljPWMucGFyZW50Tm9kZTtjPWMucXVlcnlTZWxlY3RvckFsbChcImlucHV0W25hbWU9XCIrSlNPTi5zdHJpbmdpZnkoXCJcIitiKSsnXVt0eXBlPVwicmFkaW9cIl0nKTtmb3IoYj0wO2I8Yy5sZW5ndGg7YisrKXt2YXIgZD1jW2JdO2lmKGQhPT1hJiZkLmZvcm09PT1hLmZvcm0pe3ZhciBlPURiKGQpO2lmKCFlKXRocm93IEVycm9yKHAoOTApKTtXYShkKTtiYihkLGUpfX19YnJlYWs7Y2FzZSBcInRleHRhcmVhXCI6aWIoYSxjKTticmVhaztjYXNlIFwic2VsZWN0XCI6Yj1jLnZhbHVlLG51bGwhPWImJmZiKGEsISFjLm11bHRpcGxlLGIsITEpfX07R2I9Ums7SGI9U2s7XG52YXIgdGw9e3VzaW5nQ2xpZW50RW50cnlQb2ludDohMSxFdmVudHM6W0NiLHVlLERiLEViLEZiLFJrXX0sdWw9e2ZpbmRGaWJlckJ5SG9zdEluc3RhbmNlOldjLGJ1bmRsZVR5cGU6MCx2ZXJzaW9uOlwiMTguMi4wXCIscmVuZGVyZXJQYWNrYWdlTmFtZTpcInJlYWN0LWRvbVwifTtcbnZhciB2bD17YnVuZGxlVHlwZTp1bC5idW5kbGVUeXBlLHZlcnNpb246dWwudmVyc2lvbixyZW5kZXJlclBhY2thZ2VOYW1lOnVsLnJlbmRlcmVyUGFja2FnZU5hbWUscmVuZGVyZXJDb25maWc6dWwucmVuZGVyZXJDb25maWcsb3ZlcnJpZGVIb29rU3RhdGU6bnVsbCxvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGg6bnVsbCxvdmVycmlkZUhvb2tTdGF0ZVJlbmFtZVBhdGg6bnVsbCxvdmVycmlkZVByb3BzOm51bGwsb3ZlcnJpZGVQcm9wc0RlbGV0ZVBhdGg6bnVsbCxvdmVycmlkZVByb3BzUmVuYW1lUGF0aDpudWxsLHNldEVycm9ySGFuZGxlcjpudWxsLHNldFN1c3BlbnNlSGFuZGxlcjpudWxsLHNjaGVkdWxlVXBkYXRlOm51bGwsY3VycmVudERpc3BhdGNoZXJSZWY6dWEuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixmaW5kSG9zdEluc3RhbmNlQnlGaWJlcjpmdW5jdGlvbihhKXthPVpiKGEpO3JldHVybiBudWxsPT09YT9udWxsOmEuc3RhdGVOb2RlfSxmaW5kRmliZXJCeUhvc3RJbnN0YW5jZTp1bC5maW5kRmliZXJCeUhvc3RJbnN0YW5jZXx8XG5rbCxmaW5kSG9zdEluc3RhbmNlc0ZvclJlZnJlc2g6bnVsbCxzY2hlZHVsZVJlZnJlc2g6bnVsbCxzY2hlZHVsZVJvb3Q6bnVsbCxzZXRSZWZyZXNoSGFuZGxlcjpudWxsLGdldEN1cnJlbnRGaWJlcjpudWxsLHJlY29uY2lsZXJWZXJzaW9uOlwiMTguMi4wLW5leHQtOWUzYjc3MmI4LTIwMjIwNjA4XCJ9O2lmKFwidW5kZWZpbmVkXCIhPT10eXBlb2YgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fKXt2YXIgd2w9X19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fO2lmKCF3bC5pc0Rpc2FibGVkJiZ3bC5zdXBwb3J0c0ZpYmVyKXRyeXtrYz13bC5pbmplY3QodmwpLGxjPXdsfWNhdGNoKGEpe319ZXhwb3J0cy5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRD10bDtcbmV4cG9ydHMuY3JlYXRlUG9ydGFsPWZ1bmN0aW9uKGEsYil7dmFyIGM9Mjxhcmd1bWVudHMubGVuZ3RoJiZ2b2lkIDAhPT1hcmd1bWVudHNbMl0/YXJndW1lbnRzWzJdOm51bGw7aWYoIW9sKGIpKXRocm93IEVycm9yKHAoMjAwKSk7cmV0dXJuIGRsKGEsYixudWxsLGMpfTtleHBvcnRzLmNyZWF0ZVJvb3Q9ZnVuY3Rpb24oYSxiKXtpZighb2woYSkpdGhyb3cgRXJyb3IocCgyOTkpKTt2YXIgYz0hMSxkPVwiXCIsZT1sbDtudWxsIT09YiYmdm9pZCAwIT09YiYmKCEwPT09Yi51bnN0YWJsZV9zdHJpY3RNb2RlJiYoYz0hMCksdm9pZCAwIT09Yi5pZGVudGlmaWVyUHJlZml4JiYoZD1iLmlkZW50aWZpZXJQcmVmaXgpLHZvaWQgMCE9PWIub25SZWNvdmVyYWJsZUVycm9yJiYoZT1iLm9uUmVjb3ZlcmFibGVFcnJvcikpO2I9Y2woYSwxLCExLG51bGwsbnVsbCxjLCExLGQsZSk7YVt1Zl09Yi5jdXJyZW50O3NmKDg9PT1hLm5vZGVUeXBlP2EucGFyZW50Tm9kZTphKTtyZXR1cm4gbmV3IG1sKGIpfTtcbmV4cG9ydHMuZmluZERPTU5vZGU9ZnVuY3Rpb24oYSl7aWYobnVsbD09YSlyZXR1cm4gbnVsbDtpZigxPT09YS5ub2RlVHlwZSlyZXR1cm4gYTt2YXIgYj1hLl9yZWFjdEludGVybmFscztpZih2b2lkIDA9PT1iKXtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYS5yZW5kZXIpdGhyb3cgRXJyb3IocCgxODgpKTthPU9iamVjdC5rZXlzKGEpLmpvaW4oXCIsXCIpO3Rocm93IEVycm9yKHAoMjY4LGEpKTt9YT1aYihiKTthPW51bGw9PT1hP251bGw6YS5zdGF0ZU5vZGU7cmV0dXJuIGF9O2V4cG9ydHMuZmx1c2hTeW5jPWZ1bmN0aW9uKGEpe3JldHVybiBTayhhKX07ZXhwb3J0cy5oeWRyYXRlPWZ1bmN0aW9uKGEsYixjKXtpZighcGwoYikpdGhyb3cgRXJyb3IocCgyMDApKTtyZXR1cm4gc2wobnVsbCxhLGIsITAsYyl9O1xuZXhwb3J0cy5oeWRyYXRlUm9vdD1mdW5jdGlvbihhLGIsYyl7aWYoIW9sKGEpKXRocm93IEVycm9yKHAoNDA1KSk7dmFyIGQ9bnVsbCE9YyYmYy5oeWRyYXRlZFNvdXJjZXN8fG51bGwsZT0hMSxmPVwiXCIsZz1sbDtudWxsIT09YyYmdm9pZCAwIT09YyYmKCEwPT09Yy51bnN0YWJsZV9zdHJpY3RNb2RlJiYoZT0hMCksdm9pZCAwIT09Yy5pZGVudGlmaWVyUHJlZml4JiYoZj1jLmlkZW50aWZpZXJQcmVmaXgpLHZvaWQgMCE9PWMub25SZWNvdmVyYWJsZUVycm9yJiYoZz1jLm9uUmVjb3ZlcmFibGVFcnJvcikpO2I9ZmwoYixudWxsLGEsMSxudWxsIT1jP2M6bnVsbCxlLCExLGYsZyk7YVt1Zl09Yi5jdXJyZW50O3NmKGEpO2lmKGQpZm9yKGE9MDthPGQubGVuZ3RoO2ErKyljPWRbYV0sZT1jLl9nZXRWZXJzaW9uLGU9ZShjLl9zb3VyY2UpLG51bGw9PWIubXV0YWJsZVNvdXJjZUVhZ2VySHlkcmF0aW9uRGF0YT9iLm11dGFibGVTb3VyY2VFYWdlckh5ZHJhdGlvbkRhdGE9W2MsZV06Yi5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhLnB1c2goYyxcbmUpO3JldHVybiBuZXcgbmwoYil9O2V4cG9ydHMucmVuZGVyPWZ1bmN0aW9uKGEsYixjKXtpZighcGwoYikpdGhyb3cgRXJyb3IocCgyMDApKTtyZXR1cm4gc2wobnVsbCxhLGIsITEsYyl9O2V4cG9ydHMudW5tb3VudENvbXBvbmVudEF0Tm9kZT1mdW5jdGlvbihhKXtpZighcGwoYSkpdGhyb3cgRXJyb3IocCg0MCkpO3JldHVybiBhLl9yZWFjdFJvb3RDb250YWluZXI/KFNrKGZ1bmN0aW9uKCl7c2wobnVsbCxudWxsLGEsITEsZnVuY3Rpb24oKXthLl9yZWFjdFJvb3RDb250YWluZXI9bnVsbDthW3VmXT1udWxsfSl9KSwhMCk6ITF9O2V4cG9ydHMudW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXM9Ums7XG5leHBvcnRzLnVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyPWZ1bmN0aW9uKGEsYixjLGQpe2lmKCFwbChjKSl0aHJvdyBFcnJvcihwKDIwMCkpO2lmKG51bGw9PWF8fHZvaWQgMD09PWEuX3JlYWN0SW50ZXJuYWxzKXRocm93IEVycm9yKHAoMzgpKTtyZXR1cm4gc2woYSxiLGMsITEsZCl9O2V4cG9ydHMudmVyc2lvbj1cIjE4LjIuMC1uZXh0LTllM2I3NzJiOC0yMDIyMDYwOFwiO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///448\n')},745:(__unused_webpack_module,exports,__webpack_require__)=>{"use strict";eval("var __webpack_unused_export__;\n\n\nvar m = __webpack_require__(935);\nif (true) {\n exports.s = m.createRoot;\n __webpack_unused_export__ = m.hydrateRoot;\n} else { var i; }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ1LmpzIiwibWFwcGluZ3MiOiI7QUFBYTs7QUFFYixRQUFRLG1CQUFPLENBQUMsR0FBVztBQUMzQixJQUFJLElBQXFDO0FBQ3pDLEVBQUUsU0FBa0I7QUFDcEIsRUFBRSx5QkFBbUI7QUFDckIsRUFBRSxLQUFLLFVBa0JOIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9jbGllbnQuanM/MTFiMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBtID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBtLmNyZWF0ZVJvb3Q7XG4gIGV4cG9ydHMuaHlkcmF0ZVJvb3QgPSBtLmh5ZHJhdGVSb290O1xufSBlbHNlIHtcbiAgdmFyIGkgPSBtLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBmdW5jdGlvbihjLCBvKSB7XG4gICAgaS51c2luZ0NsaWVudEVudHJ5UG9pbnQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbS5jcmVhdGVSb290KGMsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbiAgZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGZ1bmN0aW9uKGMsIGgsIG8pIHtcbiAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtLmh5ZHJhdGVSb290KGMsIGgsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///745\n")},935:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nfunction checkDCE() {\n /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\n if (\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'\n ) {\n return;\n }\n if (false) {}\n try {\n // Verify that the code above has been dead code eliminated (DCE'd).\n __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);\n } catch (err) {\n // DevTools shouldn't crash React, no matter what.\n // We should still report in case we break this code.\n console.error(err);\n }\n}\n\nif (true) {\n // DCE check should happen before ReactDOM bundle executes so that\n // DevTools can report bad minification during injection.\n checkDCE();\n module.exports = __webpack_require__(448);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLEtBQXFDLEVBQUUsRUFTMUM7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJLElBQXFDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBLEVBQUUseUNBQTZEO0FBQy9ELEVBQUUsS0FBSyxFQUVOIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9pbmRleC5qcz84YmM4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gY2hlY2tEQ0UoKSB7XG4gIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbiAgaWYgKFxuICAgIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gPT09ICd1bmRlZmluZWQnIHx8XG4gICAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRSAhPT0gJ2Z1bmN0aW9uJ1xuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBUaGlzIGJyYW5jaCBpcyB1bnJlYWNoYWJsZSBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWRcbiAgICAvLyBpbiBwcm9kdWN0aW9uLCBidXQgdGhlIGNvbmRpdGlvbiBpcyB0cnVlIG9ubHkgaW4gZGV2ZWxvcG1lbnQuXG4gICAgLy8gVGhlcmVmb3JlIGlmIHRoZSBicmFuY2ggaXMgc3RpbGwgaGVyZSwgZGVhZCBjb2RlIGVsaW1pbmF0aW9uIHdhc24ndFxuICAgIC8vIHByb3Blcmx5IGFwcGxpZWQuXG4gICAgLy8gRG9uJ3QgY2hhbmdlIHRoZSBtZXNzYWdlLiBSZWFjdCBEZXZUb29scyByZWxpZXMgb24gaXQuIEFsc28gbWFrZSBzdXJlXG4gICAgLy8gdGhpcyBtZXNzYWdlIGRvZXNuJ3Qgb2NjdXIgZWxzZXdoZXJlIGluIHRoaXMgZnVuY3Rpb24sIG9yIGl0IHdpbGwgY2F1c2VcbiAgICAvLyBhIGZhbHNlIHBvc2l0aXZlLlxuICAgIHRocm93IG5ldyBFcnJvcignXl9eJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29kZSBhYm92ZSBoYXMgYmVlbiBkZWFkIGNvZGUgZWxpbWluYXRlZCAoRENFJ2QpLlxuICAgIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRShjaGVja0RDRSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIERldlRvb2xzIHNob3VsZG4ndCBjcmFzaCBSZWFjdCwgbm8gbWF0dGVyIHdoYXQuXG4gICAgLy8gV2Ugc2hvdWxkIHN0aWxsIHJlcG9ydCBpbiBjYXNlIHdlIGJyZWFrIHRoaXMgY29kZS5cbiAgICBjb25zb2xlLmVycm9yKGVycik7XG4gIH1cbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgLy8gRENFIGNoZWNrIHNob3VsZCBoYXBwZW4gYmVmb3JlIFJlYWN0RE9NIGJ1bmRsZSBleGVjdXRlcyBzbyB0aGF0XG4gIC8vIERldlRvb2xzIGNhbiByZXBvcnQgYmFkIG1pbmlmaWNhdGlvbiBkdXJpbmcgaW5qZWN0aW9uLlxuICBjaGVja0RDRSgpO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3JlYWN0LWRvbS5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20uZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///935\n")},408:(__unused_webpack_module,exports)=>{"use strict";eval('/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nvar l=Symbol.for("react.element"),n=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),q=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),t=Symbol.for("react.provider"),u=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),z=Symbol.iterator;function A(a){if(null===a||"object"!==typeof a)return null;a=z&&a[z]||a["@@iterator"];return"function"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}\nfunction N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return"object"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\\/+/g;function Q(a,b){return"object"===typeof a&&null!==a&&null!=a.key?escape(""+a.key):b.toString(36)}\nfunction R(a,b,e,d,c){var k=typeof a;if("undefined"===k||"boolean"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=""===d?"."+Q(h,0):d,I(c)?(e="",null!=a&&(e=a.replace(P,"$&/")+"/"),R(c,b,e,"",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?"":(""+c.key).replace(P,"$&/")+"/")+a)),b.push(c)),1;h=0;d=""===d?".":d+":";if(I(a))for(var g=0;g<a.length;g++){k=\na[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),"function"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if("object"===k)throw b=String(a),Error("Objects are not valid as a React child (found: "+("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}\nfunction S(a,b,e){if(null==a)return a;var d=[],c=0;R(a,d,"","",function(a){return b.call(e,a,c++)});return d}function T(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}\nvar U={current:null},V={transition:null},W={ReactCurrentDispatcher:U,ReactCurrentBatchConfig:V,ReactCurrentOwner:K};exports.Children={map:S,forEach:function(a,b,e){S(a,function(){b.apply(this,arguments)},e)},count:function(a){var b=0;S(a,function(){b++});return b},toArray:function(a){return S(a,function(a){return a})||[]},only:function(a){if(!O(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};exports.Component=E;exports.Fragment=p;\nexports.Profiler=r;exports.PureComponent=G;exports.StrictMode=q;exports.Suspense=w;exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=W;\nexports.cloneElement=function(a,b,e){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var d=C({},a.props),c=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=K.current);void 0!==b.key&&(c=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)J.call(b,f)&&!L.hasOwnProperty(f)&&(d[f]=void 0===b[f]&&void 0!==g?g[f]:b[f])}var f=arguments.length-2;if(1===f)d.children=e;else if(1<f){g=Array(f);\nfor(var m=0;m<f;m++)g[m]=arguments[m+2];d.children=g}return{$$typeof:l,type:a.type,key:c,ref:k,props:d,_owner:h}};exports.createContext=function(a){a={$$typeof:u,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:t,_context:a};return a.Consumer=a};exports.createElement=M;exports.createFactory=function(a){var b=M.bind(null,a);b.type=a;return b};exports.createRef=function(){return{current:null}};\nexports.forwardRef=function(a){return{$$typeof:v,render:a}};exports.isValidElement=O;exports.lazy=function(a){return{$$typeof:y,_payload:{_status:-1,_result:a},_init:T}};exports.memo=function(a,b){return{$$typeof:x,type:a,compare:void 0===b?null:b}};exports.startTransition=function(a){var b=V.transition;V.transition={};try{a()}finally{V.transition=b}};exports.unstable_act=function(){throw Error("act(...) is not supported in production builds of React.");};\nexports.useCallback=function(a,b){return U.current.useCallback(a,b)};exports.useContext=function(a){return U.current.useContext(a)};exports.useDebugValue=function(){};exports.useDeferredValue=function(a){return U.current.useDeferredValue(a)};exports.useEffect=function(a,b){return U.current.useEffect(a,b)};exports.useId=function(){return U.current.useId()};exports.useImperativeHandle=function(a,b,e){return U.current.useImperativeHandle(a,b,e)};\nexports.useInsertionEffect=function(a,b){return U.current.useInsertionEffect(a,b)};exports.useLayoutEffect=function(a,b){return U.current.useLayoutEffect(a,b)};exports.useMemo=function(a,b){return U.current.useMemo(a,b)};exports.useReducer=function(a,b,e){return U.current.useReducer(a,b,e)};exports.useRef=function(a){return U.current.useRef(a)};exports.useState=function(a){return U.current.useState(a)};exports.useSyncExternalStore=function(a,b,e){return U.current.useSyncExternalStore(a,b,e)};\nexports.useTransition=function(){return U.current.useTransition()};exports.version="18.2.0";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDA4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNhLHFXQUFxVyxjQUFjLDZDQUE2QywyQkFBMkI7QUFDeGMsT0FBTyxxQkFBcUIsU0FBUyxnQ0FBZ0MsaUNBQWlDLDhCQUE4QixzQkFBc0Isa0JBQWtCLGFBQWEsZUFBZSxZQUFZLGtCQUFrQjtBQUN0TyxtQ0FBbUMsNExBQTRMLG1EQUFtRCxvQ0FBb0MsdURBQXVELGNBQWMsd0JBQXdCLGtCQUFrQixhQUFhLGVBQWUsWUFBWSxrQkFBa0I7QUFDL2QsZ0JBQWdCLGlCQUFpQiwwQkFBMEIseURBQXlELGFBQWEsSUFBSTtBQUNySSxrQkFBa0IsVUFBVSxlQUFlLDRIQUE0SCx5QkFBeUIsc0JBQXNCLGFBQWEsdUJBQXVCLElBQUksd0JBQXdCLGFBQWEsNEVBQTRFLE9BQU87QUFDdFgsZ0JBQWdCLE9BQU8sc0VBQXNFLGNBQWMsb0RBQW9ELG1CQUFtQixPQUFPLG1CQUFtQix3Q0FBd0MsWUFBWSxFQUFFLGFBQWEsZ0JBQWdCO0FBQy9SLHNCQUFzQixlQUFlLHlDQUF5QyxTQUFTLGlCQUFpQixlQUFlLGlDQUFpQyxNQUFNLGlDQUFpQyxvQkFBb0IsbUhBQW1ILFNBQVMsMkdBQTJHLElBQUksbUJBQW1CLG9CQUFvQixXQUFXLEtBQUs7QUFDcmYsS0FBSyxlQUFlLGdCQUFnQix5REFBeUQsbUJBQW1CLHdDQUF3Qyx5SUFBeUksOEJBQThCLGtGQUFrRjtBQUNqWixrQkFBa0Isb0JBQW9CLGFBQWEsd0JBQXdCLHVCQUF1QixFQUFFLFNBQVMsY0FBYyxtQkFBbUIsZ0JBQWdCLE1BQU0sbUJBQW1CLHlEQUF5RCxhQUFhLHlEQUF5RCxFQUFFLDBDQUEwQywwQ0FBMEM7QUFDNVksT0FBTyxhQUFhLElBQUksZ0JBQWdCLElBQUksd0VBQXdFLGdCQUFnQixFQUFFLDhCQUE4QixlQUFlLHdCQUF3QixJQUFJLG1CQUFtQixRQUFRLGVBQWUsSUFBSSxFQUFFLFNBQVMscUJBQXFCLHVCQUF1QixTQUFTLE1BQU0sa0JBQWtCLDhGQUE4RixXQUFXLGlCQUFpQixHQUFHLGdCQUFnQjtBQUNsZSxnQkFBZ0IsR0FBRyxxQkFBcUIsR0FBRyxrQkFBa0IsR0FBRyxnQkFBZ0IsR0FBRywwREFBMEQ7QUFDN0ksb0JBQW9CLGlCQUFpQiw0SEFBNEgsVUFBVSxxQ0FBcUMsWUFBWSxzQ0FBc0MsNkJBQTZCLHlEQUF5RCx5RkFBeUYseUJBQXlCLHNCQUFzQixhQUFhO0FBQzdlLFlBQVksSUFBSSx3QkFBd0IsYUFBYSxPQUFPLHNEQUFzRCxxQkFBcUIsYUFBYSxHQUFHLDRIQUE0SCxZQUFZLHVCQUF1QixxQkFBcUIscUJBQXFCLEdBQUcscUJBQXFCLGFBQWEscUJBQXFCLFNBQVMsVUFBVSxpQkFBaUIsWUFBWSxPQUFPO0FBQ2pkLGtCQUFrQixhQUFhLE9BQU8sc0JBQXNCLHNCQUFzQixHQUFHLFlBQVksYUFBYSxPQUFPLHFCQUFxQixxQkFBcUIsV0FBVyxZQUFZLGVBQWUsT0FBTyw4Q0FBOEMsdUJBQXVCLGFBQWEsbUJBQW1CLGdCQUFnQixJQUFJLElBQUksUUFBUSxpQkFBaUIsb0JBQW9CLFlBQVk7QUFDbFksbUJBQW1CLGVBQWUsbUNBQW1DLGtCQUFrQixhQUFhLGdDQUFnQyxxQkFBcUIsY0FBYyx3QkFBd0IsYUFBYSxzQ0FBc0MsaUJBQWlCLGVBQWUsaUNBQWlDLGFBQWEsWUFBWSwwQkFBMEIsMkJBQTJCLGlCQUFpQjtBQUNsWiwwQkFBMEIsZUFBZSwwQ0FBMEMsdUJBQXVCLGVBQWUsdUNBQXVDLGVBQWUsZUFBZSwrQkFBK0Isa0JBQWtCLGlCQUFpQixvQ0FBb0MsY0FBYyxhQUFhLDRCQUE0QixnQkFBZ0IsYUFBYSw4QkFBOEIsNEJBQTRCLGlCQUFpQjtBQUNuYyxxQkFBcUIsWUFBWSxrQ0FBa0MsZUFBZSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yZWFjdC9janMvcmVhY3QucHJvZHVjdGlvbi5taW4uanM/YmUyNCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC5wcm9kdWN0aW9uLm1pbi5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7dmFyIGw9U3ltYm9sLmZvcihcInJlYWN0LmVsZW1lbnRcIiksbj1TeW1ib2wuZm9yKFwicmVhY3QucG9ydGFsXCIpLHA9U3ltYm9sLmZvcihcInJlYWN0LmZyYWdtZW50XCIpLHE9U3ltYm9sLmZvcihcInJlYWN0LnN0cmljdF9tb2RlXCIpLHI9U3ltYm9sLmZvcihcInJlYWN0LnByb2ZpbGVyXCIpLHQ9U3ltYm9sLmZvcihcInJlYWN0LnByb3ZpZGVyXCIpLHU9U3ltYm9sLmZvcihcInJlYWN0LmNvbnRleHRcIiksdj1TeW1ib2wuZm9yKFwicmVhY3QuZm9yd2FyZF9yZWZcIiksdz1TeW1ib2wuZm9yKFwicmVhY3Quc3VzcGVuc2VcIikseD1TeW1ib2wuZm9yKFwicmVhY3QubWVtb1wiKSx5PVN5bWJvbC5mb3IoXCJyZWFjdC5sYXp5XCIpLHo9U3ltYm9sLml0ZXJhdG9yO2Z1bmN0aW9uIEEoYSl7aWYobnVsbD09PWF8fFwib2JqZWN0XCIhPT10eXBlb2YgYSlyZXR1cm4gbnVsbDthPXomJmFbel18fGFbXCJAQGl0ZXJhdG9yXCJdO3JldHVyblwiZnVuY3Rpb25cIj09PXR5cGVvZiBhP2E6bnVsbH1cbnZhciBCPXtpc01vdW50ZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sZW5xdWV1ZUZvcmNlVXBkYXRlOmZ1bmN0aW9uKCl7fSxlbnF1ZXVlUmVwbGFjZVN0YXRlOmZ1bmN0aW9uKCl7fSxlbnF1ZXVlU2V0U3RhdGU6ZnVuY3Rpb24oKXt9fSxDPU9iamVjdC5hc3NpZ24sRD17fTtmdW5jdGlvbiBFKGEsYixlKXt0aGlzLnByb3BzPWE7dGhpcy5jb250ZXh0PWI7dGhpcy5yZWZzPUQ7dGhpcy51cGRhdGVyPWV8fEJ9RS5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudD17fTtcbkUucHJvdG90eXBlLnNldFN0YXRlPWZ1bmN0aW9uKGEsYil7aWYoXCJvYmplY3RcIiE9PXR5cGVvZiBhJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgYSYmbnVsbCE9YSl0aHJvdyBFcnJvcihcInNldFN0YXRlKC4uLik6IHRha2VzIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMgdG8gdXBkYXRlIG9yIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhbiBvYmplY3Qgb2Ygc3RhdGUgdmFyaWFibGVzLlwiKTt0aGlzLnVwZGF0ZXIuZW5xdWV1ZVNldFN0YXRlKHRoaXMsYSxiLFwic2V0U3RhdGVcIil9O0UucHJvdG90eXBlLmZvcmNlVXBkYXRlPWZ1bmN0aW9uKGEpe3RoaXMudXBkYXRlci5lbnF1ZXVlRm9yY2VVcGRhdGUodGhpcyxhLFwiZm9yY2VVcGRhdGVcIil9O2Z1bmN0aW9uIEYoKXt9Ri5wcm90b3R5cGU9RS5wcm90b3R5cGU7ZnVuY3Rpb24gRyhhLGIsZSl7dGhpcy5wcm9wcz1hO3RoaXMuY29udGV4dD1iO3RoaXMucmVmcz1EO3RoaXMudXBkYXRlcj1lfHxCfXZhciBIPUcucHJvdG90eXBlPW5ldyBGO1xuSC5jb25zdHJ1Y3Rvcj1HO0MoSCxFLnByb3RvdHlwZSk7SC5pc1B1cmVSZWFjdENvbXBvbmVudD0hMDt2YXIgST1BcnJheS5pc0FycmF5LEo9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxLPXtjdXJyZW50Om51bGx9LEw9e2tleTohMCxyZWY6ITAsX19zZWxmOiEwLF9fc291cmNlOiEwfTtcbmZ1bmN0aW9uIE0oYSxiLGUpe3ZhciBkLGM9e30saz1udWxsLGg9bnVsbDtpZihudWxsIT1iKWZvcihkIGluIHZvaWQgMCE9PWIucmVmJiYoaD1iLnJlZiksdm9pZCAwIT09Yi5rZXkmJihrPVwiXCIrYi5rZXkpLGIpSi5jYWxsKGIsZCkmJiFMLmhhc093blByb3BlcnR5KGQpJiYoY1tkXT1iW2RdKTt2YXIgZz1hcmd1bWVudHMubGVuZ3RoLTI7aWYoMT09PWcpYy5jaGlsZHJlbj1lO2Vsc2UgaWYoMTxnKXtmb3IodmFyIGY9QXJyYXkoZyksbT0wO208ZzttKyspZlttXT1hcmd1bWVudHNbbSsyXTtjLmNoaWxkcmVuPWZ9aWYoYSYmYS5kZWZhdWx0UHJvcHMpZm9yKGQgaW4gZz1hLmRlZmF1bHRQcm9wcyxnKXZvaWQgMD09PWNbZF0mJihjW2RdPWdbZF0pO3JldHVybnskJHR5cGVvZjpsLHR5cGU6YSxrZXk6ayxyZWY6aCxwcm9wczpjLF9vd25lcjpLLmN1cnJlbnR9fVxuZnVuY3Rpb24gTihhLGIpe3JldHVybnskJHR5cGVvZjpsLHR5cGU6YS50eXBlLGtleTpiLHJlZjphLnJlZixwcm9wczphLnByb3BzLF9vd25lcjphLl9vd25lcn19ZnVuY3Rpb24gTyhhKXtyZXR1cm5cIm9iamVjdFwiPT09dHlwZW9mIGEmJm51bGwhPT1hJiZhLiQkdHlwZW9mPT09bH1mdW5jdGlvbiBlc2NhcGUoYSl7dmFyIGI9e1wiPVwiOlwiPTBcIixcIjpcIjpcIj0yXCJ9O3JldHVyblwiJFwiK2EucmVwbGFjZSgvWz06XS9nLGZ1bmN0aW9uKGEpe3JldHVybiBiW2FdfSl9dmFyIFA9L1xcLysvZztmdW5jdGlvbiBRKGEsYil7cmV0dXJuXCJvYmplY3RcIj09PXR5cGVvZiBhJiZudWxsIT09YSYmbnVsbCE9YS5rZXk/ZXNjYXBlKFwiXCIrYS5rZXkpOmIudG9TdHJpbmcoMzYpfVxuZnVuY3Rpb24gUihhLGIsZSxkLGMpe3ZhciBrPXR5cGVvZiBhO2lmKFwidW5kZWZpbmVkXCI9PT1rfHxcImJvb2xlYW5cIj09PWspYT1udWxsO3ZhciBoPSExO2lmKG51bGw9PT1hKWg9ITA7ZWxzZSBzd2l0Y2goayl7Y2FzZSBcInN0cmluZ1wiOmNhc2UgXCJudW1iZXJcIjpoPSEwO2JyZWFrO2Nhc2UgXCJvYmplY3RcIjpzd2l0Y2goYS4kJHR5cGVvZil7Y2FzZSBsOmNhc2UgbjpoPSEwfX1pZihoKXJldHVybiBoPWEsYz1jKGgpLGE9XCJcIj09PWQ/XCIuXCIrUShoLDApOmQsSShjKT8oZT1cIlwiLG51bGwhPWEmJihlPWEucmVwbGFjZShQLFwiJCYvXCIpK1wiL1wiKSxSKGMsYixlLFwiXCIsZnVuY3Rpb24oYSl7cmV0dXJuIGF9KSk6bnVsbCE9YyYmKE8oYykmJihjPU4oYyxlKyghYy5rZXl8fGgmJmgua2V5PT09Yy5rZXk/XCJcIjooXCJcIitjLmtleSkucmVwbGFjZShQLFwiJCYvXCIpK1wiL1wiKSthKSksYi5wdXNoKGMpKSwxO2g9MDtkPVwiXCI9PT1kP1wiLlwiOmQrXCI6XCI7aWYoSShhKSlmb3IodmFyIGc9MDtnPGEubGVuZ3RoO2crKyl7az1cbmFbZ107dmFyIGY9ZCtRKGssZyk7aCs9UihrLGIsZSxmLGMpfWVsc2UgaWYoZj1BKGEpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBmKWZvcihhPWYuY2FsbChhKSxnPTA7IShrPWEubmV4dCgpKS5kb25lOylrPWsudmFsdWUsZj1kK1EoayxnKyspLGgrPVIoayxiLGUsZixjKTtlbHNlIGlmKFwib2JqZWN0XCI9PT1rKXRocm93IGI9U3RyaW5nKGEpLEVycm9yKFwiT2JqZWN0cyBhcmUgbm90IHZhbGlkIGFzIGEgUmVhY3QgY2hpbGQgKGZvdW5kOiBcIisoXCJbb2JqZWN0IE9iamVjdF1cIj09PWI/XCJvYmplY3Qgd2l0aCBrZXlzIHtcIitPYmplY3Qua2V5cyhhKS5qb2luKFwiLCBcIikrXCJ9XCI6YikrXCIpLiBJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiwgdXNlIGFuIGFycmF5IGluc3RlYWQuXCIpO3JldHVybiBofVxuZnVuY3Rpb24gUyhhLGIsZSl7aWYobnVsbD09YSlyZXR1cm4gYTt2YXIgZD1bXSxjPTA7UihhLGQsXCJcIixcIlwiLGZ1bmN0aW9uKGEpe3JldHVybiBiLmNhbGwoZSxhLGMrKyl9KTtyZXR1cm4gZH1mdW5jdGlvbiBUKGEpe2lmKC0xPT09YS5fc3RhdHVzKXt2YXIgYj1hLl9yZXN1bHQ7Yj1iKCk7Yi50aGVuKGZ1bmN0aW9uKGIpe2lmKDA9PT1hLl9zdGF0dXN8fC0xPT09YS5fc3RhdHVzKWEuX3N0YXR1cz0xLGEuX3Jlc3VsdD1ifSxmdW5jdGlvbihiKXtpZigwPT09YS5fc3RhdHVzfHwtMT09PWEuX3N0YXR1cylhLl9zdGF0dXM9MixhLl9yZXN1bHQ9Yn0pOy0xPT09YS5fc3RhdHVzJiYoYS5fc3RhdHVzPTAsYS5fcmVzdWx0PWIpfWlmKDE9PT1hLl9zdGF0dXMpcmV0dXJuIGEuX3Jlc3VsdC5kZWZhdWx0O3Rocm93IGEuX3Jlc3VsdDt9XG52YXIgVT17Y3VycmVudDpudWxsfSxWPXt0cmFuc2l0aW9uOm51bGx9LFc9e1JlYWN0Q3VycmVudERpc3BhdGNoZXI6VSxSZWFjdEN1cnJlbnRCYXRjaENvbmZpZzpWLFJlYWN0Q3VycmVudE93bmVyOkt9O2V4cG9ydHMuQ2hpbGRyZW49e21hcDpTLGZvckVhY2g6ZnVuY3Rpb24oYSxiLGUpe1MoYSxmdW5jdGlvbigpe2IuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxlKX0sY291bnQ6ZnVuY3Rpb24oYSl7dmFyIGI9MDtTKGEsZnVuY3Rpb24oKXtiKyt9KTtyZXR1cm4gYn0sdG9BcnJheTpmdW5jdGlvbihhKXtyZXR1cm4gUyhhLGZ1bmN0aW9uKGEpe3JldHVybiBhfSl8fFtdfSxvbmx5OmZ1bmN0aW9uKGEpe2lmKCFPKGEpKXRocm93IEVycm9yKFwiUmVhY3QuQ2hpbGRyZW4ub25seSBleHBlY3RlZCB0byByZWNlaXZlIGEgc2luZ2xlIFJlYWN0IGVsZW1lbnQgY2hpbGQuXCIpO3JldHVybiBhfX07ZXhwb3J0cy5Db21wb25lbnQ9RTtleHBvcnRzLkZyYWdtZW50PXA7XG5leHBvcnRzLlByb2ZpbGVyPXI7ZXhwb3J0cy5QdXJlQ29tcG9uZW50PUc7ZXhwb3J0cy5TdHJpY3RNb2RlPXE7ZXhwb3J0cy5TdXNwZW5zZT13O2V4cG9ydHMuX19TRUNSRVRfSU5URVJOQUxTX0RPX05PVF9VU0VfT1JfWU9VX1dJTExfQkVfRklSRUQ9VztcbmV4cG9ydHMuY2xvbmVFbGVtZW50PWZ1bmN0aW9uKGEsYixlKXtpZihudWxsPT09YXx8dm9pZCAwPT09YSl0aHJvdyBFcnJvcihcIlJlYWN0LmNsb25lRWxlbWVudCguLi4pOiBUaGUgYXJndW1lbnQgbXVzdCBiZSBhIFJlYWN0IGVsZW1lbnQsIGJ1dCB5b3UgcGFzc2VkIFwiK2ErXCIuXCIpO3ZhciBkPUMoe30sYS5wcm9wcyksYz1hLmtleSxrPWEucmVmLGg9YS5fb3duZXI7aWYobnVsbCE9Yil7dm9pZCAwIT09Yi5yZWYmJihrPWIucmVmLGg9Sy5jdXJyZW50KTt2b2lkIDAhPT1iLmtleSYmKGM9XCJcIitiLmtleSk7aWYoYS50eXBlJiZhLnR5cGUuZGVmYXVsdFByb3BzKXZhciBnPWEudHlwZS5kZWZhdWx0UHJvcHM7Zm9yKGYgaW4gYilKLmNhbGwoYixmKSYmIUwuaGFzT3duUHJvcGVydHkoZikmJihkW2ZdPXZvaWQgMD09PWJbZl0mJnZvaWQgMCE9PWc/Z1tmXTpiW2ZdKX12YXIgZj1hcmd1bWVudHMubGVuZ3RoLTI7aWYoMT09PWYpZC5jaGlsZHJlbj1lO2Vsc2UgaWYoMTxmKXtnPUFycmF5KGYpO1xuZm9yKHZhciBtPTA7bTxmO20rKylnW21dPWFyZ3VtZW50c1ttKzJdO2QuY2hpbGRyZW49Z31yZXR1cm57JCR0eXBlb2Y6bCx0eXBlOmEudHlwZSxrZXk6YyxyZWY6ayxwcm9wczpkLF9vd25lcjpofX07ZXhwb3J0cy5jcmVhdGVDb250ZXh0PWZ1bmN0aW9uKGEpe2E9eyQkdHlwZW9mOnUsX2N1cnJlbnRWYWx1ZTphLF9jdXJyZW50VmFsdWUyOmEsX3RocmVhZENvdW50OjAsUHJvdmlkZXI6bnVsbCxDb25zdW1lcjpudWxsLF9kZWZhdWx0VmFsdWU6bnVsbCxfZ2xvYmFsTmFtZTpudWxsfTthLlByb3ZpZGVyPXskJHR5cGVvZjp0LF9jb250ZXh0OmF9O3JldHVybiBhLkNvbnN1bWVyPWF9O2V4cG9ydHMuY3JlYXRlRWxlbWVudD1NO2V4cG9ydHMuY3JlYXRlRmFjdG9yeT1mdW5jdGlvbihhKXt2YXIgYj1NLmJpbmQobnVsbCxhKTtiLnR5cGU9YTtyZXR1cm4gYn07ZXhwb3J0cy5jcmVhdGVSZWY9ZnVuY3Rpb24oKXtyZXR1cm57Y3VycmVudDpudWxsfX07XG5leHBvcnRzLmZvcndhcmRSZWY9ZnVuY3Rpb24oYSl7cmV0dXJueyQkdHlwZW9mOnYscmVuZGVyOmF9fTtleHBvcnRzLmlzVmFsaWRFbGVtZW50PU87ZXhwb3J0cy5sYXp5PWZ1bmN0aW9uKGEpe3JldHVybnskJHR5cGVvZjp5LF9wYXlsb2FkOntfc3RhdHVzOi0xLF9yZXN1bHQ6YX0sX2luaXQ6VH19O2V4cG9ydHMubWVtbz1mdW5jdGlvbihhLGIpe3JldHVybnskJHR5cGVvZjp4LHR5cGU6YSxjb21wYXJlOnZvaWQgMD09PWI/bnVsbDpifX07ZXhwb3J0cy5zdGFydFRyYW5zaXRpb249ZnVuY3Rpb24oYSl7dmFyIGI9Vi50cmFuc2l0aW9uO1YudHJhbnNpdGlvbj17fTt0cnl7YSgpfWZpbmFsbHl7Vi50cmFuc2l0aW9uPWJ9fTtleHBvcnRzLnVuc3RhYmxlX2FjdD1mdW5jdGlvbigpe3Rocm93IEVycm9yKFwiYWN0KC4uLikgaXMgbm90IHN1cHBvcnRlZCBpbiBwcm9kdWN0aW9uIGJ1aWxkcyBvZiBSZWFjdC5cIik7fTtcbmV4cG9ydHMudXNlQ2FsbGJhY2s9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVS5jdXJyZW50LnVzZUNhbGxiYWNrKGEsYil9O2V4cG9ydHMudXNlQ29udGV4dD1mdW5jdGlvbihhKXtyZXR1cm4gVS5jdXJyZW50LnVzZUNvbnRleHQoYSl9O2V4cG9ydHMudXNlRGVidWdWYWx1ZT1mdW5jdGlvbigpe307ZXhwb3J0cy51c2VEZWZlcnJlZFZhbHVlPWZ1bmN0aW9uKGEpe3JldHVybiBVLmN1cnJlbnQudXNlRGVmZXJyZWRWYWx1ZShhKX07ZXhwb3J0cy51c2VFZmZlY3Q9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVS5jdXJyZW50LnVzZUVmZmVjdChhLGIpfTtleHBvcnRzLnVzZUlkPWZ1bmN0aW9uKCl7cmV0dXJuIFUuY3VycmVudC51c2VJZCgpfTtleHBvcnRzLnVzZUltcGVyYXRpdmVIYW5kbGU9ZnVuY3Rpb24oYSxiLGUpe3JldHVybiBVLmN1cnJlbnQudXNlSW1wZXJhdGl2ZUhhbmRsZShhLGIsZSl9O1xuZXhwb3J0cy51c2VJbnNlcnRpb25FZmZlY3Q9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVS5jdXJyZW50LnVzZUluc2VydGlvbkVmZmVjdChhLGIpfTtleHBvcnRzLnVzZUxheW91dEVmZmVjdD1mdW5jdGlvbihhLGIpe3JldHVybiBVLmN1cnJlbnQudXNlTGF5b3V0RWZmZWN0KGEsYil9O2V4cG9ydHMudXNlTWVtbz1mdW5jdGlvbihhLGIpe3JldHVybiBVLmN1cnJlbnQudXNlTWVtbyhhLGIpfTtleHBvcnRzLnVzZVJlZHVjZXI9ZnVuY3Rpb24oYSxiLGUpe3JldHVybiBVLmN1cnJlbnQudXNlUmVkdWNlcihhLGIsZSl9O2V4cG9ydHMudXNlUmVmPWZ1bmN0aW9uKGEpe3JldHVybiBVLmN1cnJlbnQudXNlUmVmKGEpfTtleHBvcnRzLnVzZVN0YXRlPWZ1bmN0aW9uKGEpe3JldHVybiBVLmN1cnJlbnQudXNlU3RhdGUoYSl9O2V4cG9ydHMudXNlU3luY0V4dGVybmFsU3RvcmU9ZnVuY3Rpb24oYSxiLGUpe3JldHVybiBVLmN1cnJlbnQudXNlU3luY0V4dGVybmFsU3RvcmUoYSxiLGUpfTtcbmV4cG9ydHMudXNlVHJhbnNpdGlvbj1mdW5jdGlvbigpe3JldHVybiBVLmN1cnJlbnQudXNlVHJhbnNpdGlvbigpfTtleHBvcnRzLnZlcnNpb249XCIxOC4yLjBcIjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///408\n')},294:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(408);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLElBQUksSUFBcUM7QUFDekMsRUFBRSx5Q0FBeUQ7QUFDM0QsRUFBRSxLQUFLLEVBRU4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVhY3QvaW5kZXguanM/YWI1YiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///294\n")},53:(__unused_webpack_module,exports)=>{"use strict";eval('/**\n * @license React\n * scheduler.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction f(a,b){var c=a.length;a.push(b);a:for(;0<c;){var d=c-1>>>1,e=a[d];if(0<g(e,b))a[d]=b,a[c]=e,c=d;else break a}}function h(a){return 0===a.length?null:a[0]}function k(a){if(0===a.length)return null;var b=a[0],c=a.pop();if(c!==b){a[0]=c;a:for(var d=0,e=a.length,w=e>>>1;d<w;){var m=2*(d+1)-1,C=a[m],n=m+1,x=a[n];if(0>g(C,c))n<e&&0>g(x,C)?(a[d]=x,a[n]=c,d=n):(a[d]=C,a[m]=c,d=m);else if(n<e&&0>g(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b}\nfunction g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if("object"===typeof performance&&"function"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D="function"===typeof setTimeout?setTimeout:null,E="function"===typeof clearTimeout?clearTimeout:null,F="undefined"!==typeof setImmediate?setImmediate:null;\n"undefined"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}}\nfunction J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if("function"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();"function"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1;\nfunction M(){return exports.unstable_now()-Q<P?!1:!0}function R(){if(null!==O){var a=exports.unstable_now();Q=a;var b=!0;try{b=O(!0,a)}finally{b?S():(N=!1,O=null)}}else N=!1}var S;if("function"===typeof F)S=function(){F(R)};else if("undefined"!==typeof MessageChannel){var T=new MessageChannel,U=T.port2;T.port1.onmessage=R;S=function(){U.postMessage(null)}}else S=function(){D(R,0)};function I(a){O=a;N||(N=!0,S())}function K(a,b){L=D(function(){a(exports.unstable_now())},b)}\nexports.unstable_IdlePriority=5;exports.unstable_ImmediatePriority=1;exports.unstable_LowPriority=4;exports.unstable_NormalPriority=3;exports.unstable_Profiling=null;exports.unstable_UserBlockingPriority=2;exports.unstable_cancelCallback=function(a){a.callback=null};exports.unstable_continueExecution=function(){A||z||(A=!0,I(J))};\nexports.unstable_forceFrameRate=function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):P=0<a?Math.floor(1E3/a):5};exports.unstable_getCurrentPriorityLevel=function(){return y};exports.unstable_getFirstCallbackNode=function(){return h(r)};exports.unstable_next=function(a){switch(y){case 1:case 2:case 3:var b=3;break;default:b=y}var c=y;y=b;try{return a()}finally{y=c}};exports.unstable_pauseExecution=function(){};\nexports.unstable_requestPaint=function(){};exports.unstable_runWithPriority=function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=y;y=a;try{return b()}finally{y=c}};\nexports.unstable_scheduleCallback=function(a,b,c){var d=exports.unstable_now();"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0<c?d+c:d):c=d;switch(a){case 1:var e=-1;break;case 2:e=250;break;case 5:e=1073741823;break;case 4:e=1E4;break;default:e=5E3}e=c+e;a={id:u++,callback:b,priorityLevel:a,startTime:c,expirationTime:e,sortIndex:-1};c>d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2EsZ0JBQWdCLGVBQWUsVUFBVSxPQUFPLElBQUksRUFBRSxxQkFBcUIsOEJBQThCLGNBQWMsY0FBYyw4QkFBOEIsY0FBYyw0QkFBNEIscUJBQXFCLFVBQVUsT0FBTyxpQ0FBaUMsSUFBSSxFQUFFLG9DQUFvQyxrRUFBa0Usd0NBQXdDLGNBQWM7QUFDbmMsZ0JBQWdCLDhCQUE4Qix5QkFBeUIsdUVBQXVFLGtCQUFrQixvQkFBb0IsWUFBWSxnQkFBZ0IsS0FBSyxxQkFBcUIsb0JBQW9CLFlBQVksa0JBQWtCO0FBQzVSLDRLQUE0SyxjQUFjLGVBQWUsU0FBUyxFQUFFLDBCQUEwQixnRUFBZ0UsV0FBVyxRQUFRLGNBQWMsS0FBSyxLQUFLLCtCQUErQixLQUFLLFdBQVc7QUFDeFksZ0JBQWdCLEtBQUssb0JBQW9CLEtBQUssUUFBUSxJQUFJLEtBQUssV0FBVywyQ0FBMkMsRUFBRSxpQkFBaUIsMEJBQTBCLGdCQUFnQixrQkFBa0IsNkJBQTZCLHlCQUF5QixrREFBa0QsS0FBSyxVQUFVLE9BQU8scUJBQXFCLEtBQUssV0FBVyw2QkFBNkIsS0FBSyxTQUFTLFFBQVEsaUJBQWlCO0FBQzNhLGFBQWEsd0NBQXdDLGFBQWEsYUFBYSw2QkFBNkIsSUFBSSxTQUFTLElBQUksVUFBVSxRQUFRLHFCQUFxQixVQUFVLE1BQU0sc0NBQXNDLE1BQU0sNkNBQTZDLG1DQUFtQyxvQkFBb0IsYUFBYSxxQkFBcUIsa0JBQWtCLFFBQVEsY0FBYyxJQUFJLGNBQWMsZ0JBQWdCLGVBQWUsMEJBQTBCO0FBQ3pkLDZCQUE2QixHQUFHLGtDQUFrQyxHQUFHLDRCQUE0QixHQUFHLCtCQUErQixHQUFHLDBCQUEwQixNQUFNLHFDQUFxQyxHQUFHLCtCQUErQixhQUFhLGlCQUFpQixrQ0FBa0MsWUFBWTtBQUN6VCwrQkFBK0IsYUFBYSx1S0FBdUssd0NBQXdDLFlBQVksVUFBVSxxQ0FBcUMsWUFBWSxhQUFhLHFCQUFxQixhQUFhLFVBQVUsNkJBQTZCLE1BQU0sWUFBWSxRQUFRLElBQUksSUFBSSxXQUFXLFFBQVEsTUFBTSwrQkFBK0I7QUFDbGYsNkJBQTZCLGNBQWMsZ0NBQWdDLGVBQWUsVUFBVSx5Q0FBeUMsWUFBWSxRQUFRLElBQUksSUFBSSxXQUFXLFFBQVE7QUFDNUwsaUNBQWlDLGlCQUFpQiw2QkFBNkIsK0VBQStFLFVBQVUsZ0JBQWdCLE1BQU0sYUFBYSxNQUFNLG9CQUFvQixNQUFNLGFBQWEsTUFBTSxjQUFjLE1BQU0sR0FBRyw2RUFBNkUseUhBQXlIO0FBQzNkLDRCQUE0QixHQUFHLDZCQUE2QixhQUFhLFFBQVEsa0JBQWtCLFFBQVEsSUFBSSxJQUFJLCtCQUErQixRQUFRIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3NjaGVkdWxlci9janMvc2NoZWR1bGVyLnByb2R1Y3Rpb24ubWluLmpzP2ZiMDciXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZSBSZWFjdFxuICogc2NoZWR1bGVyLnByb2R1Y3Rpb24ubWluLmpzXG4gKlxuICogQ29weXJpZ2h0IChjKSBGYWNlYm9vaywgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cbid1c2Ugc3RyaWN0JztmdW5jdGlvbiBmKGEsYil7dmFyIGM9YS5sZW5ndGg7YS5wdXNoKGIpO2E6Zm9yKDswPGM7KXt2YXIgZD1jLTE+Pj4xLGU9YVtkXTtpZigwPGcoZSxiKSlhW2RdPWIsYVtjXT1lLGM9ZDtlbHNlIGJyZWFrIGF9fWZ1bmN0aW9uIGgoYSl7cmV0dXJuIDA9PT1hLmxlbmd0aD9udWxsOmFbMF19ZnVuY3Rpb24gayhhKXtpZigwPT09YS5sZW5ndGgpcmV0dXJuIG51bGw7dmFyIGI9YVswXSxjPWEucG9wKCk7aWYoYyE9PWIpe2FbMF09YzthOmZvcih2YXIgZD0wLGU9YS5sZW5ndGgsdz1lPj4+MTtkPHc7KXt2YXIgbT0yKihkKzEpLTEsQz1hW21dLG49bSsxLHg9YVtuXTtpZigwPmcoQyxjKSluPGUmJjA+Zyh4LEMpPyhhW2RdPXgsYVtuXT1jLGQ9bik6KGFbZF09QyxhW21dPWMsZD1tKTtlbHNlIGlmKG48ZSYmMD5nKHgsYykpYVtkXT14LGFbbl09YyxkPW47ZWxzZSBicmVhayBhfX1yZXR1cm4gYn1cbmZ1bmN0aW9uIGcoYSxiKXt2YXIgYz1hLnNvcnRJbmRleC1iLnNvcnRJbmRleDtyZXR1cm4gMCE9PWM/YzphLmlkLWIuaWR9aWYoXCJvYmplY3RcIj09PXR5cGVvZiBwZXJmb3JtYW5jZSYmXCJmdW5jdGlvblwiPT09dHlwZW9mIHBlcmZvcm1hbmNlLm5vdyl7dmFyIGw9cGVyZm9ybWFuY2U7ZXhwb3J0cy51bnN0YWJsZV9ub3c9ZnVuY3Rpb24oKXtyZXR1cm4gbC5ub3coKX19ZWxzZXt2YXIgcD1EYXRlLHE9cC5ub3coKTtleHBvcnRzLnVuc3RhYmxlX25vdz1mdW5jdGlvbigpe3JldHVybiBwLm5vdygpLXF9fXZhciByPVtdLHQ9W10sdT0xLHY9bnVsbCx5PTMsej0hMSxBPSExLEI9ITEsRD1cImZ1bmN0aW9uXCI9PT10eXBlb2Ygc2V0VGltZW91dD9zZXRUaW1lb3V0Om51bGwsRT1cImZ1bmN0aW9uXCI9PT10eXBlb2YgY2xlYXJUaW1lb3V0P2NsZWFyVGltZW91dDpudWxsLEY9XCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBzZXRJbW1lZGlhdGU/c2V0SW1tZWRpYXRlOm51bGw7XG5cInVuZGVmaW5lZFwiIT09dHlwZW9mIG5hdmlnYXRvciYmdm9pZCAwIT09bmF2aWdhdG9yLnNjaGVkdWxpbmcmJnZvaWQgMCE9PW5hdmlnYXRvci5zY2hlZHVsaW5nLmlzSW5wdXRQZW5kaW5nJiZuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZy5iaW5kKG5hdmlnYXRvci5zY2hlZHVsaW5nKTtmdW5jdGlvbiBHKGEpe2Zvcih2YXIgYj1oKHQpO251bGwhPT1iOyl7aWYobnVsbD09PWIuY2FsbGJhY2spayh0KTtlbHNlIGlmKGIuc3RhcnRUaW1lPD1hKWsodCksYi5zb3J0SW5kZXg9Yi5leHBpcmF0aW9uVGltZSxmKHIsYik7ZWxzZSBicmVhaztiPWgodCl9fWZ1bmN0aW9uIEgoYSl7Qj0hMTtHKGEpO2lmKCFBKWlmKG51bGwhPT1oKHIpKUE9ITAsSShKKTtlbHNle3ZhciBiPWgodCk7bnVsbCE9PWImJksoSCxiLnN0YXJ0VGltZS1hKX19XG5mdW5jdGlvbiBKKGEsYil7QT0hMTtCJiYoQj0hMSxFKEwpLEw9LTEpO3o9ITA7dmFyIGM9eTt0cnl7RyhiKTtmb3Iodj1oKHIpO251bGwhPT12JiYoISh2LmV4cGlyYXRpb25UaW1lPmIpfHxhJiYhTSgpKTspe3ZhciBkPXYuY2FsbGJhY2s7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGQpe3YuY2FsbGJhY2s9bnVsbDt5PXYucHJpb3JpdHlMZXZlbDt2YXIgZT1kKHYuZXhwaXJhdGlvblRpbWU8PWIpO2I9ZXhwb3J0cy51bnN0YWJsZV9ub3coKTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgZT92LmNhbGxiYWNrPWU6dj09PWgocikmJmsocik7RyhiKX1lbHNlIGsocik7dj1oKHIpfWlmKG51bGwhPT12KXZhciB3PSEwO2Vsc2V7dmFyIG09aCh0KTtudWxsIT09bSYmSyhILG0uc3RhcnRUaW1lLWIpO3c9ITF9cmV0dXJuIHd9ZmluYWxseXt2PW51bGwseT1jLHo9ITF9fXZhciBOPSExLE89bnVsbCxMPS0xLFA9NSxRPS0xO1xuZnVuY3Rpb24gTSgpe3JldHVybiBleHBvcnRzLnVuc3RhYmxlX25vdygpLVE8UD8hMTohMH1mdW5jdGlvbiBSKCl7aWYobnVsbCE9PU8pe3ZhciBhPWV4cG9ydHMudW5zdGFibGVfbm93KCk7UT1hO3ZhciBiPSEwO3RyeXtiPU8oITAsYSl9ZmluYWxseXtiP1MoKTooTj0hMSxPPW51bGwpfX1lbHNlIE49ITF9dmFyIFM7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIEYpUz1mdW5jdGlvbigpe0YoUil9O2Vsc2UgaWYoXCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBNZXNzYWdlQ2hhbm5lbCl7dmFyIFQ9bmV3IE1lc3NhZ2VDaGFubmVsLFU9VC5wb3J0MjtULnBvcnQxLm9ubWVzc2FnZT1SO1M9ZnVuY3Rpb24oKXtVLnBvc3RNZXNzYWdlKG51bGwpfX1lbHNlIFM9ZnVuY3Rpb24oKXtEKFIsMCl9O2Z1bmN0aW9uIEkoYSl7Tz1hO058fChOPSEwLFMoKSl9ZnVuY3Rpb24gSyhhLGIpe0w9RChmdW5jdGlvbigpe2EoZXhwb3J0cy51bnN0YWJsZV9ub3coKSl9LGIpfVxuZXhwb3J0cy51bnN0YWJsZV9JZGxlUHJpb3JpdHk9NTtleHBvcnRzLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5PTE7ZXhwb3J0cy51bnN0YWJsZV9Mb3dQcmlvcml0eT00O2V4cG9ydHMudW5zdGFibGVfTm9ybWFsUHJpb3JpdHk9MztleHBvcnRzLnVuc3RhYmxlX1Byb2ZpbGluZz1udWxsO2V4cG9ydHMudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHk9MjtleHBvcnRzLnVuc3RhYmxlX2NhbmNlbENhbGxiYWNrPWZ1bmN0aW9uKGEpe2EuY2FsbGJhY2s9bnVsbH07ZXhwb3J0cy51bnN0YWJsZV9jb250aW51ZUV4ZWN1dGlvbj1mdW5jdGlvbigpe0F8fHp8fChBPSEwLEkoSikpfTtcbmV4cG9ydHMudW5zdGFibGVfZm9yY2VGcmFtZVJhdGU9ZnVuY3Rpb24oYSl7MD5hfHwxMjU8YT9jb25zb2xlLmVycm9yKFwiZm9yY2VGcmFtZVJhdGUgdGFrZXMgYSBwb3NpdGl2ZSBpbnQgYmV0d2VlbiAwIGFuZCAxMjUsIGZvcmNpbmcgZnJhbWUgcmF0ZXMgaGlnaGVyIHRoYW4gMTI1IGZwcyBpcyBub3Qgc3VwcG9ydGVkXCIpOlA9MDxhP01hdGguZmxvb3IoMUUzL2EpOjV9O2V4cG9ydHMudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWw9ZnVuY3Rpb24oKXtyZXR1cm4geX07ZXhwb3J0cy51bnN0YWJsZV9nZXRGaXJzdENhbGxiYWNrTm9kZT1mdW5jdGlvbigpe3JldHVybiBoKHIpfTtleHBvcnRzLnVuc3RhYmxlX25leHQ9ZnVuY3Rpb24oYSl7c3dpdGNoKHkpe2Nhc2UgMTpjYXNlIDI6Y2FzZSAzOnZhciBiPTM7YnJlYWs7ZGVmYXVsdDpiPXl9dmFyIGM9eTt5PWI7dHJ5e3JldHVybiBhKCl9ZmluYWxseXt5PWN9fTtleHBvcnRzLnVuc3RhYmxlX3BhdXNlRXhlY3V0aW9uPWZ1bmN0aW9uKCl7fTtcbmV4cG9ydHMudW5zdGFibGVfcmVxdWVzdFBhaW50PWZ1bmN0aW9uKCl7fTtleHBvcnRzLnVuc3RhYmxlX3J1bldpdGhQcmlvcml0eT1mdW5jdGlvbihhLGIpe3N3aXRjaChhKXtjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6Y2FzZSA1OmJyZWFrO2RlZmF1bHQ6YT0zfXZhciBjPXk7eT1hO3RyeXtyZXR1cm4gYigpfWZpbmFsbHl7eT1jfX07XG5leHBvcnRzLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2s9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPWV4cG9ydHMudW5zdGFibGVfbm93KCk7XCJvYmplY3RcIj09PXR5cGVvZiBjJiZudWxsIT09Yz8oYz1jLmRlbGF5LGM9XCJudW1iZXJcIj09PXR5cGVvZiBjJiYwPGM/ZCtjOmQpOmM9ZDtzd2l0Y2goYSl7Y2FzZSAxOnZhciBlPS0xO2JyZWFrO2Nhc2UgMjplPTI1MDticmVhaztjYXNlIDU6ZT0xMDczNzQxODIzO2JyZWFrO2Nhc2UgNDplPTFFNDticmVhaztkZWZhdWx0OmU9NUUzfWU9YytlO2E9e2lkOnUrKyxjYWxsYmFjazpiLHByaW9yaXR5TGV2ZWw6YSxzdGFydFRpbWU6YyxleHBpcmF0aW9uVGltZTplLHNvcnRJbmRleDotMX07Yz5kPyhhLnNvcnRJbmRleD1jLGYodCxhKSxudWxsPT09aChyKSYmYT09PWgodCkmJihCPyhFKEwpLEw9LTEpOkI9ITAsSyhILGMtZCkpKTooYS5zb3J0SW5kZXg9ZSxmKHIsYSksQXx8enx8KEE9ITAsSShKKSkpO3JldHVybiBhfTtcbmV4cG9ydHMudW5zdGFibGVfc2hvdWxkWWllbGQ9TTtleHBvcnRzLnVuc3RhYmxlX3dyYXBDYWxsYmFjaz1mdW5jdGlvbihhKXt2YXIgYj15O3JldHVybiBmdW5jdGlvbigpe3ZhciBjPXk7eT1iO3RyeXtyZXR1cm4gYS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9ZmluYWxseXt5PWN9fX07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///53\n')},840:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(53);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLElBQUksSUFBcUM7QUFDekMsRUFBRSx3Q0FBNkQ7QUFDL0QsRUFBRSxLQUFLLEVBRU4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc2NoZWR1bGVyL2luZGV4LmpzPzQwMjkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3NjaGVkdWxlci5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},897:module=>{eval('function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}\nmodule.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk3LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQSx5Q0FBeUMsU0FBUztBQUNsRDtBQUNBO0FBQ0Esb0NBQW9DLHlCQUF5QixTQUFTLHlCQUF5QiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2FycmF5TGlrZVRvQXJyYXkuanM/NGViYyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikge1xuICBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkobGVuKTsgaSA8IGxlbjsgaSsrKSBhcnIyW2ldID0gYXJyW2ldO1xuICByZXR1cm4gYXJyMjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2FycmF5TGlrZVRvQXJyYXksIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///897\n')},372:module=>{eval('function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\nmodule.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcnJheVdpdGhIb2xlcy5qcz83NjNmIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2FycmF5V2l0aEhvbGVzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///372\n')},690:module=>{eval('function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\nmodule.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjkwLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2suanM/OTRkYyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfY2xhc3NDYWxsQ2hlY2ssIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///690\n')},728:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var toPropertyKey = __webpack_require__(62);\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, toPropertyKey(descriptor.key), descriptor);\n }\n}\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, "prototype", {\n writable: false\n });\n return Constructor;\n}\nmodule.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzI4LmpzIiwibWFwcGluZ3MiOiJBQUFBLG9CQUFvQixtQkFBTyxDQUFDLEVBQW9CO0FBQ2hEO0FBQ0Esa0JBQWtCLGtCQUFrQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLCtCQUErQix5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcy5qcz83YjBmIl0sInNvdXJjZXNDb250ZW50IjpbInZhciB0b1Byb3BlcnR5S2V5ID0gcmVxdWlyZShcIi4vdG9Qcm9wZXJ0eUtleS5qc1wiKTtcbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHRvUHJvcGVydHlLZXkoZGVzY3JpcHRvci5rZXkpLCBkZXNjcmlwdG9yKTtcbiAgfVxufVxuZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcbiAgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29uc3RydWN0b3IsIFwicHJvdG90eXBlXCIsIHtcbiAgICB3cml0YWJsZTogZmFsc2VcbiAgfSk7XG4gIHJldHVybiBDb25zdHJ1Y3Rvcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NyZWF0ZUNsYXNzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///728\n')},872:module=>{eval('function _iterableToArrayLimit(arr, i) {\n var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];\n if (null != _i) {\n var _s,\n _e,\n _x,\n _r,\n _arr = [],\n _n = !0,\n _d = !1;\n try {\n if (_x = (_i = _i.call(arr)).next, 0 === i) {\n if (Object(_i) !== _i) return;\n _n = !1;\n } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);\n } catch (err) {\n _d = !0, _e = err;\n } finally {\n try {\n if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return;\n } finally {\n if (_d) throw _e;\n }\n }\n return _arr;\n }\n}\nmodule.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODcyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQVksNkVBQTZFO0FBQ2pHLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qcz8wZGFlIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHtcbiAgdmFyIF9pID0gbnVsbCA9PSBhcnIgPyBudWxsIDogXCJ1bmRlZmluZWRcIiAhPSB0eXBlb2YgU3ltYm9sICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07XG4gIGlmIChudWxsICE9IF9pKSB7XG4gICAgdmFyIF9zLFxuICAgICAgX2UsXG4gICAgICBfeCxcbiAgICAgIF9yLFxuICAgICAgX2FyciA9IFtdLFxuICAgICAgX24gPSAhMCxcbiAgICAgIF9kID0gITE7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChfeCA9IChfaSA9IF9pLmNhbGwoYXJyKSkubmV4dCwgMCA9PT0gaSkge1xuICAgICAgICBpZiAoT2JqZWN0KF9pKSAhPT0gX2kpIHJldHVybjtcbiAgICAgICAgX24gPSAhMTtcbiAgICAgIH0gZWxzZSBmb3IgKDsgIShfbiA9IChfcyA9IF94LmNhbGwoX2kpKS5kb25lKSAmJiAoX2Fyci5wdXNoKF9zLnZhbHVlKSwgX2Fyci5sZW5ndGggIT09IGkpOyBfbiA9ICEwKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIF9kID0gITAsIF9lID0gZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIV9uICYmIG51bGwgIT0gX2lbXCJyZXR1cm5cIl0gJiYgKF9yID0gX2lbXCJyZXR1cm5cIl0oKSwgT2JqZWN0KF9yKSAhPT0gX3IpKSByZXR1cm47XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gX2FycjtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfaXRlcmFibGVUb0FycmF5TGltaXQsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///872\n')},218:module=>{eval('function _nonIterableRest() {\n throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\nmodule.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9ub25JdGVyYWJsZVJlc3QuanM/N2RkZiJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfbm9uSXRlcmFibGVSZXN0LCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///218\n')},424:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var arrayWithHoles = __webpack_require__(372);\nvar iterableToArrayLimit = __webpack_require__(872);\nvar unsupportedIterableToArray = __webpack_require__(116);\nvar nonIterableRest = __webpack_require__(218);\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\nmodule.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI0LmpzIiwibWFwcGluZ3MiOiJBQUFBLHFCQUFxQixtQkFBTyxDQUFDLEdBQXFCO0FBQ2xELDJCQUEyQixtQkFBTyxDQUFDLEdBQTJCO0FBQzlELGlDQUFpQyxtQkFBTyxDQUFDLEdBQWlDO0FBQzFFLHNCQUFzQixtQkFBTyxDQUFDLEdBQXNCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5LmpzPzMyODAiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGFycmF5V2l0aEhvbGVzID0gcmVxdWlyZShcIi4vYXJyYXlXaXRoSG9sZXMuanNcIik7XG52YXIgaXRlcmFibGVUb0FycmF5TGltaXQgPSByZXF1aXJlKFwiLi9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qc1wiKTtcbnZhciB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSA9IHJlcXVpcmUoXCIuL3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5LmpzXCIpO1xudmFyIG5vbkl0ZXJhYmxlUmVzdCA9IHJlcXVpcmUoXCIuL25vbkl0ZXJhYmxlUmVzdC5qc1wiKTtcbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFyciwgaSkgfHwgbm9uSXRlcmFibGVSZXN0KCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9zbGljZWRUb0FycmF5LCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///424\n')},36:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var _typeof = (__webpack_require__(698)["default"]);\nfunction _toPrimitive(input, hint) {\n if (_typeof(input) !== "object" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || "default");\n if (_typeof(res) !== "object") return res;\n throw new TypeError("@@toPrimitive must return a primitive value.");\n }\n return (hint === "string" ? String : Number)(input);\n}\nmodule.exports = _toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYuanMiLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxxQ0FBaUM7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9QcmltaXRpdmUuanM/MzgzMSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgX3R5cGVvZiA9IHJlcXVpcmUoXCIuL3R5cGVvZi5qc1wiKVtcImRlZmF1bHRcIl07XG5mdW5jdGlvbiBfdG9QcmltaXRpdmUoaW5wdXQsIGhpbnQpIHtcbiAgaWYgKF90eXBlb2YoaW5wdXQpICE9PSBcIm9iamVjdFwiIHx8IGlucHV0ID09PSBudWxsKSByZXR1cm4gaW5wdXQ7XG4gIHZhciBwcmltID0gaW5wdXRbU3ltYm9sLnRvUHJpbWl0aXZlXTtcbiAgaWYgKHByaW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciByZXMgPSBwcmltLmNhbGwoaW5wdXQsIGhpbnQgfHwgXCJkZWZhdWx0XCIpO1xuICAgIGlmIChfdHlwZW9mKHJlcykgIT09IFwib2JqZWN0XCIpIHJldHVybiByZXM7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpO1xuICB9XG4gIHJldHVybiAoaGludCA9PT0gXCJzdHJpbmdcIiA/IFN0cmluZyA6IE51bWJlcikoaW5wdXQpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfdG9QcmltaXRpdmUsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///36\n')},62:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var _typeof = (__webpack_require__(698)["default"]);\nvar toPrimitive = __webpack_require__(36);\nfunction _toPropertyKey(arg) {\n var key = toPrimitive(arg, "string");\n return _typeof(key) === "symbol" ? key : String(key);\n}\nmodule.exports = _toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjIuanMiLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxxQ0FBaUM7QUFDL0Msa0JBQWtCLG1CQUFPLENBQUMsRUFBa0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Qcm9wZXJ0eUtleS5qcz9jNGU0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBfdHlwZW9mID0gcmVxdWlyZShcIi4vdHlwZW9mLmpzXCIpW1wiZGVmYXVsdFwiXTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoXCIuL3RvUHJpbWl0aXZlLmpzXCIpO1xuZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7XG4gIHZhciBrZXkgPSB0b1ByaW1pdGl2ZShhcmcsIFwic3RyaW5nXCIpO1xuICByZXR1cm4gX3R5cGVvZihrZXkpID09PSBcInN5bWJvbFwiID8ga2V5IDogU3RyaW5nKGtleSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF90b1Byb3BlcnR5S2V5LCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///62\n')},698:module=>{eval('function _typeof(obj) {\n "@babel/helpers - typeof";\n\n return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj);\n}\nmodule.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEdBQUcsRUFBRSx5QkFBeUIsU0FBUyx5QkFBeUI7QUFDaEU7QUFDQSwwQkFBMEIseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdHlwZW9mLmpzP2Q4Y2QiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX3R5cGVvZihvYmopIHtcbiAgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiO1xuXG4gIHJldHVybiAobW9kdWxlLmV4cG9ydHMgPSBfdHlwZW9mID0gXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgXCJzeW1ib2xcIiA9PSB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID8gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqO1xuICB9IDogZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBvYmogJiYgXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7XG4gIH0sIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cyksIF90eXBlb2Yob2JqKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3R5cGVvZiwgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWUsIG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///698\n')},116:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var arrayLikeToArray = __webpack_require__(897);\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === "Object" && o.constructor) n = o.constructor.name;\n if (n === "Map" || n === "Set") return Array.from(o);\n if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\nmodule.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTE2LmpzIiwibWFwcGluZ3MiOiJBQUFBLHVCQUF1QixtQkFBTyxDQUFDLEdBQXVCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanM/MjQ4NyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXJyYXlMaWtlVG9BcnJheSA9IHJlcXVpcmUoXCIuL2FycmF5TGlrZVRvQXJyYXkuanNcIik7XG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7XG4gIGlmICghbykgcmV0dXJuO1xuICBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBhcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gIHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTtcbiAgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gIGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXksIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///116\n')}},__webpack_module_cache__={};function __webpack_require__(I){var g=__webpack_module_cache__[I];if(void 0!==g)return g.exports;var n=__webpack_module_cache__[I]={exports:{}};return __webpack_modules__[I].call(n.exports,n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=I=>{var g=I&&I.__esModule?()=>I.default:()=>I;return __webpack_require__.d(g,{a:g}),g},__webpack_require__.d=(I,g)=>{for(var n in g)__webpack_require__.o(g,n)&&!__webpack_require__.o(I,n)&&Object.defineProperty(I,n,{enumerable:!0,get:g[n]})},__webpack_require__.o=(I,g)=>Object.prototype.hasOwnProperty.call(I,g);var __webpack_exports__=__webpack_require__(441)})();
|